2000-09-18 15:18:56 +00:00
|
|
|
|
/*************************************************************************
|
|
|
|
|
*
|
2008-04-11 11:06:21 +00:00
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2010-02-12 15:01:35 +01:00
|
|
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 11:06:21 +00:00
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 11:06:21 +00:00
|
|
|
|
* This file is part of OpenOffice.org.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 11:06:21 +00:00
|
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
|
* only, as published by the Free Software Foundation.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 11:06:21 +00:00
|
|
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU Lesser General Public License version 3 for more details
|
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 11:06:21 +00:00
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
|
* for a copy of the LGPLv3 License.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
|
|
|
|
************************************************************************/
|
|
|
|
|
|
2006-09-17 09:07:02 +00:00
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
|
#include "precompiled_basic.hxx"
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#include "runtime.hxx"
|
2004-09-08 13:55:48 +00:00
|
|
|
|
#ifndef GCC
|
|
|
|
|
#endif
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#include "iosys.hxx"
|
|
|
|
|
#include "image.hxx"
|
|
|
|
|
#include "sbintern.hxx"
|
|
|
|
|
#include "sbunoobj.hxx"
|
|
|
|
|
#include "opcodes.hxx"
|
|
|
|
|
|
|
|
|
|
#include <com/sun/star/container/XIndexAccess.hpp>
|
2006-05-05 09:13:24 +00:00
|
|
|
|
#include <com/sun/star/script/XDefaultMethod.hpp>
|
2007-04-25 14:52:45 +00:00
|
|
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#include <com/sun/star/uno/Any.hxx>
|
2007-04-25 14:52:45 +00:00
|
|
|
|
#include <comphelper/processfactory.hxx>
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2007-06-05 14:11:21 +00:00
|
|
|
|
using namespace com::sun::star::uno;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
using namespace com::sun::star::container;
|
|
|
|
|
using namespace com::sun::star::lang;
|
2007-06-05 14:11:21 +00:00
|
|
|
|
using namespace com::sun::star::beans;
|
|
|
|
|
using namespace com::sun::star::script;
|
|
|
|
|
|
|
|
|
|
using com::sun::star::uno::Reference;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2007-08-30 09:09:56 +00:00
|
|
|
|
SbxVariable* getVBAConstant( const String& rName );
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Suchen eines Elements
|
|
|
|
|
// Die Bits im String-ID:
|
|
|
|
|
// 0x8000 - Argv ist belegt
|
|
|
|
|
|
|
|
|
|
SbxVariable* SbiRuntime::FindElement
|
2008-07-02 09:14:41 +00:00
|
|
|
|
( SbxObject* pObj, UINT32 nOp1, UINT32 nOp2, SbError nNotFound, BOOL bLocal, BOOL bStatic )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-11-02 15:37:23 +00:00
|
|
|
|
bool bIsVBAInterOp = SbiRuntime::isVBAEnabled();
|
2007-08-03 08:56:23 +00:00
|
|
|
|
if( bIsVBAInterOp )
|
|
|
|
|
{
|
|
|
|
|
StarBASIC* pMSOMacroRuntimeLib = GetSbData()->pMSOMacroRuntimLib;
|
|
|
|
|
if( pMSOMacroRuntimeLib != NULL )
|
|
|
|
|
pMSOMacroRuntimeLib->ResetFlag( SBX_EXTSEARCH );
|
|
|
|
|
}
|
2006-11-02 15:37:23 +00:00
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbxVariable* pElem = NULL;
|
|
|
|
|
if( !pObj )
|
|
|
|
|
{
|
|
|
|
|
Error( SbERR_NO_OBJECT );
|
|
|
|
|
pElem = new SbxVariable;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
BOOL bFatalError = FALSE;
|
|
|
|
|
SbxDataType t = (SbxDataType) nOp2;
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) );
|
2007-08-30 09:09:56 +00:00
|
|
|
|
// Hacky capture of Evaluate [] syntax
|
|
|
|
|
// this should be tackled I feel at the pcode level
|
|
|
|
|
if ( bIsVBAInterOp && aName.Search('[') == 0 )
|
|
|
|
|
{
|
|
|
|
|
// emulate pcode here
|
|
|
|
|
StepARGC();
|
|
|
|
|
// psuedo StepLOADSC
|
|
|
|
|
String sArg = aName.Copy( 1, aName.Len() - 2 );
|
|
|
|
|
SbxVariable* p = new SbxVariable;
|
|
|
|
|
p->PutString( sArg );
|
|
|
|
|
PushVar( p );
|
|
|
|
|
//
|
|
|
|
|
StepARGV();
|
|
|
|
|
nOp1 = nOp1 | 0x8000; // indicate params are present
|
|
|
|
|
aName = String::CreateFromAscii("Evaluate");
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( bLocal )
|
2008-07-02 09:14:41 +00:00
|
|
|
|
{
|
|
|
|
|
if ( bStatic )
|
|
|
|
|
{
|
|
|
|
|
if ( pMeth )
|
|
|
|
|
pElem = pMeth->GetStatics()->Find( aName, SbxCLASS_DONTCARE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !pElem )
|
|
|
|
|
pElem = refLocals->Find( aName, SbxCLASS_DONTCARE );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( !pElem )
|
|
|
|
|
{
|
|
|
|
|
// Die RTL brauchen wir nicht mehr zu durchsuchen!
|
|
|
|
|
BOOL bSave = rBasic.bNoRtl;
|
|
|
|
|
rBasic.bNoRtl = TRUE;
|
|
|
|
|
pElem = pObj->Find( aName, SbxCLASS_DONTCARE );
|
2004-03-17 12:37:42 +00:00
|
|
|
|
|
|
|
|
|
// #110004, #112015: Make private really private
|
|
|
|
|
if( bLocal && pElem ) // Local as flag for global search
|
|
|
|
|
{
|
|
|
|
|
if( pElem->IsSet( SBX_PRIVATE ) )
|
|
|
|
|
{
|
2006-06-19 16:47:47 +00:00
|
|
|
|
SbiInstance* pInst_ = pINST;
|
|
|
|
|
if( pInst_ && pInst_->IsCompatibility() && pObj != pElem->GetParent() )
|
2004-03-17 12:37:42 +00:00
|
|
|
|
pElem = NULL; // Found but in wrong module!
|
2005-03-29 10:53:06 +00:00
|
|
|
|
|
|
|
|
|
// Interfaces: Use SBX_EXTFOUND
|
2004-03-17 12:37:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
rBasic.bNoRtl = bSave;
|
|
|
|
|
|
|
|
|
|
// Ist es ein globaler Uno-Bezeichner?
|
|
|
|
|
if( bLocal && !pElem )
|
|
|
|
|
{
|
2006-11-02 15:37:23 +00:00
|
|
|
|
bool bSetName = true; // preserve normal behaviour
|
|
|
|
|
|
|
|
|
|
// i#i68894# if VBAInterOp favour searching vba globals
|
|
|
|
|
// over searching for uno classess
|
2007-08-30 09:09:56 +00:00
|
|
|
|
if ( bVBAEnabled )
|
2002-09-30 07:54:11 +00:00
|
|
|
|
{
|
2006-11-02 15:37:23 +00:00
|
|
|
|
// Try Find in VBA symbols space
|
2009-09-18 15:24:22 +00:00
|
|
|
|
pElem = rBasic.VBAFind( aName, SbxCLASS_DONTCARE );
|
2006-11-02 15:37:23 +00:00
|
|
|
|
if ( pElem )
|
|
|
|
|
bSetName = false; // don't overwrite uno name
|
2007-08-30 09:09:56 +00:00
|
|
|
|
else
|
|
|
|
|
pElem = getVBAConstant( aName );
|
2006-11-02 15:37:23 +00:00
|
|
|
|
}
|
2007-08-30 09:09:56 +00:00
|
|
|
|
// #72382 VORSICHT! Liefert jetzt wegen unbekannten
|
|
|
|
|
// Modulen IMMER ein Ergebnis!
|
2009-08-06 11:03:20 +00:00
|
|
|
|
SbUnoClass* pUnoClass = findUnoClass( aName );
|
2007-08-30 09:09:56 +00:00
|
|
|
|
if( pUnoClass )
|
2006-11-02 15:37:23 +00:00
|
|
|
|
{
|
2007-08-30 09:09:56 +00:00
|
|
|
|
pElem = new SbxVariable( t );
|
|
|
|
|
SbxValues aRes( SbxOBJECT );
|
|
|
|
|
aRes.pObj = pUnoClass;
|
|
|
|
|
pElem->SbxVariable::Put( aRes );
|
2002-09-30 07:54:11 +00:00
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// #62939 Wenn eine Uno-Klasse gefunden wurde, muss
|
|
|
|
|
// das Wrapper-Objekt gehalten werden, da sonst auch
|
|
|
|
|
// die Uno-Klasse, z.B. "stardiv" immer wieder neu
|
|
|
|
|
// aus der Registry gelesen werden muss
|
2002-09-30 07:54:11 +00:00
|
|
|
|
if( pElem )
|
|
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// #63774 Darf nicht mit gespeichert werden!!!
|
|
|
|
|
pElem->SetFlag( SBX_DONTSTORE );
|
|
|
|
|
pElem->SetFlag( SBX_NO_MODIFY);
|
|
|
|
|
|
|
|
|
|
// #72382 Lokal speichern, sonst werden alle implizit
|
|
|
|
|
// deklarierten Vars automatisch global !
|
2006-11-02 15:37:23 +00:00
|
|
|
|
if ( bSetName )
|
|
|
|
|
pElem->SetName( aName );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
refLocals->Put( pElem, refLocals->Count() );
|
2002-09-30 07:54:11 +00:00
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !pElem )
|
|
|
|
|
{
|
|
|
|
|
// Nicht da und nicht im Objekt?
|
|
|
|
|
// Hat das Ding Parameter, nicht einrichten!
|
|
|
|
|
if( nOp1 & 0x8000 )
|
|
|
|
|
bFatalError = TRUE;
|
|
|
|
|
// ALT: StarBASIC::FatalError( nNotFound );
|
|
|
|
|
|
|
|
|
|
// Sonst, falls keine Parameter sind, anderen Error Code verwenden
|
|
|
|
|
if( !bLocal || pImg->GetFlag( SBIMG_EXPLICIT ) )
|
|
|
|
|
{
|
|
|
|
|
// #39108 Bei explizit und als ELEM immer ein Fatal Error
|
|
|
|
|
bFatalError = TRUE;
|
|
|
|
|
|
|
|
|
|
// Falls keine Parameter sind, anderen Error Code verwenden
|
|
|
|
|
if( !( nOp1 & 0x8000 ) && nNotFound == SbERR_PROC_UNDEFINED )
|
|
|
|
|
nNotFound = SbERR_VAR_UNDEFINED;
|
|
|
|
|
}
|
|
|
|
|
if( bFatalError )
|
|
|
|
|
{
|
|
|
|
|
// #39108 Statt FatalError zu setzen, Dummy-Variable liefern
|
|
|
|
|
if( !xDummyVar.Is() )
|
|
|
|
|
xDummyVar = new SbxVariable( SbxVARIANT );
|
|
|
|
|
pElem = xDummyVar;
|
|
|
|
|
|
|
|
|
|
// Parameter von Hand loeschen
|
|
|
|
|
ClearArgvStack();
|
|
|
|
|
|
|
|
|
|
// Normalen Error setzen
|
2009-08-06 11:03:20 +00:00
|
|
|
|
Error( nNotFound, aName );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2008-07-02 09:14:41 +00:00
|
|
|
|
if ( bStatic )
|
|
|
|
|
pElem = StepSTATIC_Impl( aName, t );
|
|
|
|
|
if ( !pElem )
|
|
|
|
|
{
|
|
|
|
|
// Sonst Variable neu anlegen
|
|
|
|
|
pElem = new SbxVariable( t );
|
|
|
|
|
if( t != SbxVARIANT )
|
|
|
|
|
pElem->SetFlag( SBX_FIXED );
|
|
|
|
|
pElem->SetName( aName );
|
|
|
|
|
refLocals->Put( pElem, refLocals->Count() );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// #39108 Args koennen schon geloescht sein!
|
|
|
|
|
if( !bFatalError )
|
|
|
|
|
SetupArgs( pElem, nOp1 );
|
|
|
|
|
// Ein bestimmter Call-Type wurde gewuenscht, daher muessen
|
|
|
|
|
// wir hier den Typ setzen und das Ding anfassen, um den
|
|
|
|
|
// korrekten Returnwert zu erhalten!
|
|
|
|
|
if( pElem->IsA( TYPE(SbxMethod) ) )
|
|
|
|
|
{
|
|
|
|
|
// Soll der Typ konvertiert werden?
|
|
|
|
|
SbxDataType t2 = pElem->GetType();
|
|
|
|
|
BOOL bSet = FALSE;
|
|
|
|
|
if( !( pElem->GetFlags() & SBX_FIXED ) )
|
|
|
|
|
{
|
|
|
|
|
if( t != SbxVARIANT && t != t2 &&
|
|
|
|
|
t >= SbxINTEGER && t <= SbxSTRING )
|
|
|
|
|
pElem->SetType( t ), bSet = TRUE;
|
|
|
|
|
}
|
|
|
|
|
// pElem auf eine Ref zuweisen, um ggf. eine Temp-Var zu loeschen
|
|
|
|
|
SbxVariableRef refTemp = pElem;
|
|
|
|
|
|
|
|
|
|
// Moegliche Reste vom letzten Aufruf der SbxMethod beseitigen
|
|
|
|
|
// Vorher Schreiben freigeben, damit kein Error gesetzt wird.
|
2006-06-19 16:47:47 +00:00
|
|
|
|
USHORT nSavFlags = pElem->GetFlags();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pElem->SetFlag( SBX_READWRITE | SBX_NO_BROADCAST );
|
|
|
|
|
pElem->SbxValue::Clear();
|
2006-06-19 16:47:47 +00:00
|
|
|
|
pElem->SetFlags( nSavFlags );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Erst nach dem Setzen anfassen, da z.B. LEFT()
|
|
|
|
|
// den Unterschied zwischen Left$() und Left() kennen muss
|
|
|
|
|
|
|
|
|
|
// AB 12.8.96: Da in PopVar() die Parameter von Methoden weggehauen
|
|
|
|
|
// werden, muessen wir hier explizit eine neue SbxMethod anlegen
|
|
|
|
|
SbxVariable* pNew = new SbxMethod( *((SbxMethod*)pElem) ); // das ist der Call!
|
|
|
|
|
//ALT: SbxVariable* pNew = new SbxVariable( *pElem ); // das ist der Call!
|
|
|
|
|
|
|
|
|
|
pElem->SetParameters(0); // sonst bleibt Ref auf sich selbst
|
|
|
|
|
pNew->SetFlag( SBX_READWRITE );
|
|
|
|
|
|
|
|
|
|
// den Datentypen zuruecksetzen?
|
|
|
|
|
if( bSet )
|
|
|
|
|
pElem->SetType( t2 );
|
|
|
|
|
pElem = pNew;
|
|
|
|
|
}
|
|
|
|
|
// Index-Access bei UnoObjekten beruecksichtigen
|
2010-06-25 08:57:06 +02:00
|
|
|
|
// definitely we want this for VBA where properties are often
|
|
|
|
|
// collections ( which need index access ), but lets only do
|
|
|
|
|
// this if we actually have params following
|
|
|
|
|
else if( bVBAEnabled && pElem->ISA(SbUnoProperty) && pElem->GetParameters() )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// pElem auf eine Ref zuweisen, um ggf. eine Temp-Var zu loeschen
|
|
|
|
|
SbxVariableRef refTemp = pElem;
|
|
|
|
|
|
|
|
|
|
// Variable kopieren und dabei den Notify aufloesen
|
|
|
|
|
SbxVariable* pNew = new SbxVariable( *((SbxVariable*)pElem) ); // das ist der Call!
|
|
|
|
|
pElem->SetParameters( NULL ); // sonst bleibt Ref auf sich selbst
|
|
|
|
|
pElem = pNew;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return CheckArray( pElem );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find-Funktion ueber Name fuer aktuellen Scope (z.B. Abfrage aus BASIC-IDE)
|
|
|
|
|
SbxBase* SbiRuntime::FindElementExtern( const String& rName )
|
|
|
|
|
{
|
|
|
|
|
// Hinweis zu #35281#: Es darf nicht davon ausgegangen werden, dass
|
|
|
|
|
// pMeth != null, da im RunInit noch keine gesetzt ist.
|
|
|
|
|
|
|
|
|
|
SbxVariable* pElem = NULL;
|
|
|
|
|
if( !pMod || !rName.Len() )
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
// Lokal suchen
|
|
|
|
|
if( refLocals )
|
|
|
|
|
pElem = refLocals->Find( rName, SbxCLASS_DONTCARE );
|
|
|
|
|
|
|
|
|
|
// In Statics suchen
|
|
|
|
|
if ( !pElem && pMeth )
|
|
|
|
|
{
|
|
|
|
|
// Bei Statics, Name der Methode davor setzen
|
|
|
|
|
String aMethName = pMeth->GetName();
|
|
|
|
|
aMethName += ':';
|
|
|
|
|
aMethName += rName;
|
|
|
|
|
pElem = pMod->Find(aMethName, SbxCLASS_DONTCARE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// In Parameter-Liste suchen
|
|
|
|
|
if( !pElem && pMeth )
|
|
|
|
|
{
|
|
|
|
|
SbxInfo* pInfo = pMeth->GetInfo();
|
|
|
|
|
if( pInfo && refParams )
|
|
|
|
|
{
|
2001-05-18 11:42:15 +00:00
|
|
|
|
USHORT nParamCount = refParams->Count();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
USHORT j = 1;
|
|
|
|
|
const SbxParamInfo* pParam = pInfo->GetParam( j );
|
|
|
|
|
while( pParam )
|
|
|
|
|
{
|
|
|
|
|
if( pParam->aName.EqualsIgnoreCaseAscii( rName ) )
|
|
|
|
|
{
|
2001-05-18 11:42:15 +00:00
|
|
|
|
if( j >= nParamCount )
|
|
|
|
|
{
|
|
|
|
|
// Parameter is missing
|
|
|
|
|
pElem = new SbxVariable( SbxSTRING );
|
|
|
|
|
pElem->PutString( String( RTL_CONSTASCII_USTRINGPARAM("<missing parameter>" ) ) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pElem = refParams->Get( j );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
pParam = pInfo->GetParam( ++j );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Im Modul suchen
|
|
|
|
|
if( !pElem )
|
|
|
|
|
{
|
|
|
|
|
// RTL nicht durchsuchen!
|
|
|
|
|
BOOL bSave = rBasic.bNoRtl;
|
|
|
|
|
rBasic.bNoRtl = TRUE;
|
|
|
|
|
pElem = pMod->Find( rName, SbxCLASS_DONTCARE );
|
|
|
|
|
rBasic.bNoRtl = bSave;
|
|
|
|
|
}
|
|
|
|
|
return pElem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Argumente eines Elements setzen
|
|
|
|
|
// Dabei auch die Argumente umsetzen, falls benannte Parameter
|
|
|
|
|
// verwendet wurden
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::SetupArgs( SbxVariable* p, UINT32 nOp1 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
if( nOp1 & 0x8000 )
|
|
|
|
|
{
|
|
|
|
|
if( !refArgv )
|
|
|
|
|
StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
|
|
|
|
|
BOOL bHasNamed = FALSE;
|
|
|
|
|
USHORT i;
|
2004-03-17 12:37:42 +00:00
|
|
|
|
USHORT nArgCount = refArgv->Count();
|
|
|
|
|
for( i = 1 ; i < nArgCount ; i++ )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
if( refArgv->GetAlias( i ).Len() )
|
|
|
|
|
{
|
|
|
|
|
bHasNamed = TRUE; break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( bHasNamed )
|
|
|
|
|
{
|
|
|
|
|
// Wir haben mindestens einen benannten Parameter!
|
|
|
|
|
// Wir muessen also umsortieren
|
|
|
|
|
// Gibt es Parameter-Infos?
|
|
|
|
|
SbxInfo* pInfo = p->GetInfo();
|
|
|
|
|
if( !pInfo )
|
2004-03-17 12:37:42 +00:00
|
|
|
|
{
|
2006-06-19 16:47:47 +00:00
|
|
|
|
bool bError_ = true;
|
2004-03-17 12:37:42 +00:00
|
|
|
|
|
|
|
|
|
SbUnoMethod* pUnoMethod = PTR_CAST(SbUnoMethod,p);
|
|
|
|
|
if( pUnoMethod )
|
|
|
|
|
{
|
|
|
|
|
SbUnoObject* pParentUnoObj = PTR_CAST( SbUnoObject,p->GetParent() );
|
|
|
|
|
if( pParentUnoObj )
|
|
|
|
|
{
|
|
|
|
|
Any aUnoAny = pParentUnoObj->getUnoAny();
|
|
|
|
|
Reference< XInvocation > xInvocation;
|
|
|
|
|
aUnoAny >>= xInvocation;
|
|
|
|
|
if( xInvocation.is() ) // TODO: if( xOLEAutomation.is() )
|
|
|
|
|
{
|
2006-06-19 16:47:47 +00:00
|
|
|
|
bError_ = false;
|
2004-03-17 12:37:42 +00:00
|
|
|
|
|
|
|
|
|
USHORT nCurPar = 1;
|
|
|
|
|
AutomationNamedArgsSbxArray* pArg =
|
|
|
|
|
new AutomationNamedArgsSbxArray( nArgCount );
|
2008-06-24 15:04:49 +00:00
|
|
|
|
::rtl::OUString* pNames = pArg->getNames().getArray();
|
2004-03-17 12:37:42 +00:00
|
|
|
|
for( i = 1 ; i < nArgCount ; i++ )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* pVar = refArgv->Get( i );
|
|
|
|
|
const String& rName = refArgv->GetAlias( i );
|
|
|
|
|
if( rName.Len() )
|
|
|
|
|
pNames[i] = rName;
|
|
|
|
|
pArg->Put( pVar, nCurPar++ );
|
|
|
|
|
}
|
|
|
|
|
refArgv = pArg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-06-19 16:47:47 +00:00
|
|
|
|
if( bError_ )
|
2004-03-17 12:37:42 +00:00
|
|
|
|
Error( SbERR_NO_NAMED_ARGS );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
USHORT nCurPar = 1;
|
|
|
|
|
SbxArray* pArg = new SbxArray;
|
2004-03-17 12:37:42 +00:00
|
|
|
|
for( i = 1 ; i < nArgCount ; i++ )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
SbxVariable* pVar = refArgv->Get( i );
|
|
|
|
|
const String& rName = refArgv->GetAlias( i );
|
|
|
|
|
if( rName.Len() )
|
|
|
|
|
{
|
|
|
|
|
// nCurPar wird auf den gefundenen Parameter gesetzt
|
|
|
|
|
USHORT j = 1;
|
|
|
|
|
const SbxParamInfo* pParam = pInfo->GetParam( j );
|
|
|
|
|
while( pParam )
|
|
|
|
|
{
|
|
|
|
|
if( pParam->aName.EqualsIgnoreCaseAscii( rName ) )
|
|
|
|
|
{
|
|
|
|
|
nCurPar = j;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
pParam = pInfo->GetParam( ++j );
|
|
|
|
|
}
|
|
|
|
|
if( !pParam )
|
|
|
|
|
{
|
|
|
|
|
Error( SbERR_NAMED_NOT_FOUND ); break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pArg->Put( pVar, nCurPar++ );
|
|
|
|
|
}
|
|
|
|
|
refArgv = pArg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Eigene Var als Parameter 0
|
|
|
|
|
refArgv->Put( p, 0 );
|
|
|
|
|
p->SetParameters( refArgv );
|
|
|
|
|
PopArgv();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
p->SetParameters( NULL );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Holen eines Array-Elements
|
|
|
|
|
|
|
|
|
|
SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem )
|
|
|
|
|
{
|
|
|
|
|
// Falls wir ein Array haben, wollen wir bitte das Array-Element!
|
|
|
|
|
SbxArray* pPar;
|
|
|
|
|
if( pElem->GetType() & SbxARRAY )
|
|
|
|
|
{
|
|
|
|
|
SbxBase* pElemObj = pElem->GetObject();
|
|
|
|
|
SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
|
|
|
|
|
pPar = pElem->GetParameters();
|
|
|
|
|
if( pDimArray )
|
|
|
|
|
{
|
|
|
|
|
// Die Parameter koennen fehlen, wenn ein Array als
|
|
|
|
|
// Argument uebergeben wird.
|
|
|
|
|
if( pPar )
|
|
|
|
|
pElem = pDimArray->Get( pPar );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SbxArray* pArray = PTR_CAST(SbxArray,pElemObj);
|
|
|
|
|
if( pArray )
|
|
|
|
|
{
|
|
|
|
|
if( !pPar )
|
|
|
|
|
{
|
|
|
|
|
Error( SbERR_OUT_OF_RANGE );
|
|
|
|
|
pElem = new SbxVariable;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pElem = pArray->Get( pPar->Get( 1 )->GetInteger() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #42940, 0.Parameter zu NULL setzen, damit sich Var nicht selbst haelt
|
|
|
|
|
if( pPar )
|
|
|
|
|
pPar->Put( NULL, 0 );
|
|
|
|
|
}
|
|
|
|
|
// Index-Access bei UnoObjekten beruecksichtigen
|
2006-10-12 13:31:26 +00:00
|
|
|
|
else if( pElem->GetType() == SbxOBJECT && !pElem->ISA(SbxMethod) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
pPar = pElem->GetParameters();
|
|
|
|
|
if ( pPar )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
// Ist es ein Uno-Objekt?
|
|
|
|
|
SbxBaseRef pObj = (SbxBase*)pElem->GetObject();
|
|
|
|
|
if( pObj )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
if( pObj->ISA(SbUnoObject) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
SbUnoObject* pUnoObj = (SbUnoObject*)(SbxBase*)pObj;
|
|
|
|
|
Any aAny = pUnoObj->getUnoAny();
|
|
|
|
|
|
|
|
|
|
if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue();
|
|
|
|
|
Reference< XIndexAccess > xIndexAccess( x, UNO_QUERY );
|
2007-08-30 09:09:56 +00:00
|
|
|
|
if ( !bVBAEnabled )
|
2005-01-28 15:10:01 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
// Haben wir Index-Access?
|
|
|
|
|
if( xIndexAccess.is() )
|
2006-05-05 09:13:24 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
UINT32 nParamCount = (UINT32)pPar->Count() - 1;
|
|
|
|
|
if( nParamCount != 1 )
|
|
|
|
|
{
|
|
|
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
|
|
|
return pElem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Index holen
|
|
|
|
|
INT32 nIndex = pPar->Get( 1 )->GetLong();
|
|
|
|
|
Reference< XInterface > xRet;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Any aAny2 = xIndexAccess->getByIndex( nIndex );
|
|
|
|
|
TypeClass eType = aAny2.getValueType().getTypeClass();
|
|
|
|
|
if( eType == TypeClass_INTERFACE )
|
|
|
|
|
xRet = *(Reference< XInterface >*)aAny2.getValue();
|
|
|
|
|
}
|
|
|
|
|
catch (IndexOutOfBoundsException&)
|
|
|
|
|
{
|
|
|
|
|
// Bei Exception erstmal immer von Konvertierungs-Problem ausgehen
|
|
|
|
|
StarBASIC::Error( SbERR_OUT_OF_RANGE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #57847 Immer neue Variable anlegen, sonst Fehler
|
|
|
|
|
// durch PutObject(NULL) bei ReadOnly-Properties.
|
|
|
|
|
pElem = new SbxVariable( SbxVARIANT );
|
|
|
|
|
if( xRet.is() )
|
|
|
|
|
{
|
|
|
|
|
aAny <<= xRet;
|
|
|
|
|
|
|
|
|
|
// #67173 Kein Namen angeben, damit echter Klassen-Namen eintragen wird
|
|
|
|
|
String aName;
|
|
|
|
|
SbxObjectRef xWrapper = (SbxObject*)new SbUnoObject( aName, aAny );
|
|
|
|
|
pElem->PutObject( xWrapper );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pElem->PutObject( NULL );
|
|
|
|
|
}
|
2006-05-05 09:13:24 +00:00
|
|
|
|
}
|
2006-10-12 13:31:26 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rtl::OUString sDefaultMethod;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2006-10-12 13:31:26 +00:00
|
|
|
|
Reference< XDefaultMethod > xDfltMethod( x, UNO_QUERY );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2006-10-12 13:31:26 +00:00
|
|
|
|
if ( xDfltMethod.is() )
|
2006-11-02 15:37:23 +00:00
|
|
|
|
sDefaultMethod = xDfltMethod->getDefaultMethodName();
|
2006-10-12 13:31:26 +00:00
|
|
|
|
else if( xIndexAccess.is() )
|
|
|
|
|
sDefaultMethod = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getByIndex" ) );
|
2005-01-28 15:10:01 +00:00
|
|
|
|
|
2006-10-12 13:31:26 +00:00
|
|
|
|
if ( sDefaultMethod.getLength() )
|
2006-05-05 09:13:24 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
SbxVariable* meth = pUnoObj->Find( sDefaultMethod, SbxCLASS_METHOD );
|
|
|
|
|
SbxVariableRef refTemp = meth;
|
|
|
|
|
if ( refTemp )
|
|
|
|
|
{
|
|
|
|
|
meth->SetParameters( pPar );
|
2006-11-02 14:49:01 +00:00
|
|
|
|
SbxVariable* pNew = new SbxMethod( *(SbxMethod*)meth );
|
2006-10-12 13:31:26 +00:00
|
|
|
|
pElem = pNew;
|
|
|
|
|
}
|
2006-05-05 09:13:24 +00:00
|
|
|
|
}
|
2005-01-28 15:10:01 +00:00
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2006-05-05 09:13:24 +00:00
|
|
|
|
|
2006-10-12 13:31:26 +00:00
|
|
|
|
// #42940, 0.Parameter zu NULL setzen, damit sich Var nicht selbst haelt
|
|
|
|
|
pPar->Put( NULL, 0 );
|
|
|
|
|
}
|
|
|
|
|
else if( pObj->ISA(BasicCollection) )
|
|
|
|
|
{
|
|
|
|
|
BasicCollection* pCol = (BasicCollection*)(SbxBase*)pObj;
|
|
|
|
|
pElem = new SbxVariable( SbxVARIANT );
|
|
|
|
|
pPar->Put( pElem, 0 );
|
|
|
|
|
pCol->CollItem( pPar );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return pElem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Laden eines Elements aus der Runtime-Library (+StringID+Typ)
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepRTL( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
PushVar( FindElement( rBasic.pRtl, nOp1, nOp2, SbERR_PROC_UNDEFINED, FALSE ) );
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-02 09:14:41 +00:00
|
|
|
|
void
|
|
|
|
|
SbiRuntime::StepFIND_Impl( SbxObject* pObj, UINT32 nOp1, UINT32 nOp2, SbError nNotFound, BOOL bLocal, BOOL bStatic )
|
|
|
|
|
{
|
|
|
|
|
if( !refLocals )
|
|
|
|
|
refLocals = new SbxArray;
|
|
|
|
|
PushVar( FindElement( pObj, nOp1, nOp2, nNotFound, bLocal, bStatic ) );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Laden einer lokalen/globalen Variablen (+StringID+Typ)
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepFIND( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2008-07-02 09:14:41 +00:00
|
|
|
|
StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, TRUE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-11-02 10:58:59 +00:00
|
|
|
|
// Search inside a class module (CM) to enable global search in time
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepFIND_CM( UINT32 nOp1, UINT32 nOp2 )
|
2004-11-02 10:58:59 +00:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pMod);
|
|
|
|
|
if( pClassModuleObject )
|
|
|
|
|
pMod->SetFlag( SBX_GBLSEARCH );
|
2008-07-02 09:14:41 +00:00
|
|
|
|
|
|
|
|
|
StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, TRUE );
|
|
|
|
|
|
2004-11-02 10:58:59 +00:00
|
|
|
|
if( pClassModuleObject )
|
|
|
|
|
pMod->ResetFlag( SBX_GBLSEARCH );
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-02 09:14:41 +00:00
|
|
|
|
void SbiRuntime::StepFIND_STATIC( UINT32 nOp1, UINT32 nOp2 )
|
|
|
|
|
{
|
|
|
|
|
StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, TRUE, TRUE );
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Laden eines Objekt-Elements (+StringID+Typ)
|
|
|
|
|
// Das Objekt liegt auf TOS
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepELEM( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Liegt auf dem TOS ein Objekt?
|
|
|
|
|
SbxVariableRef pObjVar = PopVar();
|
|
|
|
|
|
|
|
|
|
SbxObject* pObj = PTR_CAST(SbxObject,(SbxVariable*) pObjVar);
|
|
|
|
|
if( !pObj )
|
|
|
|
|
{
|
|
|
|
|
SbxBase* pObjVarObj = pObjVar->GetObject();
|
|
|
|
|
pObj = PTR_CAST(SbxObject,pObjVarObj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #56368 Bei StepElem Referenz sichern, sonst koennen Objekte
|
|
|
|
|
// in Qualifizierungsketten wie ActiveComponent.Selection(0).Text
|
|
|
|
|
// zu fueh die Referenz verlieren
|
|
|
|
|
// #74254 Jetzt per Liste
|
|
|
|
|
if( pObj )
|
|
|
|
|
SaveRef( (SbxVariable*)pObj );
|
|
|
|
|
|
|
|
|
|
PushVar( FindElement( pObj, nOp1, nOp2, SbERR_NO_METHOD, FALSE ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Laden eines Parameters (+Offset+Typ)
|
|
|
|
|
// Wenn der Datentyp nicht stimmen sollte, eine Kopie anlegen
|
2006-11-01 15:17:07 +00:00
|
|
|
|
// Der Datentyp SbxEMPTY zeigt an, daa kein Parameter angegeben ist.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Get( 0 ) darf EMPTY sein
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepPARAM( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-11-03 14:11:10 +00:00
|
|
|
|
USHORT i = static_cast<USHORT>( nOp1 & 0x7FFF );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbxDataType t = (SbxDataType) nOp2;
|
|
|
|
|
SbxVariable* p;
|
|
|
|
|
|
|
|
|
|
// #57915 Missing sauberer loesen
|
|
|
|
|
USHORT nParamCount = refParams->Count();
|
|
|
|
|
if( i >= nParamCount )
|
|
|
|
|
{
|
2006-04-07 13:04:37 +00:00
|
|
|
|
INT16 iLoop = i;
|
|
|
|
|
while( iLoop >= nParamCount )
|
|
|
|
|
{
|
|
|
|
|
p = new SbxVariable();
|
2010-07-20 11:49:49 +02:00
|
|
|
|
|
|
|
|
|
if( SbiRuntime::isVBAEnabled() &&
|
|
|
|
|
(t == SbxOBJECT || t == SbxSTRING) )
|
|
|
|
|
{
|
|
|
|
|
if( t == SbxOBJECT )
|
|
|
|
|
p->PutObject( NULL );
|
|
|
|
|
else
|
|
|
|
|
p->PutString( String() );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
p->PutErr( 448 ); // Wie in VB: Error-Code 448 (SbERR_NAMED_NOT_FOUND)
|
|
|
|
|
|
2006-04-07 13:04:37 +00:00
|
|
|
|
refParams->Put( p, iLoop );
|
|
|
|
|
iLoop--;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2006-04-07 13:04:37 +00:00
|
|
|
|
p = refParams->Get( i );
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( p->GetType() == SbxERROR && ( i ) )
|
|
|
|
|
//if( p->GetType() == SbxEMPTY && ( i ) )
|
|
|
|
|
{
|
|
|
|
|
// Wenn ein Parameter fehlt, kann er OPTIONAL sein
|
|
|
|
|
BOOL bOpt = FALSE;
|
2006-10-12 13:31:26 +00:00
|
|
|
|
if( pMeth )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
SbxInfo* pInfo = pMeth->GetInfo();
|
|
|
|
|
if ( pInfo )
|
2004-03-17 12:37:42 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
const SbxParamInfo* pParam = pInfo->GetParam( i );
|
|
|
|
|
if( pParam && ( (pParam->nFlags & SBX_OPTIONAL) != 0 ) )
|
2004-03-17 12:37:42 +00:00
|
|
|
|
{
|
2006-10-12 13:31:26 +00:00
|
|
|
|
// Default value?
|
|
|
|
|
USHORT nDefaultId = sal::static_int_cast< USHORT >(
|
|
|
|
|
pParam->nUserData & 0xffff );
|
|
|
|
|
if( nDefaultId > 0 )
|
|
|
|
|
{
|
|
|
|
|
String aDefaultStr = pImg->GetString( nDefaultId );
|
|
|
|
|
p = new SbxVariable();
|
|
|
|
|
p->PutString( aDefaultStr );
|
|
|
|
|
refParams->Put( p, i );
|
|
|
|
|
}
|
|
|
|
|
bOpt = TRUE;
|
2004-03-17 12:37:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
if( bOpt == FALSE )
|
|
|
|
|
Error( SbERR_NOT_OPTIONAL );
|
|
|
|
|
}
|
|
|
|
|
else if( t != SbxVARIANT && (SbxDataType)(p->GetType() & 0x0FFF ) != t )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* q = new SbxVariable( t );
|
|
|
|
|
SaveRef( q );
|
|
|
|
|
*q = *p;
|
|
|
|
|
p = q;
|
|
|
|
|
}
|
|
|
|
|
SetupArgs( p, nOp1 );
|
|
|
|
|
PushVar( CheckArray( p ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Case-Test (+True-Target+Test-Opcode)
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepCASEIS( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
if( !refCaseStk || !refCaseStk->Count() )
|
|
|
|
|
StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SbxVariableRef xComp = PopVar();
|
|
|
|
|
SbxVariableRef xCase = refCaseStk->Get( refCaseStk->Count() - 1 );
|
|
|
|
|
if( xCase->Compare( (SbxOperator) nOp2, *xComp ) )
|
|
|
|
|
StepJUMP( nOp1 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Aufruf einer DLL-Prozedur (+StringID+Typ)
|
|
|
|
|
// Auch hier zeigt das MSB des StringIDs an, dass Argv belegt ist
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepCALL( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbxArray* pArgs = NULL;
|
|
|
|
|
if( nOp1 & 0x8000 )
|
|
|
|
|
pArgs = refArgv;
|
|
|
|
|
DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, FALSE );
|
|
|
|
|
aLibName = String();
|
|
|
|
|
if( nOp1 & 0x8000 )
|
|
|
|
|
PopArgv();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Aufruf einer DLL-Prozedur nach CDecl (+StringID+Typ)
|
|
|
|
|
// Auch hier zeigt das MSB des StringIDs an, dass Argv belegt ist
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepCALLC( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbxArray* pArgs = NULL;
|
|
|
|
|
if( nOp1 & 0x8000 )
|
|
|
|
|
pArgs = refArgv;
|
|
|
|
|
DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, TRUE );
|
|
|
|
|
aLibName = String();
|
|
|
|
|
if( nOp1 & 0x8000 )
|
|
|
|
|
PopArgv();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Beginn eines Statements (+Line+Col)
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepSTMNT( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Wenn der Expr-Stack am Anfang einen Statements eine Variable enthaelt,
|
|
|
|
|
// hat ein Trottel X als Funktion aufgerufen, obwohl es eine Variable ist!
|
|
|
|
|
BOOL bFatalExpr = FALSE;
|
2009-08-06 11:03:20 +00:00
|
|
|
|
String sUnknownMethodName;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( nExprLvl > 1 )
|
|
|
|
|
bFatalExpr = TRUE;
|
|
|
|
|
else if( nExprLvl )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* p = refExprStk->Get( 0 );
|
|
|
|
|
if( p->GetRefCount() > 1
|
|
|
|
|
&& refLocals.Is() && refLocals->Find( p->GetName(), p->GetClass() ) )
|
2009-08-06 11:03:20 +00:00
|
|
|
|
{
|
|
|
|
|
sUnknownMethodName = p->GetName();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
bFatalExpr = TRUE;
|
2009-08-06 11:03:20 +00:00
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
// Der Expr-Stack ist nun nicht mehr notwendig
|
|
|
|
|
ClearExprStack();
|
|
|
|
|
|
|
|
|
|
// #56368 Kuenstliche Referenz fuer StepElem wieder freigeben,
|
|
|
|
|
// damit sie nicht ueber ein Statement hinaus erhalten bleibt
|
|
|
|
|
//refSaveObj = NULL;
|
|
|
|
|
// #74254 Jetzt per Liste
|
|
|
|
|
ClearRefs();
|
|
|
|
|
|
|
|
|
|
// Wir muessen hier hart abbrechen, da sonst Zeile und Spalte nicht mehr
|
|
|
|
|
// stimmen!
|
|
|
|
|
if( bFatalExpr)
|
|
|
|
|
{
|
2009-08-06 11:03:20 +00:00
|
|
|
|
StarBASIC::FatalError( SbERR_NO_METHOD, sUnknownMethodName );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2006-11-01 15:17:07 +00:00
|
|
|
|
pStmnt = pCode - 9;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
USHORT nOld = nLine;
|
2006-11-03 14:11:10 +00:00
|
|
|
|
nLine = static_cast<short>( nOp1 );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// #29955 & 0xFF, um for-Schleifen-Ebene wegzufiltern
|
2006-11-03 14:11:10 +00:00
|
|
|
|
nCol1 = static_cast<short>( nOp2 & 0xFF );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Suchen des naechsten STMNT-Befehls,
|
|
|
|
|
// um die End-Spalte dieses Statements zu setzen
|
2004-09-08 13:55:48 +00:00
|
|
|
|
// Searches of the next STMNT instruction,
|
|
|
|
|
// around the final column of this statement to set
|
|
|
|
|
|
2006-06-19 16:47:47 +00:00
|
|
|
|
nCol2 = 0xffff;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
USHORT n1, n2;
|
|
|
|
|
const BYTE* p = pMod->FindNextStmnt( pCode, n1, n2 );
|
|
|
|
|
if( p )
|
|
|
|
|
{
|
|
|
|
|
if( n1 == nOp1 )
|
|
|
|
|
{
|
|
|
|
|
// #29955 & 0xFF, um for-Schleifen-Ebene wegzufiltern
|
|
|
|
|
nCol2 = (n2 & 0xFF) - 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #29955 for-Schleifen-Ebene korrigieren, #67452 NICHT im Error-Handler sonst Chaos
|
|
|
|
|
if( !bInError )
|
|
|
|
|
{
|
|
|
|
|
// (Bei Spr<70>ngen aus Schleifen tritt hier eine Differenz auf)
|
2006-11-03 14:11:10 +00:00
|
|
|
|
USHORT nExspectedForLevel = static_cast<USHORT>( nOp2 / 0x100 );
|
2004-11-15 15:38:03 +00:00
|
|
|
|
if( pGosubStk )
|
2006-10-12 13:31:26 +00:00
|
|
|
|
nExspectedForLevel = nExspectedForLevel + pGosubStk->nStartForLvl;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Wenn der tatsaechliche For-Level zu klein ist, wurde aus
|
|
|
|
|
// einer Schleife heraus gesprungen -> korrigieren
|
2004-11-15 15:38:03 +00:00
|
|
|
|
while( nForLvl > nExspectedForLevel )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
PopFor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
|
|
|
|
|
// Erkl<6B>rung siehe bei _ImplGetBreakCallLevel.
|
|
|
|
|
if( pInst->nCallLvl <= pInst->nBreakCallLvl )
|
|
|
|
|
//if( nFlags & SbDEBUG_STEPINTO )
|
|
|
|
|
{
|
|
|
|
|
StarBASIC* pStepBasic = GetCurrentBasic( &rBasic );
|
|
|
|
|
USHORT nNewFlags = pStepBasic->StepPoint( nLine, nCol1, nCol2 );
|
|
|
|
|
|
|
|
|
|
// Neuen BreakCallLevel ermitteln
|
|
|
|
|
pInst->CalcBreakCallLevel( nNewFlags );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Breakpoints nur bei STMNT-Befehlen in neuer Zeile!
|
|
|
|
|
else if( ( nOp1 != nOld )
|
|
|
|
|
&& ( nFlags & SbDEBUG_BREAK )
|
2006-11-03 14:11:10 +00:00
|
|
|
|
&& pMod->IsBP( static_cast<USHORT>( nOp1 ) ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
StarBASIC* pBreakBasic = GetCurrentBasic( &rBasic );
|
|
|
|
|
USHORT nNewFlags = pBreakBasic->BreakPoint( nLine, nCol1, nCol2 );
|
|
|
|
|
|
|
|
|
|
// Neuen BreakCallLevel ermitteln
|
|
|
|
|
pInst->CalcBreakCallLevel( nNewFlags );
|
|
|
|
|
//16.10.96, ALT:
|
|
|
|
|
//if( nNewFlags != SbDEBUG_CONTINUE )
|
|
|
|
|
// nFlags = nNewFlags;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// (+SvStreamFlags+Flags)
|
|
|
|
|
// Stack: Blocklaenge
|
|
|
|
|
// Kanalnummer
|
|
|
|
|
// Dateiname
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepOPEN( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
SbxVariableRef pName = PopVar();
|
|
|
|
|
SbxVariableRef pChan = PopVar();
|
|
|
|
|
SbxVariableRef pLen = PopVar();
|
|
|
|
|
short nBlkLen = pLen->GetInteger();
|
|
|
|
|
short nChan = pChan->GetInteger();
|
|
|
|
|
ByteString aName( pName->GetString(), gsl_getSystemTextEncoding() );
|
2006-11-03 14:11:10 +00:00
|
|
|
|
pIosys->Open( nChan, aName, static_cast<short>( nOp1 ),
|
|
|
|
|
static_cast<short>( nOp2 ), nBlkLen );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Error( pIosys->GetError() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Objekt kreieren (+StringID+StringID)
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepCREATE( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbxObject *pObj = SbxBase::CreateObject( aClass );
|
|
|
|
|
if( !pObj )
|
|
|
|
|
Error( SbERR_INVALID_OBJECT );
|
|
|
|
|
else
|
|
|
|
|
{
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pObj->SetName( aName );
|
|
|
|
|
// Das Objekt muss BASIC rufen koennen
|
|
|
|
|
pObj->SetParent( &rBasic );
|
|
|
|
|
SbxVariable* pNew = new SbxVariable;
|
|
|
|
|
pNew->PutObject( pObj );
|
|
|
|
|
PushVar( pNew );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepDCREATE( UINT32 nOp1, UINT32 nOp2 )
|
2003-03-18 15:28:40 +00:00
|
|
|
|
{
|
2006-06-19 16:47:47 +00:00
|
|
|
|
StepDCREATE_IMPL( nOp1, nOp2 );
|
2003-03-18 15:28:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepDCREATE_REDIMP( UINT32 nOp1, UINT32 nOp2 )
|
2003-03-18 15:28:40 +00:00
|
|
|
|
{
|
2006-06-19 16:47:47 +00:00
|
|
|
|
StepDCREATE_IMPL( nOp1, nOp2 );
|
2003-03-18 15:28:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Helper function for StepDCREATE_IMPL / bRedimp = true
|
|
|
|
|
void implCopyDimArray_DCREATE( SbxDimArray* pNewArray, SbxDimArray* pOldArray, short nMaxDimIndex,
|
|
|
|
|
short nActualDim, sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
|
|
|
|
|
{
|
|
|
|
|
sal_Int32& ri = pActualIndices[nActualDim];
|
|
|
|
|
for( ri = pLowerBounds[nActualDim] ; ri <= pUpperBounds[nActualDim] ; ri++ )
|
|
|
|
|
{
|
|
|
|
|
if( nActualDim < nMaxDimIndex )
|
|
|
|
|
{
|
|
|
|
|
implCopyDimArray_DCREATE( pNewArray, pOldArray, nMaxDimIndex, nActualDim + 1,
|
|
|
|
|
pActualIndices, pLowerBounds, pUpperBounds );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* pSource = pOldArray->Get32( pActualIndices );
|
|
|
|
|
pNewArray->Put32( pSource, pActualIndices );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #56204 Objekt-Array kreieren (+StringID+StringID), DCREATE == Dim-Create
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepDCREATE_IMPL( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
SbxVariableRef refVar = PopVar();
|
2003-03-18 15:28:40 +00:00
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
DimImpl( refVar );
|
|
|
|
|
|
|
|
|
|
// Das Array mit Instanzen der geforderten Klasse fuellen
|
|
|
|
|
SbxBaseRef xObj = (SbxBase*)refVar->GetObject();
|
|
|
|
|
if( !xObj )
|
|
|
|
|
{
|
|
|
|
|
StarBASIC::Error( SbERR_INVALID_OBJECT );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-08 13:55:48 +00:00
|
|
|
|
SbxDimArray* pArray = 0;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( xObj->ISA(SbxDimArray) )
|
|
|
|
|
{
|
|
|
|
|
SbxBase* pObj = (SbxBase*)xObj;
|
2003-03-18 15:28:40 +00:00
|
|
|
|
pArray = (SbxDimArray*)pObj;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Dimensionen auswerten
|
|
|
|
|
short nDims = pArray->GetDims();
|
2006-06-19 16:47:47 +00:00
|
|
|
|
INT32 nTotalSize = 0;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// es muss ein eindimensionales Array sein
|
2002-11-18 07:38:47 +00:00
|
|
|
|
INT32 nLower, nUpper, nSize;
|
2006-06-19 16:47:47 +00:00
|
|
|
|
INT32 i;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
for( i = 0 ; i < nDims ; i++ )
|
|
|
|
|
{
|
2002-11-18 07:38:47 +00:00
|
|
|
|
pArray->GetDim32( i+1, nLower, nUpper );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nSize = nUpper - nLower + 1;
|
|
|
|
|
if( i == 0 )
|
|
|
|
|
nTotalSize = nSize;
|
|
|
|
|
else
|
|
|
|
|
nTotalSize *= nSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Objekte anlegen und ins Array eintragen
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
for( i = 0 ; i < nTotalSize ; i++ )
|
|
|
|
|
{
|
2006-06-19 16:47:47 +00:00
|
|
|
|
SbxObject *pClassObj = SbxBase::CreateObject( aClass );
|
|
|
|
|
if( !pClassObj )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
Error( SbERR_INVALID_OBJECT );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
|
2006-06-19 16:47:47 +00:00
|
|
|
|
pClassObj->SetName( aName );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Das Objekt muss BASIC rufen koennen
|
2006-06-19 16:47:47 +00:00
|
|
|
|
pClassObj->SetParent( &rBasic );
|
|
|
|
|
pArray->SbxArray::Put32( pClassObj, i );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-03-18 15:28:40 +00:00
|
|
|
|
|
|
|
|
|
SbxDimArray* pOldArray = (SbxDimArray*)(SbxArray*)refRedimpArray;
|
|
|
|
|
if( pArray && pOldArray )
|
|
|
|
|
{
|
|
|
|
|
short nDimsNew = pArray->GetDims();
|
|
|
|
|
short nDimsOld = pOldArray->GetDims();
|
|
|
|
|
short nDims = nDimsNew;
|
|
|
|
|
BOOL bRangeError = FALSE;
|
|
|
|
|
|
|
|
|
|
// Store dims to use them for copying later
|
|
|
|
|
sal_Int32* pLowerBounds = new sal_Int32[nDims];
|
|
|
|
|
sal_Int32* pUpperBounds = new sal_Int32[nDims];
|
|
|
|
|
sal_Int32* pActualIndices = new sal_Int32[nDims];
|
|
|
|
|
if( nDimsOld != nDimsNew )
|
|
|
|
|
{
|
|
|
|
|
bRangeError = TRUE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Compare bounds
|
|
|
|
|
for( short i = 1 ; i <= nDims ; i++ )
|
|
|
|
|
{
|
|
|
|
|
sal_Int32 lBoundNew, uBoundNew;
|
|
|
|
|
sal_Int32 lBoundOld, uBoundOld;
|
|
|
|
|
pArray->GetDim32( i, lBoundNew, uBoundNew );
|
|
|
|
|
pOldArray->GetDim32( i, lBoundOld, uBoundOld );
|
|
|
|
|
|
|
|
|
|
lBoundNew = std::max( lBoundNew, lBoundOld );
|
|
|
|
|
uBoundNew = std::min( uBoundNew, uBoundOld );
|
|
|
|
|
short j = i - 1;
|
|
|
|
|
pActualIndices[j] = pLowerBounds[j] = lBoundNew;
|
|
|
|
|
pUpperBounds[j] = uBoundNew;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( bRangeError )
|
|
|
|
|
{
|
|
|
|
|
StarBASIC::Error( SbERR_OUT_OF_RANGE );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Copy data from old array by going recursively through all dimensions
|
|
|
|
|
// (It would be faster to work on the flat internal data array of an
|
|
|
|
|
// SbyArray but this solution is clearer and easier)
|
|
|
|
|
implCopyDimArray_DCREATE( pArray, pOldArray, nDims - 1,
|
|
|
|
|
0, pActualIndices, pLowerBounds, pUpperBounds );
|
|
|
|
|
}
|
2003-05-22 10:02:08 +00:00
|
|
|
|
delete [] pUpperBounds;
|
|
|
|
|
delete [] pLowerBounds;
|
|
|
|
|
delete [] pActualIndices;
|
2003-03-18 15:28:40 +00:00
|
|
|
|
refRedimpArray = NULL;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Objekt aus User-Type kreieren (+StringID+StringID)
|
2004-03-17 12:37:42 +00:00
|
|
|
|
|
|
|
|
|
SbxObject* createUserTypeImpl( const String& rClassName ); // sb.cxx
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepTCREATE( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
|
|
|
|
|
String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
|
2004-03-17 12:37:42 +00:00
|
|
|
|
|
|
|
|
|
SbxObject* pCopyObj = createUserTypeImpl( aClass );
|
|
|
|
|
if( pCopyObj )
|
|
|
|
|
pCopyObj->SetName( aName );
|
2005-03-29 10:53:06 +00:00
|
|
|
|
SbxVariable* pNew = new SbxVariable;
|
|
|
|
|
pNew->PutObject( pCopyObj );
|
2010-06-15 20:02:53 +02:00
|
|
|
|
pNew->SetDeclareClassName( aClass );
|
2005-03-29 10:53:06 +00:00
|
|
|
|
PushVar( pNew );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-06-15 20:02:53 +02:00
|
|
|
|
void SbiRuntime::implCreateFixedString( SbxVariable* pStrVar, UINT32 nOp2 )
|
|
|
|
|
{
|
|
|
|
|
USHORT nCount = static_cast<USHORT>( nOp2 >> 17 ); // len = all bits above 0x10000
|
|
|
|
|
String aStr;
|
|
|
|
|
aStr.Fill( nCount, 0 );
|
|
|
|
|
pStrVar->PutString( aStr );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Einrichten einer lokalen Variablen (+StringID+Typ)
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepLOCAL( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
if( !refLocals.Is() )
|
|
|
|
|
refLocals = new SbxArray;
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
|
2002-08-13 07:10:47 +00:00
|
|
|
|
if( refLocals->Find( aName, SbxCLASS_DONTCARE ) == NULL )
|
|
|
|
|
{
|
2010-06-15 20:02:53 +02:00
|
|
|
|
SbxDataType t = (SbxDataType)(nOp2 & 0xffff);
|
2002-08-13 07:10:47 +00:00
|
|
|
|
SbxVariable* p = new SbxVariable( t );
|
|
|
|
|
p->SetName( aName );
|
2010-06-15 20:02:53 +02:00
|
|
|
|
bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0);
|
|
|
|
|
if( bWithEvents )
|
|
|
|
|
p->SetFlag( SBX_WITH_EVENTS );
|
|
|
|
|
bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0);
|
|
|
|
|
if( bFixedString )
|
|
|
|
|
implCreateFixedString( p, nOp2 );
|
2002-08-13 07:10:47 +00:00
|
|
|
|
refLocals->Put( p, refLocals->Count() );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Einrichten einer modulglobalen Variablen (+StringID+Typ)
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepPUBLIC_Impl( UINT32 nOp1, UINT32 nOp2, bool bUsedForClassModule )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
|
2010-06-15 20:02:53 +02:00
|
|
|
|
SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
BOOL bFlag = pMod->IsSet( SBX_NO_MODIFY );
|
|
|
|
|
pMod->SetFlag( SBX_NO_MODIFY );
|
2001-09-04 10:16:07 +00:00
|
|
|
|
SbxVariableRef p = pMod->Find( aName, SbxCLASS_PROPERTY );
|
|
|
|
|
if( p.Is() )
|
|
|
|
|
pMod->Remove (p);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbProperty* pProp = pMod->GetProperty( aName, t );
|
2004-11-02 10:58:59 +00:00
|
|
|
|
if( !bUsedForClassModule )
|
|
|
|
|
pProp->SetFlag( SBX_PRIVATE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( !bFlag )
|
|
|
|
|
pMod->ResetFlag( SBX_NO_MODIFY );
|
|
|
|
|
if( pProp )
|
|
|
|
|
{
|
|
|
|
|
pProp->SetFlag( SBX_DONTSTORE );
|
|
|
|
|
// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
|
|
|
|
|
pProp->SetFlag( SBX_NO_MODIFY);
|
2010-06-15 20:02:53 +02:00
|
|
|
|
|
|
|
|
|
bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0);
|
|
|
|
|
if( bWithEvents )
|
|
|
|
|
pProp->SetFlag( SBX_WITH_EVENTS );
|
|
|
|
|
bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0);
|
|
|
|
|
if( bFixedString )
|
|
|
|
|
implCreateFixedString( p, nOp2 );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2004-11-02 10:58:59 +00:00
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepPUBLIC( UINT32 nOp1, UINT32 nOp2 )
|
2004-11-02 10:58:59 +00:00
|
|
|
|
{
|
|
|
|
|
StepPUBLIC_Impl( nOp1, nOp2, false );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-30 09:09:56 +00:00
|
|
|
|
void SbiRuntime::StepPUBLIC_P( UINT32 nOp1, UINT32 nOp2 )
|
|
|
|
|
{
|
|
|
|
|
// Creates module variable that isn't reinitialised when
|
|
|
|
|
// between invocations ( for VBASupport & document basic only )
|
|
|
|
|
if( pMod->pImage->bFirstInit )
|
2010-06-15 20:02:53 +02:00
|
|
|
|
{
|
|
|
|
|
bool bUsedForClassModule = pImg->GetFlag( SBIMG_CLASSMODULE );
|
|
|
|
|
StepPUBLIC_Impl( nOp1, nOp2, bUsedForClassModule );
|
|
|
|
|
}
|
2007-08-30 09:09:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Einrichten einer globalen Variablen (+StringID+Typ)
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepGLOBAL( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-11-02 10:58:59 +00:00
|
|
|
|
if( pImg->GetFlag( SBIMG_CLASSMODULE ) )
|
|
|
|
|
StepPUBLIC_Impl( nOp1, nOp2, true );
|
|
|
|
|
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
|
2010-07-05 13:58:36 +02:00
|
|
|
|
SbxDataType t = (SbxDataType)(nOp2 & 0xffff);;
|
|
|
|
|
|
|
|
|
|
// Store module scope variables at module scope
|
|
|
|
|
// in non vba mode these are stored at the library level :/
|
|
|
|
|
// not sure if this really should not be enabled for ALL basic
|
|
|
|
|
SbxObject* pStorage = &rBasic;
|
|
|
|
|
if ( SbiRuntime::isVBAEnabled() )
|
|
|
|
|
{
|
|
|
|
|
pStorage = pMod;
|
|
|
|
|
pMod->AddVarName( aName );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL bFlag = pStorage->IsSet( SBX_NO_MODIFY );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
rBasic.SetFlag( SBX_NO_MODIFY );
|
2010-07-05 13:58:36 +02:00
|
|
|
|
SbxVariableRef p = pStorage->Find( aName, SbxCLASS_PROPERTY );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( p.Is() )
|
2010-07-05 13:58:36 +02:00
|
|
|
|
pStorage->Remove (p);
|
|
|
|
|
p = pStorage->Make( aName, SbxCLASS_PROPERTY, t );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( !bFlag )
|
2010-07-05 13:58:36 +02:00
|
|
|
|
pStorage->ResetFlag( SBX_NO_MODIFY );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( p )
|
|
|
|
|
{
|
|
|
|
|
p->SetFlag( SBX_DONTSTORE );
|
|
|
|
|
// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
|
|
|
|
|
p->SetFlag( SBX_NO_MODIFY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-04 10:16:07 +00:00
|
|
|
|
|
|
|
|
|
// Creates global variable that isn't reinitialised when
|
|
|
|
|
// basic is restarted, P=PERSIST (+StringID+Typ)
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepGLOBAL_P( UINT32 nOp1, UINT32 nOp2 )
|
2001-09-04 10:16:07 +00:00
|
|
|
|
{
|
|
|
|
|
if( pMod->pImage->bFirstInit )
|
|
|
|
|
{
|
|
|
|
|
StepGLOBAL( nOp1, nOp2 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Searches for global variable, behavior depends on the fact
|
|
|
|
|
// if the variable is initialised for the first time
|
|
|
|
|
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepFIND_G( UINT32 nOp1, UINT32 nOp2 )
|
2001-09-04 10:16:07 +00:00
|
|
|
|
{
|
|
|
|
|
if( pMod->pImage->bFirstInit )
|
|
|
|
|
{
|
|
|
|
|
// Behave like always during first init
|
|
|
|
|
StepFIND( nOp1, nOp2 );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Return dummy variable
|
|
|
|
|
SbxDataType t = (SbxDataType) nOp2;
|
2006-11-03 14:11:10 +00:00
|
|
|
|
String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) );
|
2001-09-04 10:16:07 +00:00
|
|
|
|
|
|
|
|
|
SbxVariable* pDummyVar = new SbxVariable( t );
|
|
|
|
|
pDummyVar->SetName( aName );
|
|
|
|
|
PushVar( pDummyVar );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-07-02 09:14:41 +00:00
|
|
|
|
SbxVariable* SbiRuntime::StepSTATIC_Impl( String& aName, SbxDataType& t )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* p = NULL;
|
|
|
|
|
if ( pMeth )
|
|
|
|
|
{
|
|
|
|
|
SbxArray* pStatics = pMeth->GetStatics();
|
|
|
|
|
if( pStatics && ( pStatics->Find( aName, SbxCLASS_DONTCARE ) == NULL ) )
|
|
|
|
|
{
|
|
|
|
|
p = new SbxVariable( t );
|
|
|
|
|
if( t != SbxVARIANT )
|
|
|
|
|
p->SetFlag( SBX_FIXED );
|
|
|
|
|
p->SetName( aName );
|
|
|
|
|
pStatics->Put( p, pStatics->Count() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return p;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Einrichten einer statischen Variablen (+StringID+Typ)
|
2006-11-01 15:17:07 +00:00
|
|
|
|
void SbiRuntime::StepSTATIC( UINT32 nOp1, UINT32 nOp2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2008-07-02 09:14:41 +00:00
|
|
|
|
String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbxDataType t = (SbxDataType) nOp2;
|
2008-07-02 09:14:41 +00:00
|
|
|
|
StepSTATIC_Impl( aName, t );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|