1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: runtime.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #ifndef _SBRUNTIME_HXX
32 #define _SBRUNTIME_HXX
35 #include <basic/sbx.hxx>
40 // Define activates class UCBStream in iosys.cxx
44 #include <rtl/ustring.hxx>
45 #include <com/sun/star/uno/Sequence.hxx>
46 #include <osl/file.hxx>
47 #include <rtl/math.hxx>
48 #include <i18npool/lang.h>
51 #include <com/sun/star/lang/XComponent.hpp>
52 #include <com/sun/star/container/XEnumeration.hpp>
53 #include <unotools/localedatawrapper.hxx>
55 using namespace com::sun::star::uno
;
56 using namespace com::sun::star::lang
;
57 using namespace com::sun::star::container
;
60 // Define activates old file implementation
61 // (only in non UCB case)
62 // #define _OLD_FILE_IMPL
65 //#include <sal/types.h>
66 //#include <rtl/byteseq.hxx>
67 //#include <rtl/ustring>
70 namespace basicEncoder
73 // TODO: Use exported functionality (code is copied from deamons2/ucb)
77 static ::rtl::OUString
decodeUnoUrlParamValue(const rtl::OUString
& rSource
);
78 //static ::rtl::OUString encodeUnoUrlParamValue(const rtl::OUString & rSource);
79 //static ::rtl::ByteSequence decode(const ::rtl::OUString & string);
80 //static ::rtl::OUString encode(const ::rtl::ByteSequence & bytes);
88 class SbiInstance
; // aktiver StarBASIC-Prozess
89 class SbiRuntime
; // aktive StarBASIC-Prozedur-Instanz
91 struct SbiArgvStack
; // Argv stack element
92 struct SbiGosubStack
; // GOSUB stack element
93 class SbiImage
; // Code-Image
94 class SbiIoSystem
; // Dateisystem
95 class SbiDdeControl
; // DDE-Steuerung
96 class SbiDllMgr
; // Aufrufe in DLLs
97 class SvNumberFormatter
; // Zeit/Datumsfunktionen
104 FOR_EACH_XENUMERATION
107 struct SbiForStack
{ // for/next stack:
108 SbiForStack
* pNext
; // Chain
109 SbxVariableRef refVar
; // loop variable
110 SbxVariableRef refEnd
; // end expression / for each: Array/BasicCollection object
111 SbxVariableRef refInc
; // increment expression
115 INT32 nCurCollectionIndex
;
116 INT32
* pArrayCurIndices
;
117 INT32
* pArrayLowerBounds
;
118 INT32
* pArrayUpperBounds
;
119 Reference
< XEnumeration
> xEnumeration
;
122 : pArrayCurIndices( NULL
)
123 , pArrayLowerBounds( NULL
)
124 , pArrayUpperBounds( NULL
)
128 delete[] pArrayCurIndices
;
129 delete[] pArrayLowerBounds
;
130 delete[] pArrayUpperBounds
;
134 struct SbiGosubStack
{ // GOSUB-Stack:
135 SbiGosubStack
* pNext
; // Chain
136 const BYTE
* pCode
; // Return-Pointer
137 USHORT nStartForLvl
; // #118235: For Level in moment of gosub
140 #define MAXRECURSION 500 // max. 500 Rekursionen
142 #define Sb_ATTR_NORMAL 0x0000
143 #define Sb_ATTR_HIDDEN 0x0002
144 #define Sb_ATTR_SYSTEM 0x0004
145 #define Sb_ATTR_VOLUME 0x0008
146 #define Sb_ATTR_DIRECTORY 0x0010
147 #define Sb_ATTR_ARCHIVE 0x0020
157 #ifdef _OLD_FILE_IMPL
160 ::osl::Directory
* pDir
;
165 String sFullNameToBeChecked
;
169 Sequence
< ::rtl::OUString
> aDirSeq
;
170 #endif /* _USE_UNO */
176 // Die Instanz entspricht einem laufenden StarBASIC. Mehrere gleichzeitig
177 // laufende BASICs werden ueber verkettete Instanzen verwaltet. Hier liegen
178 // alle Daten, die nur leben, wenn BASIC auch lebt, wie z.B. das I/O-System.
180 typedef ::std::vector
182 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XComponent
>
189 friend class SbiRuntime
;
193 SbiIoSystem
* pIosys
; // Dateisystem
194 SbiDdeControl
* pDdeCtrl
; // DDE
195 SbiDllMgr
* pDllMgr
; // DLL-Calls (DECLARE)
197 SvNumberFormatter
* pNumberFormatter
;
198 LanguageType meFormatterLangType
;
199 DateFormat meFormatterDateFormat
;
200 sal_uInt32 nStdDateIdx
, nStdTimeIdx
, nStdDateTimeIdx
;
202 SbError nErr
; // aktueller Fehlercode
203 String aErrorMsg
; // letzte Error-Message fuer $ARG
204 USHORT nErl
; // aktuelle Fehlerzeile
205 BOOL bReschedule
; // Flag: TRUE = Reschedule in Hauptschleife
206 BOOL bCompatibility
; // Flag: TRUE = VBA runtime compatibility mode
208 ComponentVector_t ComponentVector
;
210 SbiRuntime
* pRun
; // Call-Stack
211 SbiInstance
* pNext
; // Instanzen-Chain
213 // #31460 Neues Konzept fuer StepInto/Over/Out,
214 // Erklaerung siehe runtime.cxx bei SbiInstance::CalcBreakCallLevel()
215 USHORT nCallLvl
; // Call-Level (wg. Rekursion)
216 USHORT nBreakCallLvl
; // Call-Level zum Anhalten
217 void CalcBreakCallLevel( USHORT nFlags
); // Gemaess Flags setzen
219 SbiInstance( StarBASIC
* );
222 void Error( SbError
); // trappable Error
223 void Error( SbError
, const String
& rMsg
); // trappable Error mit Message
224 void FatalError( SbError
); // non-trappable Error
225 void FatalError( SbError
, const String
& ); // non-trappable Error
226 void Abort(); // Abbruch mit aktuellem Fehlercode
229 SbError
GetErr() { return nErr
; }
230 String
GetErrorMsg() { return aErrorMsg
; }
231 xub_StrLen
GetErl() { return nErl
; }
232 void EnableReschedule( BOOL bEnable
) { bReschedule
= bEnable
; }
233 BOOL
IsReschedule( void ) { return bReschedule
; }
234 void EnableCompatibility( BOOL bEnable
) { bCompatibility
= bEnable
; }
235 BOOL
IsCompatibility( void ) { return bCompatibility
; }
237 ComponentVector_t
& getComponentVector( void ) { return ComponentVector
; }
239 SbMethod
* GetCaller( USHORT
);
240 SbModule
* GetActiveModule();
241 SbxArray
* GetLocals( SbMethod
* );
243 SbiIoSystem
* GetIoSystem() { return pIosys
; }
244 SbiDdeControl
* GetDdeControl() { return pDdeCtrl
; }
245 StarBASIC
* GetBasic( void ) { return pBasic
; }
246 SbiDllMgr
* GetDllMgr();
247 SbiRTLData
* GetRTLData() const { return (SbiRTLData
*)&aRTLData
; }
249 SvNumberFormatter
* GetNumberFormatter();
250 sal_uInt32
GetStdDateIdx() const { return nStdDateIdx
; }
251 sal_uInt32
GetStdTimeIdx() const { return nStdTimeIdx
; }
252 sal_uInt32
GetStdDateTimeIdx() const { return nStdDateTimeIdx
; }
254 // #39629# NumberFormatter auch statisch anbieten
255 static void PrepareNumberFormatter( SvNumberFormatter
*& rpNumberFormatter
,
256 sal_uInt32
&rnStdDateIdx
, sal_uInt32
&rnStdTimeIdx
, sal_uInt32
&rnStdDateTimeIdx
,
257 LanguageType
* peFormatterLangType
=NULL
, DateFormat
* peFormatterDateFormat
=NULL
);
260 SbiIoSystem
* SbGetIoSystem(); // das aktuelle I/O-System
263 // Verkettbare Items, um Referenzen temporaer zu halten
269 RefSaveItem() { pNext
= NULL
; }
273 // Eine Instanz dieser Klasse wird fuer jedes ausgefuehrte Unterprogramm
274 // aufgesetzt. Diese Instanz ist das Herz der BASIC-Maschine und enthaelt
279 typedef void( SbiRuntime::*pStep0
)();
280 typedef void( SbiRuntime::*pStep1
)( UINT32 nOp1
);
281 typedef void( SbiRuntime::*pStep2
)( UINT32 nOp1
, UINT32 nOp2
);
282 static pStep0 aStep0
[]; // Opcode-Tabelle Gruppe 0
283 static pStep1 aStep1
[]; // Opcode-Tabelle Gruppe 1
284 static pStep2 aStep2
[]; // Opcode-Tabelle Gruppe 2
286 StarBASIC
& rBasic
; // StarBASIC-Instanz
287 SbiInstance
* pInst
; // aktiver Thread
288 SbModule
* pMod
; // aktuelles Modul
289 SbMethod
* pMeth
; // Methoden-Instanz
290 SbiIoSystem
* pIosys
; // I/O-System
291 const SbiImage
* pImg
; // Code-Image
292 SbxArrayRef refExprStk
; // expression stack
293 SbxArrayRef refCaseStk
; // CASE expression stack
294 SbxArrayRef refRedimpArray
; // Array saved to use for REDIM PRESERVE
295 SbxVariableRef refRedim
; // Array saved to use for REDIM
296 SbxVariableRef xDummyVar
; // Ersatz fuer nicht gefundene Variablen
297 SbxVariable
* mpExtCaller
; // Caller ( external - e.g. button name, shape, range object etc. - only in vba mode )
298 SbiArgvStack
* pArgvStk
; // ARGV-Stack
299 SbiGosubStack
* pGosubStk
; // GOSUB stack
300 SbiForStack
* pForStk
; // FOR/NEXT-Stack
301 USHORT nExprLvl
; // Tiefe des Expr-Stacks
302 USHORT nGosubLvl
; // Zum Vermeiden von Tot-Rekursionen
303 USHORT nForLvl
; // #118235: Maintain for level
304 const BYTE
* pCode
; // aktueller Code-Pointer
305 const BYTE
* pStmnt
; // Beginn des lezten Statements
306 const BYTE
* pError
; // Adresse des aktuellen Error-Handlers
307 const BYTE
* pRestart
; // Restart-Adresse
308 const BYTE
* pErrCode
; // Restart-Adresse RESUME NEXT
309 const BYTE
* pErrStmnt
; // Restart-Adresse RESUMT 0
310 String aLibName
; // Lib-Name fuer Declare-Call
311 SbxArrayRef refParams
; // aktuelle Prozedur-Parameter
312 SbxArrayRef refLocals
; // lokale Variable
313 SbxArrayRef refArgv
; // aktueller Argv
314 // AB, 28.3.2000 #74254, Ein refSaveObj reicht nicht! Neu: pRefSaveList (s.u.)
315 //SbxVariableRef refSaveObj; // #56368 Bei StepElem Referenz sichern
316 short nArgc
; // aktueller Argc
317 BOOL bRun
; // TRUE: Programm ist aktiv
318 BOOL bError
; // TRUE: Fehler behandeln
319 BOOL bInError
; // TRUE: in einem Fehler-Handler
320 BOOL bBlocked
; // TRUE: blocked by next call level, #i48868
322 USHORT nFlags
; // Debugging-Flags
323 SbError nError
; // letzter Fehler
324 USHORT nOps
; // Opcode-Zaehler
325 sal_uInt32 m_nLastTime
;
327 RefSaveItem
* pRefSaveList
; // #74254 Temporaere Referenzen sichern
328 RefSaveItem
* pItemStoreList
; // Unbenutzte Items aufbewahren
329 void SaveRef( SbxVariable
* pVar
)
331 RefSaveItem
* pItem
= pItemStoreList
;
333 pItemStoreList
= pItem
->pNext
;
335 pItem
= new RefSaveItem();
336 pItem
->pNext
= pRefSaveList
;
338 pRefSaveList
= pItem
;
340 void ClearRefs( void )
342 while( pRefSaveList
)
344 RefSaveItem
* pToClearItem
= pRefSaveList
;
345 pRefSaveList
= pToClearItem
->pNext
;
346 pToClearItem
->xRef
= NULL
;
347 pToClearItem
->pNext
= pItemStoreList
;
348 pItemStoreList
= pToClearItem
;
352 SbxVariable
* FindElement
353 ( SbxObject
* pObj
, UINT32 nOp1
, UINT32 nOp2
, SbError
, BOOL bLocal
, BOOL bStatic
= FALSE
);
354 void SetupArgs( SbxVariable
*, UINT32
);
355 SbxVariable
* CheckArray( SbxVariable
* );
357 void PushVar( SbxVariable
* ); // Variable push
358 SbxVariableRef
PopVar(); // Variable pop
359 SbxVariable
* GetTOS( short=0 ); // Variable vom TOS holen
360 void TOSMakeTemp(); // TOS in temp. Variable wandeln
361 BOOL
ClearExprStack(); // Expr-Stack freigeben
363 void PushGosub( const BYTE
* ); // GOSUB-Element push
364 void PopGosub(); // GOSUB-Element pop
365 void ClearGosubStack(); // GOSUB-Stack freigeben
367 void PushArgv(); // Argv-Element push
368 void PopArgv(); // Argv-Element pop
369 void ClearArgvStack(); // Argv-Stack freigeben
371 void PushFor(); // For-Element push
372 void PushForEach(); // For-Each-Element push
373 void PopFor(); // For-Element pop
374 void ClearForStack(); // For-Stack freigeben
376 void StepArith( SbxOperator
); // arithmetische Verknuepfungen
377 void StepUnary( SbxOperator
); // unaere Verknuepfungen
378 void StepCompare( SbxOperator
);// Vergleiche
380 void SetParameters( SbxArray
* );// Parameter uebernehmen
382 // MUSS NOCH IMPLEMENTIERT WERDEN
383 void DllCall( const String
&, const String
&, SbxArray
*, SbxDataType
, BOOL
);
385 // #56204 DIM-Funktionalitaet in Hilfsmethode auslagern (step0.cxx)
386 void DimImpl( SbxVariableRef refVar
);
389 bool implIsClass( SbxObject
* pObj
, const String
& aClass
);
391 void StepSETCLASS_impl( UINT32 nOp1
, bool bHandleDflt
= false );
393 // Die nachfolgenden Routinen werden vom Single Stepper
394 // gerufen und implementieren die einzelnen Opcodes
395 void StepNOP(), StepEXP(), StepMUL(), StepDIV();
396 void StepMOD(), StepPLUS(), StepMINUS(), StepNEG();
397 void StepEQ(), StepNE(), StepLT(), StepGT();
398 void StepLE(), StepGE(), StepIDIV(), StepAND();
399 void StepOR(), StepXOR(), StepEQV(), StepIMP();
400 void StepNOT(), StepCAT(), StepLIKE(), StepIS();
401 void StepCLONE(), StepOLDBASED(), StepARGC();
402 void StepARGV(), StepINPUT(), StepLINPUT(), StepSTOP();
403 void StepGET(), StepSET(), StepVBASET(), StepPUT(), StepPUTC();
404 void StepSET_Impl( SbxVariableRef
& refVal
, SbxVariableRef
& refVar
, bool bDefaultHandling
= false );
405 void StepDIM(), StepREDIM(), StepREDIMP(), StepERASE();
406 void StepINITFOR(), StepNEXT(), StepERROR(), StepINITFOREACH();
407 void StepCASE(), StepENDCASE(), StepSTDERROR();
408 void StepNOERROR(), StepCHANNEL(), StepCHANNEL0(), StepPRINT();
409 void StepPRINTF(), StepWRITE(), StepRENAME(), StepPROMPT();
410 void StepRESTART(), StepEMPTY(), StepLEAVE();
411 void StepLSET(), StepRSET(), StepREDIMP_ERASE(), StepERASE_CLEAR();
412 void StepARRAYACCESS();
413 // Alle Opcodes mit einem Operanden
414 void StepLOADNC( UINT32
), StepLOADSC( UINT32
), StepLOADI( UINT32
);
415 void StepARGN( UINT32
), StepBASED( UINT32
), StepPAD( UINT32
);
416 void StepJUMP( UINT32
), StepJUMPT( UINT32
);
417 void StepJUMPF( UINT32
), StepONJUMP( UINT32
);
418 void StepGOSUB( UINT32
), StepRETURN( UINT32
);
419 void StepTESTFOR( UINT32
), StepCASETO( UINT32
), StepERRHDL( UINT32
);
420 void StepRESUME( UINT32
), StepSETCLASS( UINT32
), StepVBASETCLASS( UINT32
), StepTESTCLASS( UINT32
), StepLIB( UINT32
);
421 bool checkClass_Impl( const SbxVariableRef
& refVal
, const String
& aClass
, bool bRaiseErrors
);
422 void StepCLOSE( UINT32
), StepPRCHAR( UINT32
), StepARGTYP( UINT32
);
423 // Alle Opcodes mit zwei Operanden
424 void StepRTL( UINT32
, UINT32
), StepPUBLIC( UINT32
, UINT32
), StepPUBLIC_P( UINT32
, UINT32
);
425 void StepPUBLIC_Impl( UINT32
, UINT32
, bool bUsedForClassModule
);
426 void StepFIND_Impl( SbxObject
* pObj
, UINT32 nOp1
, UINT32 nOp2
, SbError
, BOOL bLocal
, BOOL bStatic
= FALSE
);
427 void StepFIND( UINT32
, UINT32
), StepELEM( UINT32
, UINT32
);
428 void StepGLOBAL( UINT32
, UINT32
), StepLOCAL( UINT32
, UINT32
);
429 void StepPARAM( UINT32
, UINT32
), StepCREATE( UINT32
, UINT32
);
430 void StepCALL( UINT32
, UINT32
), StepCALLC( UINT32
, UINT32
);
431 void StepCASEIS( UINT32
, UINT32
), StepSTMNT( UINT32
, UINT32
);
432 SbxVariable
* StepSTATIC_Impl( String
& aName
, SbxDataType
& t
);
433 void StepOPEN( UINT32
, UINT32
), StepSTATIC( UINT32
, UINT32
);
434 void StepTCREATE(UINT32
,UINT32
), StepDCREATE(UINT32
,UINT32
);
435 void StepGLOBAL_P( UINT32
, UINT32
),StepFIND_G( UINT32
, UINT32
);
436 void StepDCREATE_REDIMP(UINT32
,UINT32
), StepDCREATE_IMPL(UINT32
,UINT32
);
437 void StepFIND_CM( UINT32
, UINT32
);
438 void StepFIND_STATIC( UINT32
, UINT32
);
440 void SetVBAEnabled( bool bEnabled
);
441 USHORT
GetImageFlag( USHORT n
) const;
443 xub_StrLen nLine
,nCol1
,nCol2
; // aktuelle Zeile, Spaltenbereich
444 SbiRuntime
* pNext
; // Stack-Chain
446 SbiRuntime( SbModule
*, SbMethod
*, UINT32
);
448 void Error( SbError
); // Fehler setzen, falls != 0
449 void Error( SbError
, const String
& ); // Fehler setzen, falls != 0
450 void FatalError( SbError
); // Fehlerbehandlung=Standard, Fehler setzen
451 void FatalError( SbError
, const String
& ); // Fehlerbehandlung=Standard, Fehler setzen
453 BOOL
Step(); // Einzelschritt (ein Opcode)
454 void Stop() { bRun
= FALSE
; }
455 BOOL
IsRun() { return bRun
; }
456 void block( void ) { bBlocked
= TRUE
; }
457 void unblock( void ) { bBlocked
= FALSE
; }
458 SbMethod
* GetMethod() { return pMeth
; }
459 SbModule
* GetModule() { return pMod
; }
460 USHORT
GetDebugFlags() { return nFlags
; }
461 void SetDebugFlags( USHORT nFl
) { nFlags
= nFl
; }
462 SbMethod
* GetCaller();
463 SbxArray
* GetLocals();
464 SbxArray
* GetParams();
465 SbxVariable
* GetExternalCaller(){ return mpExtCaller
; }
467 SbxBase
* FindElementExtern( const String
& rName
);
468 static bool isVBAEnabled();
472 inline void checkArithmeticOverflow( double d
)
474 if( !::rtl::math::isFinite( d
) )
475 StarBASIC::Error( SbERR_MATH_OVERFLOW
);
478 inline void checkArithmeticOverflow( SbxVariable
* pVar
)
480 if( pVar
->GetType() == SbxDOUBLE
)
482 double d
= pVar
->GetDouble();
483 checkArithmeticOverflow( d
);
487 // Hilfsfunktion, um aktives Basic zu finden
488 StarBASIC
* GetCurrentBasic( StarBASIC
* pRTBasic
);
490 // Get information if security restrictions should be
491 // used (File IO based on UCB, no RTL function SHELL
492 // no DDE functionality, no DLLCALL) in basic because
493 // of portal "virtual" users (portal user != UNIX user)
494 // (Implemented in iosys.cxx)
495 BOOL
needSecurityRestrictions( void );
497 // Returns TRUE if UNO is available, otherwise the old
498 // file system implementation has to be used
499 // (Implemented in iosys.cxx)
502 // Converts possibly relative paths to absolute paths
503 // according to the setting done by ChDir/ChDrive
504 // (Implemented in methods.cxx)
505 String
getFullPath( const String
& aRelPath
);
507 // Sets (virtual) current path for UCB file access
508 void implChDir( const String
& aDir
);
510 // Sets (virtual) current drive for UCB file access
511 void implChDrive( const String
& aDrive
);
513 // Returns (virtual) current path for UCB file access
514 String
implGetCurDir( void );
516 // Implementation of StepRENAME with UCB
517 // (Implemented in methods.cxx, so step0.cxx
518 // has not to be infected with UNO)
519 void implStepRenameUCB( const String
& aSource
, const String
& aDest
);
521 //*** OSL file access ***
522 // #87427 OSL need File URLs, so map to getFullPath
523 inline String
getFullPathUNC( const String
& aRelPath
)
525 return getFullPath( aRelPath
);
527 void implStepRenameOSL( const String
& aSource
, const String
& aDest
);
528 bool IsBaseIndexOne();