| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_basic.hxx" |
| #include <tools/fsys.hxx> |
| #include <vcl/svapp.hxx> |
| #include <tools/wldcrd.hxx> |
| #include <svl/zforlist.hxx> |
| #include <unotools/syslocale.hxx> |
| #include "runtime.hxx" |
| #include "sbintern.hxx" |
| #include "opcodes.hxx" |
| #include "codegen.hxx" |
| #include "iosys.hxx" |
| #include "image.hxx" |
| #include "ddectrl.hxx" |
| #include "dllmgr.hxx" |
| #include <comphelper/processfactory.hxx> |
| #include <com/sun/star/container/XEnumerationAccess.hpp> |
| #include "sbunoobj.hxx" |
| #include "errobject.hxx" |
| #include "sbtrace.hxx" |
| #include "comenumwrapper.hxx" |
| |
| using namespace ::com::sun::star; |
| |
| bool SbiRuntime::isVBAEnabled() |
| { |
| bool result = false; |
| SbiInstance* pInst = pINST; |
| if ( pInst && pINST->pRun ) |
| result = pInst->pRun->bVBAEnabled; |
| return result; |
| } |
| |
| // #91147 Global reschedule flag |
| static sal_Bool bStaticGlobalEnableReschedule = sal_True; |
| |
| void StarBASIC::StaticEnableReschedule( sal_Bool bReschedule ) |
| { |
| bStaticGlobalEnableReschedule = bReschedule; |
| } |
| void StarBASIC::SetVBAEnabled( sal_Bool bEnabled ) |
| { |
| if ( bDocBasic ) |
| { |
| bVBAEnabled = bEnabled; |
| } |
| } |
| |
| sal_Bool StarBASIC::isVBAEnabled() |
| { |
| if ( bDocBasic ) |
| { |
| if( SbiRuntime::isVBAEnabled() ) |
| return sal_True; |
| return bVBAEnabled; |
| } |
| return sal_False; |
| } |
| |
| |
| struct SbiArgvStack { // Argv stack: |
| SbiArgvStack* pNext; // Stack Chain |
| SbxArrayRef refArgv; // Argv |
| short nArgc; // Argc |
| }; |
| |
| SbiRuntime::pStep0 SbiRuntime::aStep0[] = { // Alle Opcodes ohne Operanden |
| &SbiRuntime::StepNOP, |
| &SbiRuntime::StepEXP, |
| &SbiRuntime::StepMUL, |
| &SbiRuntime::StepDIV, |
| &SbiRuntime::StepMOD, |
| &SbiRuntime::StepPLUS, |
| &SbiRuntime::StepMINUS, |
| &SbiRuntime::StepNEG, |
| &SbiRuntime::StepEQ, |
| &SbiRuntime::StepNE, |
| &SbiRuntime::StepLT, |
| &SbiRuntime::StepGT, |
| &SbiRuntime::StepLE, |
| &SbiRuntime::StepGE, |
| &SbiRuntime::StepIDIV, |
| &SbiRuntime::StepAND, |
| &SbiRuntime::StepOR, |
| &SbiRuntime::StepXOR, |
| &SbiRuntime::StepEQV, |
| &SbiRuntime::StepIMP, |
| &SbiRuntime::StepNOT, |
| &SbiRuntime::StepCAT, |
| |
| &SbiRuntime::StepLIKE, |
| &SbiRuntime::StepIS, |
| // Laden/speichern |
| &SbiRuntime::StepARGC, // neuen Argv einrichten |
| &SbiRuntime::StepARGV, // TOS ==> aktueller Argv |
| &SbiRuntime::StepINPUT, // Input ==> TOS |
| &SbiRuntime::StepLINPUT, // Line Input ==> TOS |
| &SbiRuntime::StepGET, // TOS anfassen |
| &SbiRuntime::StepSET, // Speichern Objekt TOS ==> TOS-1 |
| &SbiRuntime::StepPUT, // TOS ==> TOS-1 |
| &SbiRuntime::StepPUTC, // TOS ==> TOS-1, dann ReadOnly |
| &SbiRuntime::StepDIM, // DIM |
| &SbiRuntime::StepREDIM, // REDIM |
| &SbiRuntime::StepREDIMP, // REDIM PRESERVE |
| &SbiRuntime::StepERASE, // TOS loeschen |
| // Verzweigen |
| &SbiRuntime::StepSTOP, // Programmende |
| &SbiRuntime::StepINITFOR, // FOR-Variable initialisieren |
| &SbiRuntime::StepNEXT, // FOR-Variable inkrementieren |
| &SbiRuntime::StepCASE, // Anfang CASE |
| &SbiRuntime::StepENDCASE, // Ende CASE |
| &SbiRuntime::StepSTDERROR, // Standard-Fehlerbehandlung |
| &SbiRuntime::StepNOERROR, // keine Fehlerbehandlung |
| &SbiRuntime::StepLEAVE, // UP verlassen |
| // E/A |
| &SbiRuntime::StepCHANNEL, // TOS = Kanalnummer |
| &SbiRuntime::StepPRINT, // print TOS |
| &SbiRuntime::StepPRINTF, // print TOS in field |
| &SbiRuntime::StepWRITE, // write TOS |
| &SbiRuntime::StepRENAME, // Rename Tos+1 to Tos |
| &SbiRuntime::StepPROMPT, // Input Prompt aus TOS definieren |
| &SbiRuntime::StepRESTART, // Set restart point |
| &SbiRuntime::StepCHANNEL0, // E/A-Kanal 0 einstellen |
| &SbiRuntime::StepEMPTY, // Leeren Ausdruck auf Stack |
| &SbiRuntime::StepERROR, // TOS = Fehlercode |
| &SbiRuntime::StepLSET, // Speichern Objekt TOS ==> TOS-1 |
| &SbiRuntime::StepRSET, // Speichern Objekt TOS ==> TOS-1 |
| &SbiRuntime::StepREDIMP_ERASE,// Copy array object for REDIMP |
| &SbiRuntime::StepINITFOREACH,// Init for each loop |
| &SbiRuntime::StepVBASET,// vba-like set statement |
| &SbiRuntime::StepERASE_CLEAR,// vba-like set statement |
| &SbiRuntime::StepARRAYACCESS,// access TOS as array |
| &SbiRuntime::StepBYVAL, // access TOS as array |
| }; |
| |
| SbiRuntime::pStep1 SbiRuntime::aStep1[] = { // Alle Opcodes mit einem Operanden |
| &SbiRuntime::StepLOADNC, // Laden einer numerischen Konstanten (+ID) |
| &SbiRuntime::StepLOADSC, // Laden einer Stringkonstanten (+ID) |
| &SbiRuntime::StepLOADI, // Immediate Load (+Wert) |
| &SbiRuntime::StepARGN, // Speichern eines named Args in Argv (+StringID) |
| &SbiRuntime::StepPAD, // String auf feste Laenge bringen (+Laenge) |
| // Verzweigungen |
| &SbiRuntime::StepJUMP, // Sprung (+Target) |
| &SbiRuntime::StepJUMPT, // TOS auswerten), bedingter Sprung (+Target) |
| &SbiRuntime::StepJUMPF, // TOS auswerten), bedingter Sprung (+Target) |
| &SbiRuntime::StepONJUMP, // TOS auswerten), Sprung in JUMP-Tabelle (+MaxVal) |
| &SbiRuntime::StepGOSUB, // UP-Aufruf (+Target) |
| &SbiRuntime::StepRETURN, // UP-Return (+0 oder Target) |
| &SbiRuntime::StepTESTFOR, // FOR-Variable testen), inkrementieren (+Endlabel) |
| &SbiRuntime::StepCASETO, // Tos+1 <= Case <= Tos), 2xremove (+Target) |
| &SbiRuntime::StepERRHDL, // Fehler-Handler (+Offset) |
| &SbiRuntime::StepRESUME, // Resume nach Fehlern (+0 or 1 or Label) |
| // E/A |
| &SbiRuntime::StepCLOSE, // (+Kanal/0) |
| &SbiRuntime::StepPRCHAR, // (+char) |
| // Verwaltung |
| &SbiRuntime::StepSETCLASS, // Set + Klassennamen testen (+StringId) |
| &SbiRuntime::StepTESTCLASS, // Check TOS class (+StringId) |
| &SbiRuntime::StepLIB, // Lib fuer Declare-Call (+StringId) |
| &SbiRuntime::StepBASED, // TOS wird um BASE erhoeht, BASE davor gepusht |
| &SbiRuntime::StepARGTYP, // Letzten Parameter in Argv konvertieren (+Typ) |
| &SbiRuntime::StepVBASETCLASS,// vba-like set statement |
| }; |
| |
| SbiRuntime::pStep2 SbiRuntime::aStep2[] = {// Alle Opcodes mit zwei Operanden |
| &SbiRuntime::StepRTL, // Laden aus RTL (+StringID+Typ) |
| &SbiRuntime::StepFIND, // Laden (+StringID+Typ) |
| &SbiRuntime::StepELEM, // Laden Element (+StringID+Typ) |
| &SbiRuntime::StepPARAM, // Parameter (+Offset+Typ) |
| // Verzweigen |
| &SbiRuntime::StepCALL, // Declare-Call (+StringID+Typ) |
| &SbiRuntime::StepCALLC, // CDecl-Declare-Call (+StringID+Typ) |
| &SbiRuntime::StepCASEIS, // Case-Test (+Test-Opcode+False-Target) |
| // Verwaltung |
| &SbiRuntime::StepSTMNT, // Beginn eines Statements (+Line+Col) |
| // E/A |
| &SbiRuntime::StepOPEN, // (+SvStreamFlags+Flags) |
| // Objekte |
| &SbiRuntime::StepLOCAL, // Lokale Variable definieren (+StringId+Typ) |
| &SbiRuntime::StepPUBLIC, // Modulglobale Variable (+StringID+Typ) |
| &SbiRuntime::StepGLOBAL, // Globale Variable definieren (+StringID+Typ) |
| &SbiRuntime::StepCREATE, // Objekt kreieren (+StringId+StringId) |
| &SbiRuntime::StepSTATIC, // Statische Variable (+StringId+StringId) |
| &SbiRuntime::StepTCREATE, // User Defined Objekte (+StringId+StringId) |
| &SbiRuntime::StepDCREATE, // Objekt-Array kreieren (+StringID+StringID) |
| &SbiRuntime::StepGLOBAL_P, // Globale Variable definieren, die beim Neustart |
| // von Basic nicht ueberschrieben wird (+StringID+Typ) |
| &SbiRuntime::StepFIND_G, // Sucht globale Variable mit Spezialbehandlung wegen _GLOBAL_P |
| &SbiRuntime::StepDCREATE_REDIMP, // Objekt-Array redimensionieren (+StringID+StringID) |
| &SbiRuntime::StepFIND_CM, // Search inside a class module (CM) to enable global search in time |
| &SbiRuntime::StepPUBLIC_P, // Search inside a class module (CM) to enable global search in time |
| &SbiRuntime::StepFIND_STATIC, // Search inside a class module (CM) to enable global search in time |
| }; |
| |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // SbiRTLData // |
| ////////////////////////////////////////////////////////////////////////// |
| |
| SbiRTLData::SbiRTLData() |
| { |
| pDir = 0; |
| nDirFlags = 0; |
| nCurDirPos = 0; |
| pWildCard = NULL; |
| } |
| |
| SbiRTLData::~SbiRTLData() |
| { |
| delete pDir; |
| pDir = 0; |
| delete pWildCard; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // SbiInstance // |
| ////////////////////////////////////////////////////////////////////////// |
| |
| // 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out |
| // Die Entscheidung, ob StepPoint aufgerufen werden soll, wird anhand des |
| // CallLevels getroffen. Angehalten wird, wenn der aktuelle CallLevel <= |
| // nBreakCallLvl ist. Der aktuelle CallLevel kann niemals kleiner als 1 |
| // sein, da er beim Aufruf einer Methode (auch main) inkrementiert wird. |
| // Daher bedeutet ein BreakCallLvl von 0, dass das Programm gar nicht |
| // angehalten wird. |
| // (siehe auch step2.cxx, SbiRuntime::StepSTMNT() ) |
| |
| // Hilfsfunktion, um den BreakCallLevel gemaess der der Debug-Flags zu ermitteln |
| void SbiInstance::CalcBreakCallLevel( sal_uInt16 nFlags ) |
| { |
| // Break-Flag wegfiltern |
| nFlags &= ~((sal_uInt16)SbDEBUG_BREAK); |
| |
| sal_uInt16 nRet; |
| switch( nFlags ) |
| { |
| case SbDEBUG_STEPINTO: |
| nRet = nCallLvl + 1; // CallLevel+1 wird auch angehalten |
| break; |
| case SbDEBUG_STEPOVER | SbDEBUG_STEPINTO: |
| nRet = nCallLvl; // Aktueller CallLevel wird angehalten |
| break; |
| case SbDEBUG_STEPOUT: |
| nRet = nCallLvl - 1; // Kleinerer CallLevel wird angehalten |
| break; |
| case SbDEBUG_CONTINUE: |
| // Basic-IDE liefert 0 statt SbDEBUG_CONTINUE, also auch default=continue |
| default: |
| nRet = 0; // CallLevel ist immer >0 -> kein StepPoint |
| } |
| nBreakCallLvl = nRet; // Ergebnis uebernehmen |
| } |
| |
| SbiInstance::SbiInstance( StarBASIC* p ) |
| { |
| pBasic = p; |
| pNext = NULL; |
| pRun = NULL; |
| pIosys = new SbiIoSystem; |
| pDdeCtrl = new SbiDdeControl; |
| pDllMgr = 0; // on demand |
| pNumberFormatter = 0; // on demand |
| nCallLvl = 0; |
| nBreakCallLvl = 0; |
| nErr = |
| nErl = 0; |
| bReschedule = sal_True; |
| bCompatibility = sal_False; |
| } |
| |
| SbiInstance::~SbiInstance() |
| { |
| while( pRun ) |
| { |
| SbiRuntime* p = pRun->pNext; |
| delete pRun; |
| pRun = p; |
| } |
| delete pIosys; |
| delete pDdeCtrl; |
| delete pDllMgr; |
| delete pNumberFormatter; |
| |
| try |
| { |
| int nSize = ComponentVector.size(); |
| if( nSize ) |
| { |
| for( int i = nSize - 1 ; i >= 0 ; --i ) |
| { |
| Reference< XComponent > xDlgComponent = ComponentVector[i]; |
| if( xDlgComponent.is() ) |
| xDlgComponent->dispose(); |
| } |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERROR( "SbiInstance::~SbiInstance: caught an exception while disposing the components!" ); |
| } |
| |
| ComponentVector.clear(); |
| } |
| |
| SbiDllMgr* SbiInstance::GetDllMgr() |
| { |
| if( !pDllMgr ) |
| pDllMgr = new SbiDllMgr; |
| return pDllMgr; |
| } |
| |
| // #39629 NumberFormatter jetzt ueber statische Methode anlegen |
| SvNumberFormatter* SbiInstance::GetNumberFormatter() |
| { |
| LanguageType eLangType = GetpApp()->GetSettings().GetLanguage(); |
| SvtSysLocale aSysLocale; |
| DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat(); |
| if( pNumberFormatter ) |
| { |
| if( eLangType != meFormatterLangType || |
| eDate != meFormatterDateFormat ) |
| { |
| delete pNumberFormatter; |
| pNumberFormatter = NULL; |
| } |
| } |
| meFormatterLangType = eLangType; |
| meFormatterDateFormat = eDate; |
| if( !pNumberFormatter ) |
| PrepareNumberFormatter( pNumberFormatter, nStdDateIdx, nStdTimeIdx, nStdDateTimeIdx, |
| &meFormatterLangType, &meFormatterDateFormat ); |
| return pNumberFormatter; |
| } |
| |
| // #39629 NumberFormatter auch statisch anbieten |
| void SbiInstance::PrepareNumberFormatter( SvNumberFormatter*& rpNumberFormatter, |
| sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx, |
| LanguageType* peFormatterLangType, DateFormat* peFormatterDateFormat ) |
| { |
| com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > |
| xFactory = comphelper::getProcessServiceFactory(); |
| |
| LanguageType eLangType; |
| if( peFormatterLangType ) |
| eLangType = *peFormatterLangType; |
| else |
| eLangType = GetpApp()->GetSettings().GetLanguage(); |
| |
| DateFormat eDate; |
| if( peFormatterDateFormat ) |
| eDate = *peFormatterDateFormat; |
| else |
| { |
| SvtSysLocale aSysLocale; |
| eDate = aSysLocale.GetLocaleData().getDateFormat(); |
| } |
| |
| rpNumberFormatter = new SvNumberFormatter( xFactory, eLangType ); |
| |
| xub_StrLen nCheckPos = 0; short nType; |
| rnStdTimeIdx = rpNumberFormatter->GetStandardFormat( NUMBERFORMAT_TIME, eLangType ); |
| |
| // Standard-Vorlagen des Formatters haben nur zweistellige |
| // Jahreszahl. Deshalb eigenes Format registrieren |
| |
| // HACK, da der Numberformatter in PutandConvertEntry die Platzhalter |
| // fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung |
| // austauscht. Problem: Print Year(Date) unter engl. BS |
| // siehe auch svtools\source\sbx\sbxdate.cxx |
| |
| String aDateStr; |
| switch( eDate ) |
| { |
| case MDY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") ); break; |
| case DMY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("TT.MM.JJJJ") ); break; |
| case YMD: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("JJJJ.MM.TT") ); break; |
| default: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") ); |
| } |
| String aStr( aDateStr ); |
| rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType, |
| rnStdDateIdx, LANGUAGE_GERMAN, eLangType ); |
| nCheckPos = 0; |
| String aStrHHMMSS( RTL_CONSTASCII_USTRINGPARAM(" HH:MM:SS") ); |
| aStr = aDateStr; |
| aStr += aStrHHMMSS; |
| rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType, |
| rnStdDateTimeIdx, LANGUAGE_GERMAN, eLangType ); |
| } |
| |
| |
| |
| // Engine laufenlassen. Falls Flags == SbDEBUG_CONTINUE, Flags uebernehmen |
| |
| void SbiInstance::Stop() |
| { |
| for( SbiRuntime* p = pRun; p; p = p->pNext ) |
| p->Stop(); |
| } |
| |
| // Allows Basic IDE to set watch mode to suppress errors |
| static bool bWatchMode = false; |
| |
| void setBasicWatchMode( bool bOn ) |
| { |
| bWatchMode = bOn; |
| } |
| |
| void SbiInstance::Error( SbError n ) |
| { |
| Error( n, String() ); |
| } |
| |
| void SbiInstance::Error( SbError n, const String& rMsg ) |
| { |
| if( !bWatchMode ) |
| { |
| aErrorMsg = rMsg; |
| pRun->Error( n ); |
| } |
| } |
| |
| void SbiInstance::ErrorVB( sal_Int32 nVBNumber, const String& rMsg ) |
| { |
| if( !bWatchMode ) |
| { |
| SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) ); |
| if ( !n ) |
| n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors |
| |
| aErrorMsg = rMsg; |
| SbiRuntime::translateErrorToVba( n, aErrorMsg ); |
| |
| bool bVBATranslationAlreadyDone = true; |
| pRun->Error( SbERR_BASIC_COMPAT, bVBATranslationAlreadyDone ); |
| } |
| } |
| |
| void SbiInstance::setErrorVB( sal_Int32 nVBNumber, const String& rMsg ) |
| { |
| SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) ); |
| if( !n ) |
| n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors |
| |
| aErrorMsg = rMsg; |
| SbiRuntime::translateErrorToVba( n, aErrorMsg ); |
| |
| nErr = n; |
| } |
| |
| |
| void SbiInstance::FatalError( SbError n ) |
| { |
| pRun->FatalError( n ); |
| } |
| |
| void SbiInstance::FatalError( SbError _errCode, const String& _details ) |
| { |
| pRun->FatalError( _errCode, _details ); |
| } |
| |
| void SbiInstance::Abort() |
| { |
| // Basic suchen, in dem der Fehler auftrat |
| StarBASIC* pErrBasic = GetCurrentBasic( pBasic ); |
| pErrBasic->RTError( nErr, aErrorMsg, pRun->nLine, pRun->nCol1, pRun->nCol2 ); |
| pBasic->Stop(); |
| } |
| |
| // Hilfsfunktion, um aktives Basic zu finden, kann ungleich pRTBasic sein |
| StarBASIC* GetCurrentBasic( StarBASIC* pRTBasic ) |
| { |
| StarBASIC* pCurBasic = pRTBasic; |
| SbModule* pActiveModule = pRTBasic->GetActiveModule(); |
| if( pActiveModule ) |
| { |
| SbxObject* pParent = pActiveModule->GetParent(); |
| if( pParent && pParent->ISA(StarBASIC) ) |
| pCurBasic = (StarBASIC*)pParent; |
| } |
| return pCurBasic; |
| } |
| |
| SbModule* SbiInstance::GetActiveModule() |
| { |
| if( pRun ) |
| return pRun->GetModule(); |
| else |
| return NULL; |
| } |
| |
| SbMethod* SbiInstance::GetCaller( sal_uInt16 nLevel ) |
| { |
| SbiRuntime* p = pRun; |
| while( nLevel-- && p ) |
| p = p->pNext; |
| if( p ) |
| return p->GetCaller(); |
| else |
| return NULL; |
| } |
| |
| SbxArray* SbiInstance::GetLocals( SbMethod* pMeth ) |
| { |
| SbiRuntime* p = pRun; |
| while( p && p->GetMethod() != pMeth ) |
| p = p->pNext; |
| if( p ) |
| return p->GetLocals(); |
| else |
| return NULL; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // SbiInstance // |
| ////////////////////////////////////////////////////////////////////////// |
| |
| // Achtung: pMeth kann auch NULL sein (beim Aufruf des Init-Codes) |
| |
| SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, sal_uInt32 nStart ) |
| : rBasic( *(StarBASIC*)pm->pParent ), pInst( pINST ), |
| pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), m_nLastTime(0) |
| { |
| nFlags = pe ? pe->GetDebugFlags() : 0; |
| pIosys = pInst->pIosys; |
| pArgvStk = NULL; |
| pGosubStk = NULL; |
| pForStk = NULL; |
| pError = NULL; |
| pErrCode = |
| pErrStmnt = |
| pRestart = NULL; |
| pNext = NULL; |
| pCode = |
| pStmnt = (const sal_uInt8* ) pImg->GetCode() + nStart; |
| bRun = |
| bError = sal_True; |
| bInError = sal_False; |
| bBlocked = sal_False; |
| nLine = 0; |
| nCol1 = 0; |
| nCol2 = 0; |
| nExprLvl = 0; |
| nArgc = 0; |
| nError = 0; |
| nGosubLvl = 0; |
| nForLvl = 0; |
| nOps = 0; |
| refExprStk = new SbxArray; |
| SetVBAEnabled( pMod->IsVBACompat() ); |
| #if defined GCC |
| SetParameters( pe ? pe->GetParameters() : (class SbxArray *)NULL ); |
| #else |
| SetParameters( pe ? pe->GetParameters() : NULL ); |
| #endif |
| pRefSaveList = NULL; |
| pItemStoreList = NULL; |
| } |
| |
| SbiRuntime::~SbiRuntime() |
| { |
| ClearGosubStack(); |
| ClearArgvStack(); |
| ClearForStack(); |
| |
| // #74254 Items zum Sichern temporaere Referenzen freigeben |
| ClearRefs(); |
| while( pItemStoreList ) |
| { |
| RefSaveItem* pToDeleteItem = pItemStoreList; |
| pItemStoreList = pToDeleteItem->pNext; |
| delete pToDeleteItem; |
| } |
| } |
| |
| void SbiRuntime::SetVBAEnabled(bool bEnabled ) |
| { |
| bVBAEnabled = bEnabled; |
| } |
| |
| // Aufbau der Parameterliste. Alle ByRef-Parameter werden direkt |
| // uebernommen; von ByVal-Parametern werden Kopien angelegt. Falls |
| // ein bestimmter Datentyp verlangt wird, wird konvertiert. |
| |
| void SbiRuntime::SetParameters( SbxArray* pParams ) |
| { |
| refParams = new SbxArray; |
| // fuer den Returnwert |
| refParams->Put( pMeth, 0 ); |
| |
| SbxInfo* pInfo = pMeth ? pMeth->GetInfo() : NULL; |
| sal_uInt16 nParamCount = pParams ? pParams->Count() : 1; |
| if( nParamCount > 1 ) |
| { |
| for( sal_uInt16 i = 1 ; i < nParamCount ; i++ ) |
| { |
| const SbxParamInfo* p = pInfo ? pInfo->GetParam( i ) : NULL; |
| |
| // #111897 ParamArray |
| if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 ) |
| { |
| SbxDimArray* pArray = new SbxDimArray( SbxVARIANT ); |
| sal_uInt16 nParamArrayParamCount = nParamCount - i; |
| pArray->unoAddDim( 0, nParamArrayParamCount - 1 ); |
| for( sal_uInt16 j = i ; j < nParamCount ; j++ ) |
| { |
| SbxVariable* v = pParams->Get( j ); |
| short nDimIndex = j - i; |
| pArray->Put( v, &nDimIndex ); |
| } |
| SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT ); |
| pArrayVar->SetFlag( SBX_READWRITE ); |
| pArrayVar->PutObject( pArray ); |
| refParams->Put( pArrayVar, i ); |
| |
| // Block ParamArray for missing parameter |
| pInfo = NULL; |
| break; |
| } |
| |
| SbxVariable* v = pParams->Get( i ); |
| // Methoden sind immer byval! |
| sal_Bool bByVal = v->IsA( TYPE(SbxMethod) ); |
| SbxDataType t = v->GetType(); |
| bool bTargetTypeIsArray = false; |
| if( p ) |
| { |
| bByVal |= sal_Bool( ( p->eType & SbxBYREF ) == 0 ); |
| t = (SbxDataType) ( p->eType & 0x0FFF ); |
| |
| if( !bByVal && t != SbxVARIANT && |
| (!v->IsFixed() || (SbxDataType)(v->GetType() & 0x0FFF ) != t) ) |
| bByVal = sal_True; |
| |
| bTargetTypeIsArray = (p->nUserData & PARAM_INFO_WITHBRACKETS) != 0; |
| } |
| if( bByVal ) |
| { |
| if( bTargetTypeIsArray ) |
| t = SbxOBJECT; |
| SbxVariable* v2 = new SbxVariable( t ); |
| v2->SetFlag( SBX_READWRITE ); |
| *v2 = *v; |
| refParams->Put( v2, i ); |
| } |
| else |
| { |
| if( t != SbxVARIANT && t != ( v->GetType() & 0x0FFF ) ) |
| { |
| // Array konvertieren?? |
| if( p && (p->eType & SbxARRAY) ) |
| Error( SbERR_CONVERSION ); |
| else |
| v->Convert( t ); |
| } |
| refParams->Put( v, i ); |
| } |
| if( p ) |
| refParams->PutAlias( p->aName, i ); |
| } |
| } |
| |
| // ParamArray for missing parameter |
| if( pInfo ) |
| { |
| // #111897 Check first missing parameter for ParamArray |
| const SbxParamInfo* p = pInfo->GetParam( nParamCount ); |
| if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 ) |
| { |
| SbxDimArray* pArray = new SbxDimArray( SbxVARIANT ); |
| pArray->unoAddDim( 0, -1 ); |
| SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT ); |
| pArrayVar->SetFlag( SBX_READWRITE ); |
| pArrayVar->PutObject( pArray ); |
| refParams->Put( pArrayVar, nParamCount ); |
| } |
| } |
| } |
| |
| |
| // Einen P-Code ausfuehren |
| |
| sal_Bool SbiRuntime::Step() |
| { |
| if( bRun ) |
| { |
| // Unbedingt gelegentlich die Kontrolle abgeben! |
| if( !( ++nOps & 0xF ) && pInst->IsReschedule() && bStaticGlobalEnableReschedule ) |
| { |
| sal_uInt32 nTime = osl_getGlobalTimer(); |
| if (nTime - m_nLastTime > 5 ) // 20 ms |
| { |
| Application::Reschedule(); |
| m_nLastTime = nTime; |
| } |
| } |
| |
| // #i48868 blocked by next call level? |
| while( bBlocked ) |
| { |
| if( pInst->IsReschedule() && bStaticGlobalEnableReschedule ) |
| Application::Reschedule(); |
| } |
| |
| #ifdef DBG_TRACE_BASIC |
| sal_uInt32 nPC = ( pCode - (const sal_uInt8* )pImg->GetCode() ); |
| dbg_traceStep( pMod, nPC, pINST->nCallLvl ); |
| #endif |
| |
| SbiOpcode eOp = (SbiOpcode ) ( *pCode++ ); |
| sal_uInt32 nOp1, nOp2; |
| if (eOp < SbOP0_END) |
| { |
| (this->*( aStep0[ eOp ] ) )(); |
| } |
| else if (eOp >= SbOP1_START && eOp < SbOP1_END) |
| { |
| nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24; |
| |
| (this->*( aStep1[ eOp - SbOP1_START ] ) )( nOp1 ); |
| } |
| else if (eOp >= SbOP2_START && eOp < SbOP2_END) |
| { |
| nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24; |
| nOp2 = *pCode++; nOp2 |= *pCode++ << 8; nOp2 |= *pCode++ << 16; nOp2 |= *pCode++ << 24; |
| (this->*( aStep2[ eOp - SbOP2_START ] ) )( nOp1, nOp2 ); |
| } |
| else |
| StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); |
| |
| // SBX-Fehler aufgetreten? |
| SbError nSbError = SbxBase::GetError(); |
| Error( ERRCODE_TOERROR(nSbError) ); // Warnings rausfiltern |
| |
| // AB 13.2.1997, neues Error-Handling: |
| // ACHTUNG: Hier kann nError auch dann gesetzt sein, wenn !nSbError, |
| // da nError jetzt auch von anderen RT-Instanzen gesetzt werden kann |
| |
| if( nError ) |
| SbxBase::ResetError(); |
| |
| // AB,15.3.96: Fehler nur anzeigen, wenn BASIC noch aktiv |
| // (insbesondere nicht nach Compiler-Fehlern zur Laufzeit) |
| if( nError && bRun ) |
| { |
| #ifdef DBG_TRACE_BASIC |
| SbError nTraceErr = nError; |
| String aTraceErrMsg = GetSbData()->aErrMsg; |
| bool bTraceErrHandled = true; |
| #endif |
| SbError err = nError; |
| ClearExprStack(); |
| nError = 0; |
| pInst->nErr = err; |
| pInst->nErl = nLine; |
| pErrCode = pCode; |
| pErrStmnt = pStmnt; |
| // An error occurred in an error handler |
| // force parent handler ( if there is one ) |
| // to handle the error |
| bool bLetParentHandleThis = false; |
| |
| // Im Error Handler? Dann Std-Error |
| if ( !bInError ) |
| { |
| bInError = sal_True; |
| |
| if( !bError ) // On Error Resume Next |
| StepRESUME( 1 ); |
| else if( pError ) // On Error Goto ... |
| pCode = pError; |
| else |
| bLetParentHandleThis = true; |
| } |
| else |
| { |
| bLetParentHandleThis = true; |
| pError = NULL; //terminate the handler |
| } |
| if ( bLetParentHandleThis ) |
| { |
| // AB 13.2.1997, neues Error-Handling: |
| // Uebergeordnete Error-Handler beruecksichtigen |
| |
| // Wir haben keinen Error-Handler -> weiter oben suchen |
| SbiRuntime* pRtErrHdl = NULL; |
| SbiRuntime* pRt = this; |
| while( NULL != (pRt = pRt->pNext) ) |
| { |
| // Gibt es einen Error-Handler? |
| if( pRt->bError == sal_False || pRt->pError != NULL ) |
| { |
| pRtErrHdl = pRt; |
| break; |
| } |
| } |
| |
| // Error-Hdl gefunden? |
| if( pRtErrHdl ) |
| { |
| // (Neuen) Error-Stack anlegen |
| SbErrorStack*& rErrStack = GetSbData()->pErrStack; |
| if( rErrStack ) |
| delete rErrStack; |
| rErrStack = new SbErrorStack(); |
| |
| // Alle im Call-Stack darunter stehenden RTs manipulieren |
| pRt = this; |
| do |
| { |
| // Fehler setzen |
| pRt->nError = err; |
| if( pRt != pRtErrHdl ) |
| pRt->bRun = sal_False; |
| |
| // In Error-Stack eintragen |
| SbErrorStackEntry *pEntry = new SbErrorStackEntry |
| ( pRt->pMeth, pRt->nLine, pRt->nCol1, pRt->nCol2 ); |
| rErrStack->C40_INSERT(SbErrorStackEntry, pEntry, rErrStack->Count() ); |
| |
| // Nach RT mit Error-Handler aufhoeren |
| if( pRt == pRtErrHdl ) |
| break; |
| pRt = pRt->pNext; |
| } |
| while( pRt ); |
| } |
| // Kein Error-Hdl gefunden -> altes Vorgehen |
| else |
| { |
| #ifdef DBG_TRACE_BASIC |
| bTraceErrHandled = false; |
| #endif |
| pInst->Abort(); |
| } |
| |
| // ALT: Nur |
| // pInst->Abort(); |
| } |
| |
| #ifdef DBG_TRACE_BASIC |
| dbg_traceNotifyError( nTraceErr, aTraceErrMsg, bTraceErrHandled, pINST->nCallLvl ); |
| #endif |
| } |
| } |
| return bRun; |
| } |
| |
| void SbiRuntime::Error( SbError n, bool bVBATranslationAlreadyDone ) |
| { |
| if( n ) |
| { |
| nError = n; |
| if( isVBAEnabled() && !bVBATranslationAlreadyDone ) |
| { |
| String aMsg = pInst->GetErrorMsg(); |
| sal_Int32 nVBAErrorNumber = translateErrorToVba( nError, aMsg ); |
| SbxVariable* pSbxErrObjVar = SbxErrObject::getErrObject(); |
| SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pSbxErrObjVar ); |
| if( pGlobErr != NULL ) |
| pGlobErr->setNumberAndDescription( nVBAErrorNumber, aMsg ); |
| |
| pInst->aErrorMsg = aMsg; |
| nError = SbERR_BASIC_COMPAT; |
| } |
| } |
| } |
| |
| void SbiRuntime::Error( SbError _errCode, const String& _details ) |
| { |
| if ( _errCode ) |
| { |
| // Not correct for class module usage, remove for now |
| //OSL_ENSURE( pInst->pRun == this, "SbiRuntime::Error: can't propagate the error message details!" ); |
| if ( pInst->pRun == this ) |
| { |
| pInst->Error( _errCode, _details ); |
| //OSL_POSTCOND( nError == _errCode, "SbiRuntime::Error: the instance is expecte to propagate the error code back to me!" ); |
| } |
| else |
| { |
| nError = _errCode; |
| } |
| } |
| } |
| |
| void SbiRuntime::FatalError( SbError n ) |
| { |
| StepSTDERROR(); |
| Error( n ); |
| } |
| |
| void SbiRuntime::FatalError( SbError _errCode, const String& _details ) |
| { |
| StepSTDERROR(); |
| Error( _errCode, _details ); |
| } |
| |
| sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, String& rMsg ) |
| { |
| // If a message is defined use that ( in preference to |
| // the defined one for the error ) NB #TODO |
| // if there is an error defined it more than likely |
| // is not the one you want ( some are the same though ) |
| // we really need a new vba compatible error list |
| if ( !rMsg.Len() ) |
| { |
| // TEST, has to be vb here always |
| #ifdef DBG_UTIL |
| SbError nTmp = StarBASIC::GetSfxFromVBError( (sal_uInt16)nError ); |
| DBG_ASSERT( nTmp, "No VB error!" ); |
| #endif |
| |
| StarBASIC::MakeErrorText( nError, rMsg ); |
| rMsg = StarBASIC::GetErrorText(); |
| if ( !rMsg.Len() ) // no message for err no, need localized resource here |
| rMsg = String( RTL_CONSTASCII_USTRINGPARAM("Internal Object Error:") ); |
| } |
| // no num? most likely then it *is* really a vba err |
| sal_uInt16 nVBErrorCode = StarBASIC::GetVBErrorCode( nError ); |
| sal_Int32 nVBAErrorNumber = ( nVBErrorCode == 0 ) ? nError : nVBErrorCode; |
| return nVBAErrorNumber; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // |
| // Parameter, Locals, Caller |
| // |
| ////////////////////////////////////////////////////////////////////////// |
| |
| SbMethod* SbiRuntime::GetCaller() |
| { |
| return pMeth; |
| } |
| |
| SbxArray* SbiRuntime::GetLocals() |
| { |
| return refLocals; |
| } |
| |
| SbxArray* SbiRuntime::GetParams() |
| { |
| return refParams; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // |
| // Stacks |
| // |
| ////////////////////////////////////////////////////////////////////////// |
| |
| // Der Expression-Stack steht fuer die laufende Auswertung von Expressions |
| // zur Verfuegung. |
| |
| void SbiRuntime::PushVar( SbxVariable* pVar ) |
| { |
| if( pVar ) |
| refExprStk->Put( pVar, nExprLvl++ ); |
| } |
| |
| SbxVariableRef SbiRuntime::PopVar() |
| { |
| #ifdef DBG_UTIL |
| if( !nExprLvl ) |
| { |
| StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); |
| return new SbxVariable; |
| } |
| #endif |
| SbxVariableRef xVar = refExprStk->Get( --nExprLvl ); |
| #ifdef DBG_UTIL |
| if ( xVar->GetName().EqualsAscii( "Cells" ) ) |
| DBG_TRACE( "" ); |
| #endif |
| // Methods halten im 0.Parameter sich selbst, also weghauen |
| if( xVar->IsA( TYPE(SbxMethod) ) ) |
| xVar->SetParameters(0); |
| return xVar; |
| } |
| |
| sal_Bool SbiRuntime::ClearExprStack() |
| { |
| // Achtung: Clear() reicht nicht, da Methods geloescht werden muessen |
| while ( nExprLvl ) |
| { |
| PopVar(); |
| } |
| refExprStk->Clear(); |
| return sal_False; |
| } |
| |
| // Variable auf dem Expression-Stack holen, ohne sie zu entfernen |
| // n zaehlt ab 0. |
| |
| SbxVariable* SbiRuntime::GetTOS( short n ) |
| { |
| n = nExprLvl - n - 1; |
| #ifdef DBG_UTIL |
| if( n < 0 ) |
| { |
| StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); |
| return new SbxVariable; |
| } |
| #endif |
| return refExprStk->Get( (sal_uInt16) n ); |
| } |
| |
| // Sicherstellen, dass TOS eine temporaere Variable ist |
| |
| void SbiRuntime::TOSMakeTemp() |
| { |
| SbxVariable* p = refExprStk->Get( nExprLvl - 1 ); |
| if( p->GetRefCount() != 1 ) |
| { |
| SbxVariable* pNew = new SbxVariable( *p ); |
| pNew->SetFlag( SBX_READWRITE ); |
| refExprStk->Put( pNew, nExprLvl - 1 ); |
| } |
| } |
| |
| // Der GOSUB-Stack nimmt Returnadressen fuer GOSUBs auf |
| |
| void SbiRuntime::PushGosub( const sal_uInt8* pc ) |
| { |
| if( ++nGosubLvl > MAXRECURSION ) |
| StarBASIC::FatalError( SbERR_STACK_OVERFLOW ); |
| SbiGosubStack* p = new SbiGosubStack; |
| p->pCode = pc; |
| p->pNext = pGosubStk; |
| p->nStartForLvl = nForLvl; |
| pGosubStk = p; |
| } |
| |
| void SbiRuntime::PopGosub() |
| { |
| if( !pGosubStk ) |
| Error( SbERR_NO_GOSUB ); |
| else |
| { |
| SbiGosubStack* p = pGosubStk; |
| pCode = p->pCode; |
| pGosubStk = p->pNext; |
| delete p; |
| nGosubLvl--; |
| } |
| } |
| |
| // Entleeren des GOSUB-Stacks |
| |
| void SbiRuntime::ClearGosubStack() |
| { |
| SbiGosubStack* p; |
| while(( p = pGosubStk ) != NULL ) |
| pGosubStk = p->pNext, delete p; |
| nGosubLvl = 0; |
| } |
| |
| // Der Argv-Stack nimmt aktuelle Argument-Vektoren auf |
| |
| void SbiRuntime::PushArgv() |
| { |
| SbiArgvStack* p = new SbiArgvStack; |
| p->refArgv = refArgv; |
| p->nArgc = nArgc; |
| nArgc = 1; |
| refArgv.Clear(); |
| p->pNext = pArgvStk; |
| pArgvStk = p; |
| } |
| |
| void SbiRuntime::PopArgv() |
| { |
| if( pArgvStk ) |
| { |
| SbiArgvStack* p = pArgvStk; |
| pArgvStk = p->pNext; |
| refArgv = p->refArgv; |
| nArgc = p->nArgc; |
| delete p; |
| } |
| } |
| |
| // Entleeren des Argv-Stacks |
| |
| void SbiRuntime::ClearArgvStack() |
| { |
| while( pArgvStk ) |
| PopArgv(); |
| } |
| |
| // Push des For-Stacks. Der Stack hat Inkrement, Ende, Beginn und Variable. |
| // Nach Aufbau des Stack-Elements ist der Stack leer. |
| |
| void SbiRuntime::PushFor() |
| { |
| SbiForStack* p = new SbiForStack; |
| p->eForType = FOR_TO; |
| p->pNext = pForStk; |
| pForStk = p; |
| // Der Stack ist wie folgt aufgebaut: |
| p->refInc = PopVar(); |
| p->refEnd = PopVar(); |
| SbxVariableRef xBgn = PopVar(); |
| p->refVar = PopVar(); |
| *(p->refVar) = *xBgn; |
| nForLvl++; |
| } |
| |
| void SbiRuntime::PushForEach() |
| { |
| SbiForStack* p = new SbiForStack; |
| p->pNext = pForStk; |
| pForStk = p; |
| |
| SbxVariableRef xObjVar = PopVar(); |
| SbxBase* pObj = xObjVar.Is() ? xObjVar->GetObject() : NULL; |
| if( pObj == NULL ) |
| { |
| Error( SbERR_NO_OBJECT ); |
| return; |
| } |
| |
| bool bError_ = false; |
| BasicCollection* pCollection; |
| SbxDimArray* pArray; |
| SbUnoObject* pUnoObj; |
| if( (pArray = PTR_CAST(SbxDimArray,pObj)) != NULL ) |
| { |
| p->eForType = FOR_EACH_ARRAY; |
| p->refEnd = (SbxVariable*)pArray; |
| |
| short nDims = pArray->GetDims(); |
| p->pArrayLowerBounds = new sal_Int32[nDims]; |
| p->pArrayUpperBounds = new sal_Int32[nDims]; |
| p->pArrayCurIndices = new sal_Int32[nDims]; |
| sal_Int32 lBound, uBound; |
| for( short i = 0 ; i < nDims ; i++ ) |
| { |
| pArray->GetDim32( i+1, lBound, uBound ); |
| p->pArrayCurIndices[i] = p->pArrayLowerBounds[i] = lBound; |
| p->pArrayUpperBounds[i] = uBound; |
| } |
| } |
| else if( (pCollection = PTR_CAST(BasicCollection,pObj)) != NULL ) |
| { |
| p->eForType = FOR_EACH_COLLECTION; |
| p->refEnd = pCollection; |
| p->nCurCollectionIndex = 0; |
| } |
| else if( (pUnoObj = PTR_CAST(SbUnoObject,pObj)) != NULL ) |
| { |
| // XEnumerationAccess? |
| Any aAny = pUnoObj->getUnoAny(); |
| Reference< XEnumerationAccess > xEnumerationAccess; |
| if( (aAny >>= xEnumerationAccess) ) |
| { |
| p->xEnumeration = xEnumerationAccess->createEnumeration(); |
| p->eForType = FOR_EACH_XENUMERATION; |
| } |
| else if ( isVBAEnabled() && pUnoObj->isNativeCOMObject() ) |
| { |
| uno::Reference< script::XInvocation > xInvocation; |
| if ( ( aAny >>= xInvocation ) && xInvocation.is() ) |
| { |
| try |
| { |
| p->xEnumeration = new ComEnumerationWrapper( xInvocation ); |
| p->eForType = FOR_EACH_XENUMERATION; |
| } |
| catch( uno::Exception& ) |
| {} |
| } |
| |
| if ( !p->xEnumeration.is() ) |
| bError_ = true; |
| } |
| else |
| { |
| bError_ = true; |
| } |
| } |
| else |
| { |
| bError_ = true; |
| } |
| |
| if( bError_ ) |
| { |
| Error( SbERR_CONVERSION ); |
| return; |
| } |
| |
| // Container variable |
| p->refVar = PopVar(); |
| nForLvl++; |
| } |
| |
| // Poppen des FOR-Stacks |
| |
| void SbiRuntime::PopFor() |
| { |
| if( pForStk ) |
| { |
| SbiForStack* p = pForStk; |
| pForStk = p->pNext; |
| delete p; |
| nForLvl--; |
| } |
| } |
| |
| // Entleeren des FOR-Stacks |
| |
| void SbiRuntime::ClearForStack() |
| { |
| while( pForStk ) |
| PopFor(); |
| } |
| |
| SbiForStack* SbiRuntime::FindForStackItemForCollection( class BasicCollection* pCollection ) |
| { |
| SbiForStack* pRet = NULL; |
| |
| SbiForStack* p = pForStk; |
| while( p ) |
| { |
| SbxVariable* pVar = p->refEnd.Is() ? (SbxVariable*)p->refEnd : NULL; |
| if( p->eForType == FOR_EACH_COLLECTION && pVar != NULL && |
| (pCollection = PTR_CAST(BasicCollection,pVar)) == pCollection ) |
| { |
| pRet = p; |
| break; |
| } |
| } |
| |
| return pRet; |
| } |
| |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // |
| // DLL-Aufrufe |
| // |
| ////////////////////////////////////////////////////////////////////////// |
| |
| void SbiRuntime::DllCall |
| ( const String& aFuncName, // Funktionsname |
| const String& aDLLName, // Name der DLL |
| SbxArray* pArgs, // Parameter (ab Index 1, kann NULL sein) |
| SbxDataType eResType, // Returnwert |
| sal_Bool bCDecl ) // sal_True: nach C-Konventionen |
| { |
| // No DllCall for "virtual" portal users |
| if( needSecurityRestrictions() ) |
| { |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| return; |
| } |
| |
| // MUSS NOCH IMPLEMENTIERT WERDEN |
| /* |
| String aMsg; |
| aMsg = "FUNC="; |
| aMsg += pFunc; |
| aMsg += " DLL="; |
| aMsg += pDLL; |
| MessBox( NULL, WB_OK, String( "DLL-CALL" ), aMsg ).Execute(); |
| Error( SbERR_NOT_IMPLEMENTED ); |
| */ |
| |
| SbxVariable* pRes = new SbxVariable( eResType ); |
| SbiDllMgr* pDllMgr = pInst->GetDllMgr(); |
| SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl ); |
| if( nErr ) |
| Error( nErr ); |
| PushVar( pRes ); |
| } |
| |
| sal_uInt16 SbiRuntime::GetImageFlag( sal_uInt16 n ) const |
| { |
| return pImg->GetFlag( n ); |
| } |
| |
| sal_uInt16 SbiRuntime::GetBase() |
| { |
| return pImg->GetBase(); |
| } |