xref: /trunk/main/basic/source/runtime/runtime.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_basic.hxx"
30*cdf0e10cSrcweir #include <tools/fsys.hxx>
31*cdf0e10cSrcweir #include <vcl/svapp.hxx>
32*cdf0e10cSrcweir #include <tools/wldcrd.hxx>
33*cdf0e10cSrcweir #include <svl/zforlist.hxx>
34*cdf0e10cSrcweir #include <unotools/syslocale.hxx>
35*cdf0e10cSrcweir #include "runtime.hxx"
36*cdf0e10cSrcweir #include "sbintern.hxx"
37*cdf0e10cSrcweir #include "opcodes.hxx"
38*cdf0e10cSrcweir #include "codegen.hxx"
39*cdf0e10cSrcweir #include "iosys.hxx"
40*cdf0e10cSrcweir #include "image.hxx"
41*cdf0e10cSrcweir #include "ddectrl.hxx"
42*cdf0e10cSrcweir #include "dllmgr.hxx"
43*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
44*cdf0e10cSrcweir #include <com/sun/star/container/XEnumerationAccess.hpp>
45*cdf0e10cSrcweir #include "sbunoobj.hxx"
46*cdf0e10cSrcweir #include "errobject.hxx"
47*cdf0e10cSrcweir #include "sbtrace.hxx"
48*cdf0e10cSrcweir #include "comenumwrapper.hxx"
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir using namespace ::com::sun::star;
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir bool SbiRuntime::isVBAEnabled()
53*cdf0e10cSrcweir {
54*cdf0e10cSrcweir     bool result = false;
55*cdf0e10cSrcweir     SbiInstance* pInst = pINST;
56*cdf0e10cSrcweir     if ( pInst && pINST->pRun )
57*cdf0e10cSrcweir         result = pInst->pRun->bVBAEnabled;
58*cdf0e10cSrcweir     return result;
59*cdf0e10cSrcweir }
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir // #91147 Global reschedule flag
62*cdf0e10cSrcweir static sal_Bool bStaticGlobalEnableReschedule = sal_True;
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir void StarBASIC::StaticEnableReschedule( sal_Bool bReschedule )
65*cdf0e10cSrcweir {
66*cdf0e10cSrcweir     bStaticGlobalEnableReschedule = bReschedule;
67*cdf0e10cSrcweir }
68*cdf0e10cSrcweir void StarBASIC::SetVBAEnabled( sal_Bool bEnabled )
69*cdf0e10cSrcweir {
70*cdf0e10cSrcweir     if ( bDocBasic )
71*cdf0e10cSrcweir     {
72*cdf0e10cSrcweir         bVBAEnabled = bEnabled;
73*cdf0e10cSrcweir     }
74*cdf0e10cSrcweir }
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir sal_Bool StarBASIC::isVBAEnabled()
77*cdf0e10cSrcweir {
78*cdf0e10cSrcweir     if ( bDocBasic )
79*cdf0e10cSrcweir     {
80*cdf0e10cSrcweir         if( SbiRuntime::isVBAEnabled() )
81*cdf0e10cSrcweir             return sal_True;
82*cdf0e10cSrcweir         return bVBAEnabled;
83*cdf0e10cSrcweir     }
84*cdf0e10cSrcweir     return sal_False;
85*cdf0e10cSrcweir }
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir struct SbiArgvStack {                   // Argv stack:
89*cdf0e10cSrcweir     SbiArgvStack*  pNext;               // Stack Chain
90*cdf0e10cSrcweir     SbxArrayRef    refArgv;             // Argv
91*cdf0e10cSrcweir     short nArgc;                        // Argc
92*cdf0e10cSrcweir };
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir SbiRuntime::pStep0 SbiRuntime::aStep0[] = { // Alle Opcodes ohne Operanden
95*cdf0e10cSrcweir     &SbiRuntime::StepNOP,
96*cdf0e10cSrcweir     &SbiRuntime::StepEXP,
97*cdf0e10cSrcweir     &SbiRuntime::StepMUL,
98*cdf0e10cSrcweir     &SbiRuntime::StepDIV,
99*cdf0e10cSrcweir     &SbiRuntime::StepMOD,
100*cdf0e10cSrcweir     &SbiRuntime::StepPLUS,
101*cdf0e10cSrcweir     &SbiRuntime::StepMINUS,
102*cdf0e10cSrcweir     &SbiRuntime::StepNEG,
103*cdf0e10cSrcweir     &SbiRuntime::StepEQ,
104*cdf0e10cSrcweir     &SbiRuntime::StepNE,
105*cdf0e10cSrcweir     &SbiRuntime::StepLT,
106*cdf0e10cSrcweir     &SbiRuntime::StepGT,
107*cdf0e10cSrcweir     &SbiRuntime::StepLE,
108*cdf0e10cSrcweir     &SbiRuntime::StepGE,
109*cdf0e10cSrcweir     &SbiRuntime::StepIDIV,
110*cdf0e10cSrcweir     &SbiRuntime::StepAND,
111*cdf0e10cSrcweir     &SbiRuntime::StepOR,
112*cdf0e10cSrcweir     &SbiRuntime::StepXOR,
113*cdf0e10cSrcweir     &SbiRuntime::StepEQV,
114*cdf0e10cSrcweir     &SbiRuntime::StepIMP,
115*cdf0e10cSrcweir     &SbiRuntime::StepNOT,
116*cdf0e10cSrcweir     &SbiRuntime::StepCAT,
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir     &SbiRuntime::StepLIKE,
119*cdf0e10cSrcweir     &SbiRuntime::StepIS,
120*cdf0e10cSrcweir     // Laden/speichern
121*cdf0e10cSrcweir     &SbiRuntime::StepARGC,      // neuen Argv einrichten
122*cdf0e10cSrcweir     &SbiRuntime::StepARGV,      // TOS ==> aktueller Argv
123*cdf0e10cSrcweir     &SbiRuntime::StepINPUT,     // Input ==> TOS
124*cdf0e10cSrcweir     &SbiRuntime::StepLINPUT,        // Line Input ==> TOS
125*cdf0e10cSrcweir     &SbiRuntime::StepGET,        // TOS anfassen
126*cdf0e10cSrcweir     &SbiRuntime::StepSET,        // Speichern Objekt TOS ==> TOS-1
127*cdf0e10cSrcweir     &SbiRuntime::StepPUT,       // TOS ==> TOS-1
128*cdf0e10cSrcweir     &SbiRuntime::StepPUTC,      // TOS ==> TOS-1, dann ReadOnly
129*cdf0e10cSrcweir     &SbiRuntime::StepDIM,       // DIM
130*cdf0e10cSrcweir     &SbiRuntime::StepREDIM,         // REDIM
131*cdf0e10cSrcweir     &SbiRuntime::StepREDIMP,        // REDIM PRESERVE
132*cdf0e10cSrcweir     &SbiRuntime::StepERASE,         // TOS loeschen
133*cdf0e10cSrcweir     // Verzweigen
134*cdf0e10cSrcweir     &SbiRuntime::StepSTOP,          // Programmende
135*cdf0e10cSrcweir     &SbiRuntime::StepINITFOR,   // FOR-Variable initialisieren
136*cdf0e10cSrcweir     &SbiRuntime::StepNEXT,      // FOR-Variable inkrementieren
137*cdf0e10cSrcweir     &SbiRuntime::StepCASE,      // Anfang CASE
138*cdf0e10cSrcweir     &SbiRuntime::StepENDCASE,   // Ende CASE
139*cdf0e10cSrcweir     &SbiRuntime::StepSTDERROR,      // Standard-Fehlerbehandlung
140*cdf0e10cSrcweir     &SbiRuntime::StepNOERROR,   // keine Fehlerbehandlung
141*cdf0e10cSrcweir     &SbiRuntime::StepLEAVE,     // UP verlassen
142*cdf0e10cSrcweir     // E/A
143*cdf0e10cSrcweir     &SbiRuntime::StepCHANNEL,   // TOS = Kanalnummer
144*cdf0e10cSrcweir     &SbiRuntime::StepPRINT,     // print TOS
145*cdf0e10cSrcweir     &SbiRuntime::StepPRINTF,        // print TOS in field
146*cdf0e10cSrcweir     &SbiRuntime::StepWRITE,     // write TOS
147*cdf0e10cSrcweir     &SbiRuntime::StepRENAME,        // Rename Tos+1 to Tos
148*cdf0e10cSrcweir     &SbiRuntime::StepPROMPT,        // Input Prompt aus TOS definieren
149*cdf0e10cSrcweir     &SbiRuntime::StepRESTART,   // Set restart point
150*cdf0e10cSrcweir     &SbiRuntime::StepCHANNEL0,  // E/A-Kanal 0 einstellen
151*cdf0e10cSrcweir     &SbiRuntime::StepEMPTY,     // Leeren Ausdruck auf Stack
152*cdf0e10cSrcweir     &SbiRuntime::StepERROR,     // TOS = Fehlercode
153*cdf0e10cSrcweir     &SbiRuntime::StepLSET,      // Speichern Objekt TOS ==> TOS-1
154*cdf0e10cSrcweir     &SbiRuntime::StepRSET,      // Speichern Objekt TOS ==> TOS-1
155*cdf0e10cSrcweir     &SbiRuntime::StepREDIMP_ERASE,// Copy array object for REDIMP
156*cdf0e10cSrcweir     &SbiRuntime::StepINITFOREACH,// Init for each loop
157*cdf0e10cSrcweir     &SbiRuntime::StepVBASET,// vba-like set statement
158*cdf0e10cSrcweir     &SbiRuntime::StepERASE_CLEAR,// vba-like set statement
159*cdf0e10cSrcweir     &SbiRuntime::StepARRAYACCESS,// access TOS as array
160*cdf0e10cSrcweir     &SbiRuntime::StepBYVAL,     // access TOS as array
161*cdf0e10cSrcweir };
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir SbiRuntime::pStep1 SbiRuntime::aStep1[] = { // Alle Opcodes mit einem Operanden
164*cdf0e10cSrcweir     &SbiRuntime::StepLOADNC,        // Laden einer numerischen Konstanten (+ID)
165*cdf0e10cSrcweir     &SbiRuntime::StepLOADSC,        // Laden einer Stringkonstanten (+ID)
166*cdf0e10cSrcweir     &SbiRuntime::StepLOADI,     // Immediate Load (+Wert)
167*cdf0e10cSrcweir     &SbiRuntime::StepARGN,      // Speichern eines named Args in Argv (+StringID)
168*cdf0e10cSrcweir     &SbiRuntime::StepPAD,       // String auf feste Laenge bringen (+Laenge)
169*cdf0e10cSrcweir     // Verzweigungen
170*cdf0e10cSrcweir     &SbiRuntime::StepJUMP,      // Sprung (+Target)
171*cdf0e10cSrcweir     &SbiRuntime::StepJUMPT,     // TOS auswerten), bedingter Sprung (+Target)
172*cdf0e10cSrcweir     &SbiRuntime::StepJUMPF,     // TOS auswerten), bedingter Sprung (+Target)
173*cdf0e10cSrcweir     &SbiRuntime::StepONJUMP,        // TOS auswerten), Sprung in JUMP-Tabelle (+MaxVal)
174*cdf0e10cSrcweir     &SbiRuntime::StepGOSUB,     // UP-Aufruf (+Target)
175*cdf0e10cSrcweir     &SbiRuntime::StepRETURN,        // UP-Return (+0 oder Target)
176*cdf0e10cSrcweir     &SbiRuntime::StepTESTFOR,   // FOR-Variable testen), inkrementieren (+Endlabel)
177*cdf0e10cSrcweir     &SbiRuntime::StepCASETO,        // Tos+1 <= Case <= Tos), 2xremove (+Target)
178*cdf0e10cSrcweir     &SbiRuntime::StepERRHDL,        // Fehler-Handler (+Offset)
179*cdf0e10cSrcweir     &SbiRuntime::StepRESUME,        // Resume nach Fehlern (+0 or 1 or Label)
180*cdf0e10cSrcweir     // E/A
181*cdf0e10cSrcweir     &SbiRuntime::StepCLOSE,     // (+Kanal/0)
182*cdf0e10cSrcweir     &SbiRuntime::StepPRCHAR,        // (+char)
183*cdf0e10cSrcweir     // Verwaltung
184*cdf0e10cSrcweir     &SbiRuntime::StepSETCLASS,  // Set + Klassennamen testen (+StringId)
185*cdf0e10cSrcweir     &SbiRuntime::StepTESTCLASS, // Check TOS class (+StringId)
186*cdf0e10cSrcweir     &SbiRuntime::StepLIB,       // Lib fuer Declare-Call (+StringId)
187*cdf0e10cSrcweir     &SbiRuntime::StepBASED,     // TOS wird um BASE erhoeht, BASE davor gepusht
188*cdf0e10cSrcweir     &SbiRuntime::StepARGTYP,        // Letzten Parameter in Argv konvertieren (+Typ)
189*cdf0e10cSrcweir     &SbiRuntime::StepVBASETCLASS,// vba-like set statement
190*cdf0e10cSrcweir };
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir SbiRuntime::pStep2 SbiRuntime::aStep2[] = {// Alle Opcodes mit zwei Operanden
193*cdf0e10cSrcweir     &SbiRuntime::StepRTL,       // Laden aus RTL (+StringID+Typ)
194*cdf0e10cSrcweir     &SbiRuntime::StepFIND,      // Laden (+StringID+Typ)
195*cdf0e10cSrcweir     &SbiRuntime::StepELEM,          // Laden Element (+StringID+Typ)
196*cdf0e10cSrcweir     &SbiRuntime::StepPARAM,     // Parameter (+Offset+Typ)
197*cdf0e10cSrcweir     // Verzweigen
198*cdf0e10cSrcweir     &SbiRuntime::StepCALL,      // Declare-Call (+StringID+Typ)
199*cdf0e10cSrcweir     &SbiRuntime::StepCALLC,     // CDecl-Declare-Call (+StringID+Typ)
200*cdf0e10cSrcweir     &SbiRuntime::StepCASEIS,        // Case-Test (+Test-Opcode+False-Target)
201*cdf0e10cSrcweir     // Verwaltung
202*cdf0e10cSrcweir     &SbiRuntime::StepSTMNT,         // Beginn eines Statements (+Line+Col)
203*cdf0e10cSrcweir     // E/A
204*cdf0e10cSrcweir     &SbiRuntime::StepOPEN,          // (+SvStreamFlags+Flags)
205*cdf0e10cSrcweir     // Objekte
206*cdf0e10cSrcweir     &SbiRuntime::StepLOCAL,     // Lokale Variable definieren (+StringId+Typ)
207*cdf0e10cSrcweir     &SbiRuntime::StepPUBLIC,        // Modulglobale Variable (+StringID+Typ)
208*cdf0e10cSrcweir     &SbiRuntime::StepGLOBAL,        // Globale Variable definieren (+StringID+Typ)
209*cdf0e10cSrcweir     &SbiRuntime::StepCREATE,        // Objekt kreieren (+StringId+StringId)
210*cdf0e10cSrcweir     &SbiRuntime::StepSTATIC,     // Statische Variable (+StringId+StringId)
211*cdf0e10cSrcweir     &SbiRuntime::StepTCREATE,    // User Defined Objekte (+StringId+StringId)
212*cdf0e10cSrcweir     &SbiRuntime::StepDCREATE,    // Objekt-Array kreieren (+StringID+StringID)
213*cdf0e10cSrcweir     &SbiRuntime::StepGLOBAL_P,   // Globale Variable definieren, die beim Neustart
214*cdf0e10cSrcweir                                         // von Basic nicht ueberschrieben wird (+StringID+Typ)
215*cdf0e10cSrcweir     &SbiRuntime::StepFIND_G,        // Sucht globale Variable mit Spezialbehandlung wegen _GLOBAL_P
216*cdf0e10cSrcweir     &SbiRuntime::StepDCREATE_REDIMP, // Objekt-Array redimensionieren (+StringID+StringID)
217*cdf0e10cSrcweir     &SbiRuntime::StepFIND_CM,    // Search inside a class module (CM) to enable global search in time
218*cdf0e10cSrcweir     &SbiRuntime::StepPUBLIC_P,    // Search inside a class module (CM) to enable global search in time
219*cdf0e10cSrcweir     &SbiRuntime::StepFIND_STATIC,    // Search inside a class module (CM) to enable global search in time
220*cdf0e10cSrcweir };
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
224*cdf0e10cSrcweir //                              SbiRTLData                              //
225*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir SbiRTLData::SbiRTLData()
228*cdf0e10cSrcweir {
229*cdf0e10cSrcweir     pDir        = 0;
230*cdf0e10cSrcweir     nDirFlags   = 0;
231*cdf0e10cSrcweir     nCurDirPos  = 0;
232*cdf0e10cSrcweir     pWildCard   = NULL;
233*cdf0e10cSrcweir }
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir SbiRTLData::~SbiRTLData()
236*cdf0e10cSrcweir {
237*cdf0e10cSrcweir     delete pDir;
238*cdf0e10cSrcweir     pDir = 0;
239*cdf0e10cSrcweir     delete pWildCard;
240*cdf0e10cSrcweir }
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
243*cdf0e10cSrcweir //                              SbiInstance                             //
244*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir // 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
247*cdf0e10cSrcweir // Die Entscheidung, ob StepPoint aufgerufen werden soll, wird anhand des
248*cdf0e10cSrcweir // CallLevels getroffen. Angehalten wird, wenn der aktuelle CallLevel <=
249*cdf0e10cSrcweir // nBreakCallLvl ist. Der aktuelle CallLevel kann niemals kleiner als 1
250*cdf0e10cSrcweir // sein, da er beim Aufruf einer Methode (auch main) inkrementiert wird.
251*cdf0e10cSrcweir // Daher bedeutet ein BreakCallLvl von 0, dass das Programm gar nicht
252*cdf0e10cSrcweir // angehalten wird.
253*cdf0e10cSrcweir // (siehe auch step2.cxx, SbiRuntime::StepSTMNT() )
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir // Hilfsfunktion, um den BreakCallLevel gemaess der der Debug-Flags zu ermitteln
256*cdf0e10cSrcweir void SbiInstance::CalcBreakCallLevel( sal_uInt16 nFlags )
257*cdf0e10cSrcweir {
258*cdf0e10cSrcweir     // Break-Flag wegfiltern
259*cdf0e10cSrcweir     nFlags &= ~((sal_uInt16)SbDEBUG_BREAK);
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir     sal_uInt16 nRet;
262*cdf0e10cSrcweir     switch( nFlags )
263*cdf0e10cSrcweir     {
264*cdf0e10cSrcweir         case SbDEBUG_STEPINTO:
265*cdf0e10cSrcweir             nRet = nCallLvl + 1;    // CallLevel+1 wird auch angehalten
266*cdf0e10cSrcweir             break;
267*cdf0e10cSrcweir         case SbDEBUG_STEPOVER | SbDEBUG_STEPINTO:
268*cdf0e10cSrcweir             nRet = nCallLvl;        // Aktueller CallLevel wird angehalten
269*cdf0e10cSrcweir             break;
270*cdf0e10cSrcweir         case SbDEBUG_STEPOUT:
271*cdf0e10cSrcweir             nRet = nCallLvl - 1;    // Kleinerer CallLevel wird angehalten
272*cdf0e10cSrcweir             break;
273*cdf0e10cSrcweir         case SbDEBUG_CONTINUE:
274*cdf0e10cSrcweir         // Basic-IDE liefert 0 statt SbDEBUG_CONTINUE, also auch default=continue
275*cdf0e10cSrcweir         default:
276*cdf0e10cSrcweir             nRet = 0;               // CallLevel ist immer >0 -> kein StepPoint
277*cdf0e10cSrcweir     }
278*cdf0e10cSrcweir     nBreakCallLvl = nRet;           // Ergebnis uebernehmen
279*cdf0e10cSrcweir }
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir SbiInstance::SbiInstance( StarBASIC* p )
282*cdf0e10cSrcweir {
283*cdf0e10cSrcweir     pBasic   = p;
284*cdf0e10cSrcweir     pNext    = NULL;
285*cdf0e10cSrcweir     pRun     = NULL;
286*cdf0e10cSrcweir     pIosys   = new SbiIoSystem;
287*cdf0e10cSrcweir     pDdeCtrl = new SbiDdeControl;
288*cdf0e10cSrcweir     pDllMgr  = 0; // on demand
289*cdf0e10cSrcweir     pNumberFormatter = 0; // on demand
290*cdf0e10cSrcweir     nCallLvl = 0;
291*cdf0e10cSrcweir     nBreakCallLvl = 0;
292*cdf0e10cSrcweir     nErr     =
293*cdf0e10cSrcweir     nErl     = 0;
294*cdf0e10cSrcweir     bReschedule = sal_True;
295*cdf0e10cSrcweir     bCompatibility = sal_False;
296*cdf0e10cSrcweir }
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir SbiInstance::~SbiInstance()
299*cdf0e10cSrcweir {
300*cdf0e10cSrcweir     while( pRun )
301*cdf0e10cSrcweir     {
302*cdf0e10cSrcweir         SbiRuntime* p = pRun->pNext;
303*cdf0e10cSrcweir         delete pRun;
304*cdf0e10cSrcweir         pRun = p;
305*cdf0e10cSrcweir     }
306*cdf0e10cSrcweir     delete pIosys;
307*cdf0e10cSrcweir     delete pDdeCtrl;
308*cdf0e10cSrcweir     delete pDllMgr;
309*cdf0e10cSrcweir     delete pNumberFormatter;
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir     try
312*cdf0e10cSrcweir     {
313*cdf0e10cSrcweir         int nSize = ComponentVector.size();
314*cdf0e10cSrcweir         if( nSize )
315*cdf0e10cSrcweir         {
316*cdf0e10cSrcweir             for( int i = nSize - 1 ; i >= 0 ; --i )
317*cdf0e10cSrcweir             {
318*cdf0e10cSrcweir                 Reference< XComponent > xDlgComponent = ComponentVector[i];
319*cdf0e10cSrcweir                 if( xDlgComponent.is() )
320*cdf0e10cSrcweir                     xDlgComponent->dispose();
321*cdf0e10cSrcweir             }
322*cdf0e10cSrcweir         }
323*cdf0e10cSrcweir     }
324*cdf0e10cSrcweir     catch( const Exception& )
325*cdf0e10cSrcweir     {
326*cdf0e10cSrcweir         DBG_ERROR( "SbiInstance::~SbiInstance: caught an exception while disposing the components!" );
327*cdf0e10cSrcweir     }
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir     ComponentVector.clear();
330*cdf0e10cSrcweir }
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir SbiDllMgr* SbiInstance::GetDllMgr()
333*cdf0e10cSrcweir {
334*cdf0e10cSrcweir     if( !pDllMgr )
335*cdf0e10cSrcweir         pDllMgr = new SbiDllMgr;
336*cdf0e10cSrcweir     return pDllMgr;
337*cdf0e10cSrcweir }
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir // #39629 NumberFormatter jetzt ueber statische Methode anlegen
340*cdf0e10cSrcweir SvNumberFormatter* SbiInstance::GetNumberFormatter()
341*cdf0e10cSrcweir {
342*cdf0e10cSrcweir     LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
343*cdf0e10cSrcweir     SvtSysLocale aSysLocale;
344*cdf0e10cSrcweir     DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
345*cdf0e10cSrcweir     if( pNumberFormatter )
346*cdf0e10cSrcweir     {
347*cdf0e10cSrcweir         if( eLangType != meFormatterLangType ||
348*cdf0e10cSrcweir             eDate != meFormatterDateFormat )
349*cdf0e10cSrcweir         {
350*cdf0e10cSrcweir             delete pNumberFormatter;
351*cdf0e10cSrcweir             pNumberFormatter = NULL;
352*cdf0e10cSrcweir         }
353*cdf0e10cSrcweir     }
354*cdf0e10cSrcweir     meFormatterLangType = eLangType;
355*cdf0e10cSrcweir     meFormatterDateFormat = eDate;
356*cdf0e10cSrcweir     if( !pNumberFormatter )
357*cdf0e10cSrcweir         PrepareNumberFormatter( pNumberFormatter, nStdDateIdx, nStdTimeIdx, nStdDateTimeIdx,
358*cdf0e10cSrcweir         &meFormatterLangType, &meFormatterDateFormat );
359*cdf0e10cSrcweir     return pNumberFormatter;
360*cdf0e10cSrcweir }
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir // #39629 NumberFormatter auch statisch anbieten
363*cdf0e10cSrcweir void SbiInstance::PrepareNumberFormatter( SvNumberFormatter*& rpNumberFormatter,
364*cdf0e10cSrcweir     sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx,
365*cdf0e10cSrcweir     LanguageType* peFormatterLangType, DateFormat* peFormatterDateFormat )
366*cdf0e10cSrcweir {
367*cdf0e10cSrcweir     com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
368*cdf0e10cSrcweir         xFactory = comphelper::getProcessServiceFactory();
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir     LanguageType eLangType;
371*cdf0e10cSrcweir     if( peFormatterLangType )
372*cdf0e10cSrcweir         eLangType = *peFormatterLangType;
373*cdf0e10cSrcweir     else
374*cdf0e10cSrcweir         eLangType = GetpApp()->GetSettings().GetLanguage();
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir     DateFormat eDate;
377*cdf0e10cSrcweir     if( peFormatterDateFormat )
378*cdf0e10cSrcweir         eDate = *peFormatterDateFormat;
379*cdf0e10cSrcweir     else
380*cdf0e10cSrcweir     {
381*cdf0e10cSrcweir         SvtSysLocale aSysLocale;
382*cdf0e10cSrcweir         eDate = aSysLocale.GetLocaleData().getDateFormat();
383*cdf0e10cSrcweir     }
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir     rpNumberFormatter = new SvNumberFormatter( xFactory, eLangType );
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir     xub_StrLen nCheckPos = 0; short nType;
388*cdf0e10cSrcweir     rnStdTimeIdx = rpNumberFormatter->GetStandardFormat( NUMBERFORMAT_TIME, eLangType );
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir     // Standard-Vorlagen des Formatters haben nur zweistellige
391*cdf0e10cSrcweir     // Jahreszahl. Deshalb eigenes Format registrieren
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir     // HACK, da der Numberformatter in PutandConvertEntry die Platzhalter
394*cdf0e10cSrcweir     // fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung
395*cdf0e10cSrcweir     // austauscht. Problem: Print Year(Date) unter engl. BS
396*cdf0e10cSrcweir     // siehe auch svtools\source\sbx\sbxdate.cxx
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir     String aDateStr;
399*cdf0e10cSrcweir     switch( eDate )
400*cdf0e10cSrcweir     {
401*cdf0e10cSrcweir         case MDY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") ); break;
402*cdf0e10cSrcweir         case DMY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("TT.MM.JJJJ") ); break;
403*cdf0e10cSrcweir         case YMD: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("JJJJ.MM.TT") ); break;
404*cdf0e10cSrcweir         default:  aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") );
405*cdf0e10cSrcweir     }
406*cdf0e10cSrcweir     String aStr( aDateStr );
407*cdf0e10cSrcweir     rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
408*cdf0e10cSrcweir         rnStdDateIdx, LANGUAGE_GERMAN, eLangType );
409*cdf0e10cSrcweir     nCheckPos = 0;
410*cdf0e10cSrcweir     String aStrHHMMSS( RTL_CONSTASCII_USTRINGPARAM(" HH:MM:SS") );
411*cdf0e10cSrcweir     aStr = aDateStr;
412*cdf0e10cSrcweir     aStr += aStrHHMMSS;
413*cdf0e10cSrcweir     rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
414*cdf0e10cSrcweir         rnStdDateTimeIdx, LANGUAGE_GERMAN, eLangType );
415*cdf0e10cSrcweir }
416*cdf0e10cSrcweir 
417*cdf0e10cSrcweir 
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir // Engine laufenlassen. Falls Flags == SbDEBUG_CONTINUE, Flags uebernehmen
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir void SbiInstance::Stop()
422*cdf0e10cSrcweir {
423*cdf0e10cSrcweir     for( SbiRuntime* p = pRun; p; p = p->pNext )
424*cdf0e10cSrcweir         p->Stop();
425*cdf0e10cSrcweir }
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir // Allows Basic IDE to set watch mode to suppress errors
428*cdf0e10cSrcweir static bool bWatchMode = false;
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir void setBasicWatchMode( bool bOn )
431*cdf0e10cSrcweir {
432*cdf0e10cSrcweir     bWatchMode = bOn;
433*cdf0e10cSrcweir }
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir void SbiInstance::Error( SbError n )
436*cdf0e10cSrcweir {
437*cdf0e10cSrcweir     Error( n, String() );
438*cdf0e10cSrcweir }
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir void SbiInstance::Error( SbError n, const String& rMsg )
441*cdf0e10cSrcweir {
442*cdf0e10cSrcweir     if( !bWatchMode )
443*cdf0e10cSrcweir     {
444*cdf0e10cSrcweir         aErrorMsg = rMsg;
445*cdf0e10cSrcweir         pRun->Error( n );
446*cdf0e10cSrcweir     }
447*cdf0e10cSrcweir }
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir void SbiInstance::ErrorVB( sal_Int32 nVBNumber, const String& rMsg )
450*cdf0e10cSrcweir {
451*cdf0e10cSrcweir     if( !bWatchMode )
452*cdf0e10cSrcweir     {
453*cdf0e10cSrcweir         SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
454*cdf0e10cSrcweir         if ( !n )
455*cdf0e10cSrcweir             n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir         aErrorMsg = rMsg;
458*cdf0e10cSrcweir         SbiRuntime::translateErrorToVba( n, aErrorMsg );
459*cdf0e10cSrcweir 
460*cdf0e10cSrcweir         bool bVBATranslationAlreadyDone = true;
461*cdf0e10cSrcweir         pRun->Error( SbERR_BASIC_COMPAT, bVBATranslationAlreadyDone );
462*cdf0e10cSrcweir     }
463*cdf0e10cSrcweir }
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir void SbiInstance::setErrorVB( sal_Int32 nVBNumber, const String& rMsg )
466*cdf0e10cSrcweir {
467*cdf0e10cSrcweir     SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
468*cdf0e10cSrcweir     if( !n )
469*cdf0e10cSrcweir         n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir     aErrorMsg = rMsg;
472*cdf0e10cSrcweir     SbiRuntime::translateErrorToVba( n, aErrorMsg );
473*cdf0e10cSrcweir 
474*cdf0e10cSrcweir     nErr = n;
475*cdf0e10cSrcweir }
476*cdf0e10cSrcweir 
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir void SbiInstance::FatalError( SbError n )
479*cdf0e10cSrcweir {
480*cdf0e10cSrcweir     pRun->FatalError( n );
481*cdf0e10cSrcweir }
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir void SbiInstance::FatalError( SbError _errCode, const String& _details )
484*cdf0e10cSrcweir {
485*cdf0e10cSrcweir     pRun->FatalError( _errCode, _details );
486*cdf0e10cSrcweir }
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir void SbiInstance::Abort()
489*cdf0e10cSrcweir {
490*cdf0e10cSrcweir     // Basic suchen, in dem der Fehler auftrat
491*cdf0e10cSrcweir     StarBASIC* pErrBasic = GetCurrentBasic( pBasic );
492*cdf0e10cSrcweir     pErrBasic->RTError( nErr, aErrorMsg, pRun->nLine, pRun->nCol1, pRun->nCol2 );
493*cdf0e10cSrcweir     pBasic->Stop();
494*cdf0e10cSrcweir }
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir // Hilfsfunktion, um aktives Basic zu finden, kann ungleich pRTBasic sein
497*cdf0e10cSrcweir StarBASIC* GetCurrentBasic( StarBASIC* pRTBasic )
498*cdf0e10cSrcweir {
499*cdf0e10cSrcweir     StarBASIC* pCurBasic = pRTBasic;
500*cdf0e10cSrcweir     SbModule* pActiveModule = pRTBasic->GetActiveModule();
501*cdf0e10cSrcweir     if( pActiveModule )
502*cdf0e10cSrcweir     {
503*cdf0e10cSrcweir         SbxObject* pParent = pActiveModule->GetParent();
504*cdf0e10cSrcweir         if( pParent && pParent->ISA(StarBASIC) )
505*cdf0e10cSrcweir             pCurBasic = (StarBASIC*)pParent;
506*cdf0e10cSrcweir     }
507*cdf0e10cSrcweir     return pCurBasic;
508*cdf0e10cSrcweir }
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir SbModule* SbiInstance::GetActiveModule()
511*cdf0e10cSrcweir {
512*cdf0e10cSrcweir     if( pRun )
513*cdf0e10cSrcweir         return pRun->GetModule();
514*cdf0e10cSrcweir     else
515*cdf0e10cSrcweir         return NULL;
516*cdf0e10cSrcweir }
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir SbMethod* SbiInstance::GetCaller( sal_uInt16 nLevel )
519*cdf0e10cSrcweir {
520*cdf0e10cSrcweir     SbiRuntime* p = pRun;
521*cdf0e10cSrcweir     while( nLevel-- && p )
522*cdf0e10cSrcweir         p = p->pNext;
523*cdf0e10cSrcweir     if( p )
524*cdf0e10cSrcweir         return p->GetCaller();
525*cdf0e10cSrcweir     else
526*cdf0e10cSrcweir         return NULL;
527*cdf0e10cSrcweir }
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir SbxArray* SbiInstance::GetLocals( SbMethod* pMeth )
530*cdf0e10cSrcweir {
531*cdf0e10cSrcweir     SbiRuntime* p = pRun;
532*cdf0e10cSrcweir     while( p && p->GetMethod() != pMeth )
533*cdf0e10cSrcweir         p = p->pNext;
534*cdf0e10cSrcweir     if( p )
535*cdf0e10cSrcweir         return p->GetLocals();
536*cdf0e10cSrcweir     else
537*cdf0e10cSrcweir         return NULL;
538*cdf0e10cSrcweir }
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
541*cdf0e10cSrcweir //                              SbiInstance                             //
542*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir // Achtung: pMeth kann auch NULL sein (beim Aufruf des Init-Codes)
545*cdf0e10cSrcweir 
546*cdf0e10cSrcweir SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, sal_uInt32 nStart )
547*cdf0e10cSrcweir          : rBasic( *(StarBASIC*)pm->pParent ), pInst( pINST ),
548*cdf0e10cSrcweir            pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), m_nLastTime(0)
549*cdf0e10cSrcweir {
550*cdf0e10cSrcweir     nFlags    = pe ? pe->GetDebugFlags() : 0;
551*cdf0e10cSrcweir     pIosys    = pInst->pIosys;
552*cdf0e10cSrcweir     pArgvStk  = NULL;
553*cdf0e10cSrcweir     pGosubStk = NULL;
554*cdf0e10cSrcweir     pForStk   = NULL;
555*cdf0e10cSrcweir     pError    = NULL;
556*cdf0e10cSrcweir     pErrCode  =
557*cdf0e10cSrcweir     pErrStmnt =
558*cdf0e10cSrcweir     pRestart  = NULL;
559*cdf0e10cSrcweir     pNext     = NULL;
560*cdf0e10cSrcweir     pCode     =
561*cdf0e10cSrcweir     pStmnt    = (const sal_uInt8* ) pImg->GetCode() + nStart;
562*cdf0e10cSrcweir     bRun      =
563*cdf0e10cSrcweir     bError    = sal_True;
564*cdf0e10cSrcweir     bInError  = sal_False;
565*cdf0e10cSrcweir     bBlocked  = sal_False;
566*cdf0e10cSrcweir     nLine     = 0;
567*cdf0e10cSrcweir     nCol1     = 0;
568*cdf0e10cSrcweir     nCol2     = 0;
569*cdf0e10cSrcweir     nExprLvl  = 0;
570*cdf0e10cSrcweir     nArgc     = 0;
571*cdf0e10cSrcweir     nError    = 0;
572*cdf0e10cSrcweir     nGosubLvl = 0;
573*cdf0e10cSrcweir     nForLvl   = 0;
574*cdf0e10cSrcweir     nOps      = 0;
575*cdf0e10cSrcweir     refExprStk = new SbxArray;
576*cdf0e10cSrcweir     SetVBAEnabled( pMod->IsVBACompat() );
577*cdf0e10cSrcweir #if defined GCC
578*cdf0e10cSrcweir     SetParameters( pe ? pe->GetParameters() : (class SbxArray *)NULL );
579*cdf0e10cSrcweir #else
580*cdf0e10cSrcweir     SetParameters( pe ? pe->GetParameters() : NULL );
581*cdf0e10cSrcweir #endif
582*cdf0e10cSrcweir     pRefSaveList = NULL;
583*cdf0e10cSrcweir     pItemStoreList = NULL;
584*cdf0e10cSrcweir }
585*cdf0e10cSrcweir 
586*cdf0e10cSrcweir SbiRuntime::~SbiRuntime()
587*cdf0e10cSrcweir {
588*cdf0e10cSrcweir     ClearGosubStack();
589*cdf0e10cSrcweir     ClearArgvStack();
590*cdf0e10cSrcweir     ClearForStack();
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir     // #74254 Items zum Sichern temporaere Referenzen freigeben
593*cdf0e10cSrcweir     ClearRefs();
594*cdf0e10cSrcweir     while( pItemStoreList )
595*cdf0e10cSrcweir     {
596*cdf0e10cSrcweir         RefSaveItem* pToDeleteItem = pItemStoreList;
597*cdf0e10cSrcweir         pItemStoreList = pToDeleteItem->pNext;
598*cdf0e10cSrcweir         delete pToDeleteItem;
599*cdf0e10cSrcweir     }
600*cdf0e10cSrcweir }
601*cdf0e10cSrcweir 
602*cdf0e10cSrcweir void SbiRuntime::SetVBAEnabled(bool bEnabled )
603*cdf0e10cSrcweir {
604*cdf0e10cSrcweir     bVBAEnabled = bEnabled;
605*cdf0e10cSrcweir }
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir // Aufbau der Parameterliste. Alle ByRef-Parameter werden direkt
608*cdf0e10cSrcweir // uebernommen; von ByVal-Parametern werden Kopien angelegt. Falls
609*cdf0e10cSrcweir // ein bestimmter Datentyp verlangt wird, wird konvertiert.
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir void SbiRuntime::SetParameters( SbxArray* pParams )
612*cdf0e10cSrcweir {
613*cdf0e10cSrcweir     refParams = new SbxArray;
614*cdf0e10cSrcweir     // fuer den Returnwert
615*cdf0e10cSrcweir     refParams->Put( pMeth, 0 );
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir     SbxInfo* pInfo = pMeth ? pMeth->GetInfo() : NULL;
618*cdf0e10cSrcweir     sal_uInt16 nParamCount = pParams ? pParams->Count() : 1;
619*cdf0e10cSrcweir     if( nParamCount > 1 )
620*cdf0e10cSrcweir     {
621*cdf0e10cSrcweir         for( sal_uInt16 i = 1 ; i < nParamCount ; i++ )
622*cdf0e10cSrcweir         {
623*cdf0e10cSrcweir             const SbxParamInfo* p = pInfo ? pInfo->GetParam( i ) : NULL;
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir             // #111897 ParamArray
626*cdf0e10cSrcweir             if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
627*cdf0e10cSrcweir             {
628*cdf0e10cSrcweir                 SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
629*cdf0e10cSrcweir                 sal_uInt16 nParamArrayParamCount = nParamCount - i;
630*cdf0e10cSrcweir                 pArray->unoAddDim( 0, nParamArrayParamCount - 1 );
631*cdf0e10cSrcweir                 for( sal_uInt16 j = i ; j < nParamCount ; j++ )
632*cdf0e10cSrcweir                 {
633*cdf0e10cSrcweir                     SbxVariable* v = pParams->Get( j );
634*cdf0e10cSrcweir                     short nDimIndex = j - i;
635*cdf0e10cSrcweir                     pArray->Put( v, &nDimIndex );
636*cdf0e10cSrcweir                 }
637*cdf0e10cSrcweir                 SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
638*cdf0e10cSrcweir                 pArrayVar->SetFlag( SBX_READWRITE );
639*cdf0e10cSrcweir                 pArrayVar->PutObject( pArray );
640*cdf0e10cSrcweir                 refParams->Put( pArrayVar, i );
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir                 // Block ParamArray for missing parameter
643*cdf0e10cSrcweir                 pInfo = NULL;
644*cdf0e10cSrcweir                 break;
645*cdf0e10cSrcweir             }
646*cdf0e10cSrcweir 
647*cdf0e10cSrcweir             SbxVariable* v = pParams->Get( i );
648*cdf0e10cSrcweir             // Methoden sind immer byval!
649*cdf0e10cSrcweir             sal_Bool bByVal = v->IsA( TYPE(SbxMethod) );
650*cdf0e10cSrcweir             SbxDataType t = v->GetType();
651*cdf0e10cSrcweir             bool bTargetTypeIsArray = false;
652*cdf0e10cSrcweir             if( p )
653*cdf0e10cSrcweir             {
654*cdf0e10cSrcweir                 bByVal |= sal_Bool( ( p->eType & SbxBYREF ) == 0 );
655*cdf0e10cSrcweir                 t = (SbxDataType) ( p->eType & 0x0FFF );
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir                 if( !bByVal && t != SbxVARIANT &&
658*cdf0e10cSrcweir                     (!v->IsFixed() || (SbxDataType)(v->GetType() & 0x0FFF ) != t) )
659*cdf0e10cSrcweir                         bByVal = sal_True;
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir                 bTargetTypeIsArray = (p->nUserData & PARAM_INFO_WITHBRACKETS) != 0;
662*cdf0e10cSrcweir             }
663*cdf0e10cSrcweir             if( bByVal )
664*cdf0e10cSrcweir             {
665*cdf0e10cSrcweir                 if( bTargetTypeIsArray )
666*cdf0e10cSrcweir                     t = SbxOBJECT;
667*cdf0e10cSrcweir                 SbxVariable* v2 = new SbxVariable( t );
668*cdf0e10cSrcweir                 v2->SetFlag( SBX_READWRITE );
669*cdf0e10cSrcweir                 *v2 = *v;
670*cdf0e10cSrcweir                 refParams->Put( v2, i );
671*cdf0e10cSrcweir             }
672*cdf0e10cSrcweir             else
673*cdf0e10cSrcweir             {
674*cdf0e10cSrcweir                 if( t != SbxVARIANT && t != ( v->GetType() & 0x0FFF ) )
675*cdf0e10cSrcweir                 {
676*cdf0e10cSrcweir                     // Array konvertieren??
677*cdf0e10cSrcweir                     if( p && (p->eType & SbxARRAY) )
678*cdf0e10cSrcweir                         Error( SbERR_CONVERSION );
679*cdf0e10cSrcweir                     else
680*cdf0e10cSrcweir                         v->Convert( t );
681*cdf0e10cSrcweir                 }
682*cdf0e10cSrcweir                 refParams->Put( v, i );
683*cdf0e10cSrcweir             }
684*cdf0e10cSrcweir             if( p )
685*cdf0e10cSrcweir                 refParams->PutAlias( p->aName, i );
686*cdf0e10cSrcweir         }
687*cdf0e10cSrcweir     }
688*cdf0e10cSrcweir 
689*cdf0e10cSrcweir     // ParamArray for missing parameter
690*cdf0e10cSrcweir     if( pInfo )
691*cdf0e10cSrcweir     {
692*cdf0e10cSrcweir         // #111897 Check first missing parameter for ParamArray
693*cdf0e10cSrcweir         const SbxParamInfo* p = pInfo->GetParam( nParamCount );
694*cdf0e10cSrcweir         if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
695*cdf0e10cSrcweir         {
696*cdf0e10cSrcweir             SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
697*cdf0e10cSrcweir             pArray->unoAddDim( 0, -1 );
698*cdf0e10cSrcweir             SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
699*cdf0e10cSrcweir             pArrayVar->SetFlag( SBX_READWRITE );
700*cdf0e10cSrcweir             pArrayVar->PutObject( pArray );
701*cdf0e10cSrcweir             refParams->Put( pArrayVar, nParamCount );
702*cdf0e10cSrcweir         }
703*cdf0e10cSrcweir     }
704*cdf0e10cSrcweir }
705*cdf0e10cSrcweir 
706*cdf0e10cSrcweir 
707*cdf0e10cSrcweir // Einen P-Code ausfuehren
708*cdf0e10cSrcweir 
709*cdf0e10cSrcweir sal_Bool SbiRuntime::Step()
710*cdf0e10cSrcweir {
711*cdf0e10cSrcweir     if( bRun )
712*cdf0e10cSrcweir     {
713*cdf0e10cSrcweir         // Unbedingt gelegentlich die Kontrolle abgeben!
714*cdf0e10cSrcweir         if( !( ++nOps & 0xF ) && pInst->IsReschedule() && bStaticGlobalEnableReschedule )
715*cdf0e10cSrcweir         {
716*cdf0e10cSrcweir             sal_uInt32 nTime = osl_getGlobalTimer();
717*cdf0e10cSrcweir             if (nTime - m_nLastTime > 5 ) // 20 ms
718*cdf0e10cSrcweir             {
719*cdf0e10cSrcweir                 Application::Reschedule();
720*cdf0e10cSrcweir                 m_nLastTime = nTime;
721*cdf0e10cSrcweir             }
722*cdf0e10cSrcweir         }
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir         // #i48868 blocked by next call level?
725*cdf0e10cSrcweir         while( bBlocked )
726*cdf0e10cSrcweir         {
727*cdf0e10cSrcweir             if( pInst->IsReschedule() && bStaticGlobalEnableReschedule )
728*cdf0e10cSrcweir                 Application::Reschedule();
729*cdf0e10cSrcweir         }
730*cdf0e10cSrcweir 
731*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
732*cdf0e10cSrcweir         sal_uInt32 nPC = ( pCode - (const sal_uInt8* )pImg->GetCode() );
733*cdf0e10cSrcweir         dbg_traceStep( pMod, nPC, pINST->nCallLvl );
734*cdf0e10cSrcweir #endif
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir         SbiOpcode eOp = (SbiOpcode ) ( *pCode++ );
737*cdf0e10cSrcweir         sal_uInt32 nOp1, nOp2;
738*cdf0e10cSrcweir         if( eOp <= SbOP0_END )
739*cdf0e10cSrcweir         {
740*cdf0e10cSrcweir             (this->*( aStep0[ eOp ] ) )();
741*cdf0e10cSrcweir         }
742*cdf0e10cSrcweir         else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
743*cdf0e10cSrcweir         {
744*cdf0e10cSrcweir             nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
745*cdf0e10cSrcweir 
746*cdf0e10cSrcweir             (this->*( aStep1[ eOp - SbOP1_START ] ) )( nOp1 );
747*cdf0e10cSrcweir         }
748*cdf0e10cSrcweir         else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
749*cdf0e10cSrcweir         {
750*cdf0e10cSrcweir             nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
751*cdf0e10cSrcweir             nOp2 = *pCode++; nOp2 |= *pCode++ << 8; nOp2 |= *pCode++ << 16; nOp2 |= *pCode++ << 24;
752*cdf0e10cSrcweir             (this->*( aStep2[ eOp - SbOP2_START ] ) )( nOp1, nOp2 );
753*cdf0e10cSrcweir         }
754*cdf0e10cSrcweir         else
755*cdf0e10cSrcweir             StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
756*cdf0e10cSrcweir 
757*cdf0e10cSrcweir         // SBX-Fehler aufgetreten?
758*cdf0e10cSrcweir         SbError nSbError = SbxBase::GetError();
759*cdf0e10cSrcweir         Error( ERRCODE_TOERROR(nSbError) );         // Warnings rausfiltern
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir         // AB 13.2.1997, neues Error-Handling:
762*cdf0e10cSrcweir         // ACHTUNG: Hier kann nError auch dann gesetzt sein, wenn !nSbError,
763*cdf0e10cSrcweir         // da nError jetzt auch von anderen RT-Instanzen gesetzt werden kann
764*cdf0e10cSrcweir 
765*cdf0e10cSrcweir         if( nError )
766*cdf0e10cSrcweir             SbxBase::ResetError();
767*cdf0e10cSrcweir 
768*cdf0e10cSrcweir         // AB,15.3.96: Fehler nur anzeigen, wenn BASIC noch aktiv
769*cdf0e10cSrcweir         // (insbesondere nicht nach Compiler-Fehlern zur Laufzeit)
770*cdf0e10cSrcweir         if( nError && bRun )
771*cdf0e10cSrcweir         {
772*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
773*cdf0e10cSrcweir             SbError nTraceErr = nError;
774*cdf0e10cSrcweir             String aTraceErrMsg = GetSbData()->aErrMsg;
775*cdf0e10cSrcweir             bool bTraceErrHandled = true;
776*cdf0e10cSrcweir #endif
777*cdf0e10cSrcweir             SbError err = nError;
778*cdf0e10cSrcweir             ClearExprStack();
779*cdf0e10cSrcweir             nError = 0;
780*cdf0e10cSrcweir             pInst->nErr = err;
781*cdf0e10cSrcweir             pInst->nErl = nLine;
782*cdf0e10cSrcweir             pErrCode    = pCode;
783*cdf0e10cSrcweir             pErrStmnt   = pStmnt;
784*cdf0e10cSrcweir             // An error occured in an error handler
785*cdf0e10cSrcweir             // force parent handler ( if there is one )
786*cdf0e10cSrcweir             // to handle the error
787*cdf0e10cSrcweir             bool bLetParentHandleThis = false;
788*cdf0e10cSrcweir 
789*cdf0e10cSrcweir             // Im Error Handler? Dann Std-Error
790*cdf0e10cSrcweir             if ( !bInError )
791*cdf0e10cSrcweir             {
792*cdf0e10cSrcweir                 bInError = sal_True;
793*cdf0e10cSrcweir 
794*cdf0e10cSrcweir                 if( !bError )           // On Error Resume Next
795*cdf0e10cSrcweir                     StepRESUME( 1 );
796*cdf0e10cSrcweir                 else if( pError )       // On Error Goto ...
797*cdf0e10cSrcweir                     pCode = pError;
798*cdf0e10cSrcweir                 else
799*cdf0e10cSrcweir                     bLetParentHandleThis = true;
800*cdf0e10cSrcweir             }
801*cdf0e10cSrcweir             else
802*cdf0e10cSrcweir             {
803*cdf0e10cSrcweir                 bLetParentHandleThis = true;
804*cdf0e10cSrcweir                 pError = NULL; //terminate the handler
805*cdf0e10cSrcweir             }
806*cdf0e10cSrcweir             if ( bLetParentHandleThis )
807*cdf0e10cSrcweir             {
808*cdf0e10cSrcweir                 // AB 13.2.1997, neues Error-Handling:
809*cdf0e10cSrcweir                 // Uebergeordnete Error-Handler beruecksichtigen
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir                 // Wir haben keinen Error-Handler -> weiter oben suchen
812*cdf0e10cSrcweir                 SbiRuntime* pRtErrHdl = NULL;
813*cdf0e10cSrcweir                 SbiRuntime* pRt = this;
814*cdf0e10cSrcweir                 while( NULL != (pRt = pRt->pNext) )
815*cdf0e10cSrcweir                 {
816*cdf0e10cSrcweir                     // Gibt es einen Error-Handler?
817*cdf0e10cSrcweir                     if( pRt->bError == sal_False || pRt->pError != NULL )
818*cdf0e10cSrcweir                     {
819*cdf0e10cSrcweir                         pRtErrHdl = pRt;
820*cdf0e10cSrcweir                         break;
821*cdf0e10cSrcweir                     }
822*cdf0e10cSrcweir                 }
823*cdf0e10cSrcweir 
824*cdf0e10cSrcweir                 // Error-Hdl gefunden?
825*cdf0e10cSrcweir                 if( pRtErrHdl )
826*cdf0e10cSrcweir                 {
827*cdf0e10cSrcweir                     // (Neuen) Error-Stack anlegen
828*cdf0e10cSrcweir                     SbErrorStack*& rErrStack = GetSbData()->pErrStack;
829*cdf0e10cSrcweir                     if( rErrStack )
830*cdf0e10cSrcweir                         delete rErrStack;
831*cdf0e10cSrcweir                     rErrStack = new SbErrorStack();
832*cdf0e10cSrcweir 
833*cdf0e10cSrcweir                     // Alle im Call-Stack darunter stehenden RTs manipulieren
834*cdf0e10cSrcweir                     pRt = this;
835*cdf0e10cSrcweir                     do
836*cdf0e10cSrcweir                     {
837*cdf0e10cSrcweir                         // Fehler setzen
838*cdf0e10cSrcweir                         pRt->nError = err;
839*cdf0e10cSrcweir                         if( pRt != pRtErrHdl )
840*cdf0e10cSrcweir                             pRt->bRun = sal_False;
841*cdf0e10cSrcweir 
842*cdf0e10cSrcweir                         // In Error-Stack eintragen
843*cdf0e10cSrcweir                         SbErrorStackEntry *pEntry = new SbErrorStackEntry
844*cdf0e10cSrcweir                             ( pRt->pMeth, pRt->nLine, pRt->nCol1, pRt->nCol2 );
845*cdf0e10cSrcweir                         rErrStack->C40_INSERT(SbErrorStackEntry, pEntry, rErrStack->Count() );
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir                         // Nach RT mit Error-Handler aufhoeren
848*cdf0e10cSrcweir                         if( pRt == pRtErrHdl )
849*cdf0e10cSrcweir                             break;
850*cdf0e10cSrcweir                            pRt = pRt->pNext;
851*cdf0e10cSrcweir                     }
852*cdf0e10cSrcweir                     while( pRt );
853*cdf0e10cSrcweir                 }
854*cdf0e10cSrcweir                 // Kein Error-Hdl gefunden -> altes Vorgehen
855*cdf0e10cSrcweir                 else
856*cdf0e10cSrcweir                 {
857*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
858*cdf0e10cSrcweir                     bTraceErrHandled = false;
859*cdf0e10cSrcweir #endif
860*cdf0e10cSrcweir                     pInst->Abort();
861*cdf0e10cSrcweir                 }
862*cdf0e10cSrcweir 
863*cdf0e10cSrcweir                 // ALT: Nur
864*cdf0e10cSrcweir                 // pInst->Abort();
865*cdf0e10cSrcweir             }
866*cdf0e10cSrcweir 
867*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
868*cdf0e10cSrcweir             dbg_traceNotifyError( nTraceErr, aTraceErrMsg, bTraceErrHandled, pINST->nCallLvl );
869*cdf0e10cSrcweir #endif
870*cdf0e10cSrcweir         }
871*cdf0e10cSrcweir     }
872*cdf0e10cSrcweir     return bRun;
873*cdf0e10cSrcweir }
874*cdf0e10cSrcweir 
875*cdf0e10cSrcweir void SbiRuntime::Error( SbError n, bool bVBATranslationAlreadyDone )
876*cdf0e10cSrcweir {
877*cdf0e10cSrcweir     if( n )
878*cdf0e10cSrcweir     {
879*cdf0e10cSrcweir         nError = n;
880*cdf0e10cSrcweir         if( isVBAEnabled() && !bVBATranslationAlreadyDone )
881*cdf0e10cSrcweir         {
882*cdf0e10cSrcweir             String aMsg = pInst->GetErrorMsg();
883*cdf0e10cSrcweir             sal_Int32 nVBAErrorNumber = translateErrorToVba( nError, aMsg );
884*cdf0e10cSrcweir             SbxVariable* pSbxErrObjVar = SbxErrObject::getErrObject();
885*cdf0e10cSrcweir             SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pSbxErrObjVar );
886*cdf0e10cSrcweir             if( pGlobErr != NULL )
887*cdf0e10cSrcweir                 pGlobErr->setNumberAndDescription( nVBAErrorNumber, aMsg );
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir             pInst->aErrorMsg = aMsg;
890*cdf0e10cSrcweir             nError = SbERR_BASIC_COMPAT;
891*cdf0e10cSrcweir         }
892*cdf0e10cSrcweir     }
893*cdf0e10cSrcweir }
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir void SbiRuntime::Error( SbError _errCode, const String& _details )
896*cdf0e10cSrcweir {
897*cdf0e10cSrcweir     if ( _errCode )
898*cdf0e10cSrcweir     {
899*cdf0e10cSrcweir         // Not correct for class module usage, remove for now
900*cdf0e10cSrcweir         //OSL_ENSURE( pInst->pRun == this, "SbiRuntime::Error: can't propagate the error message details!" );
901*cdf0e10cSrcweir         if ( pInst->pRun == this )
902*cdf0e10cSrcweir         {
903*cdf0e10cSrcweir             pInst->Error( _errCode, _details );
904*cdf0e10cSrcweir             //OSL_POSTCOND( nError == _errCode, "SbiRuntime::Error: the instance is expecte to propagate the error code back to me!" );
905*cdf0e10cSrcweir         }
906*cdf0e10cSrcweir         else
907*cdf0e10cSrcweir         {
908*cdf0e10cSrcweir             nError = _errCode;
909*cdf0e10cSrcweir         }
910*cdf0e10cSrcweir     }
911*cdf0e10cSrcweir }
912*cdf0e10cSrcweir 
913*cdf0e10cSrcweir void SbiRuntime::FatalError( SbError n )
914*cdf0e10cSrcweir {
915*cdf0e10cSrcweir     StepSTDERROR();
916*cdf0e10cSrcweir     Error( n );
917*cdf0e10cSrcweir }
918*cdf0e10cSrcweir 
919*cdf0e10cSrcweir void SbiRuntime::FatalError( SbError _errCode, const String& _details )
920*cdf0e10cSrcweir {
921*cdf0e10cSrcweir     StepSTDERROR();
922*cdf0e10cSrcweir     Error( _errCode, _details );
923*cdf0e10cSrcweir }
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, String& rMsg )
926*cdf0e10cSrcweir {
927*cdf0e10cSrcweir     // If a message is defined use that ( in preference to
928*cdf0e10cSrcweir     // the defined one for the error ) NB #TODO
929*cdf0e10cSrcweir     // if there is an error defined it more than likely
930*cdf0e10cSrcweir     // is not the one you want ( some are the same though )
931*cdf0e10cSrcweir     // we really need a new vba compatible error list
932*cdf0e10cSrcweir     if ( !rMsg.Len() )
933*cdf0e10cSrcweir     {
934*cdf0e10cSrcweir         // TEST, has to be vb here always
935*cdf0e10cSrcweir #ifdef DBG_UTIL
936*cdf0e10cSrcweir         SbError nTmp = StarBASIC::GetSfxFromVBError( (sal_uInt16)nError );
937*cdf0e10cSrcweir         DBG_ASSERT( nTmp, "No VB error!" );
938*cdf0e10cSrcweir #endif
939*cdf0e10cSrcweir 
940*cdf0e10cSrcweir         StarBASIC::MakeErrorText( nError, rMsg );
941*cdf0e10cSrcweir         rMsg = StarBASIC::GetErrorText();
942*cdf0e10cSrcweir         if ( !rMsg.Len() ) // no message for err no, need localized resource here
943*cdf0e10cSrcweir             rMsg = String( RTL_CONSTASCII_USTRINGPARAM("Internal Object Error:") );
944*cdf0e10cSrcweir     }
945*cdf0e10cSrcweir     // no num? most likely then it *is* really a vba err
946*cdf0e10cSrcweir     sal_uInt16 nVBErrorCode = StarBASIC::GetVBErrorCode( nError );
947*cdf0e10cSrcweir     sal_Int32 nVBAErrorNumber = ( nVBErrorCode == 0 ) ? nError : nVBErrorCode;
948*cdf0e10cSrcweir     return nVBAErrorNumber;
949*cdf0e10cSrcweir }
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
952*cdf0e10cSrcweir //
953*cdf0e10cSrcweir //  Parameter, Locals, Caller
954*cdf0e10cSrcweir //
955*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
956*cdf0e10cSrcweir 
957*cdf0e10cSrcweir SbMethod* SbiRuntime::GetCaller()
958*cdf0e10cSrcweir {
959*cdf0e10cSrcweir     return pMeth;
960*cdf0e10cSrcweir }
961*cdf0e10cSrcweir 
962*cdf0e10cSrcweir SbxArray* SbiRuntime::GetLocals()
963*cdf0e10cSrcweir {
964*cdf0e10cSrcweir     return refLocals;
965*cdf0e10cSrcweir }
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir SbxArray* SbiRuntime::GetParams()
968*cdf0e10cSrcweir {
969*cdf0e10cSrcweir     return refParams;
970*cdf0e10cSrcweir }
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
973*cdf0e10cSrcweir //
974*cdf0e10cSrcweir //  Stacks
975*cdf0e10cSrcweir //
976*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
977*cdf0e10cSrcweir 
978*cdf0e10cSrcweir // Der Expression-Stack steht fuer die laufende Auswertung von Expressions
979*cdf0e10cSrcweir // zur Verfuegung.
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir void SbiRuntime::PushVar( SbxVariable* pVar )
982*cdf0e10cSrcweir {
983*cdf0e10cSrcweir     if( pVar )
984*cdf0e10cSrcweir         refExprStk->Put( pVar, nExprLvl++ );
985*cdf0e10cSrcweir }
986*cdf0e10cSrcweir 
987*cdf0e10cSrcweir SbxVariableRef SbiRuntime::PopVar()
988*cdf0e10cSrcweir {
989*cdf0e10cSrcweir #ifdef DBG_UTIL
990*cdf0e10cSrcweir     if( !nExprLvl )
991*cdf0e10cSrcweir     {
992*cdf0e10cSrcweir         StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
993*cdf0e10cSrcweir         return new SbxVariable;
994*cdf0e10cSrcweir     }
995*cdf0e10cSrcweir #endif
996*cdf0e10cSrcweir     SbxVariableRef xVar = refExprStk->Get( --nExprLvl );
997*cdf0e10cSrcweir #ifdef DBG_UTIL
998*cdf0e10cSrcweir     if ( xVar->GetName().EqualsAscii( "Cells" ) )
999*cdf0e10cSrcweir         DBG_TRACE( "" );
1000*cdf0e10cSrcweir #endif
1001*cdf0e10cSrcweir     // Methods halten im 0.Parameter sich selbst, also weghauen
1002*cdf0e10cSrcweir     if( xVar->IsA( TYPE(SbxMethod) ) )
1003*cdf0e10cSrcweir         xVar->SetParameters(0);
1004*cdf0e10cSrcweir     return xVar;
1005*cdf0e10cSrcweir }
1006*cdf0e10cSrcweir 
1007*cdf0e10cSrcweir sal_Bool SbiRuntime::ClearExprStack()
1008*cdf0e10cSrcweir {
1009*cdf0e10cSrcweir     // Achtung: Clear() reicht nicht, da Methods geloescht werden muessen
1010*cdf0e10cSrcweir     while ( nExprLvl )
1011*cdf0e10cSrcweir     {
1012*cdf0e10cSrcweir         PopVar();
1013*cdf0e10cSrcweir     }
1014*cdf0e10cSrcweir     refExprStk->Clear();
1015*cdf0e10cSrcweir     return sal_False;
1016*cdf0e10cSrcweir }
1017*cdf0e10cSrcweir 
1018*cdf0e10cSrcweir // Variable auf dem Expression-Stack holen, ohne sie zu entfernen
1019*cdf0e10cSrcweir // n zaehlt ab 0.
1020*cdf0e10cSrcweir 
1021*cdf0e10cSrcweir SbxVariable* SbiRuntime::GetTOS( short n )
1022*cdf0e10cSrcweir {
1023*cdf0e10cSrcweir     n = nExprLvl - n - 1;
1024*cdf0e10cSrcweir #ifdef DBG_UTIL
1025*cdf0e10cSrcweir     if( n < 0 )
1026*cdf0e10cSrcweir     {
1027*cdf0e10cSrcweir         StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
1028*cdf0e10cSrcweir         return new SbxVariable;
1029*cdf0e10cSrcweir     }
1030*cdf0e10cSrcweir #endif
1031*cdf0e10cSrcweir     return refExprStk->Get( (sal_uInt16) n );
1032*cdf0e10cSrcweir }
1033*cdf0e10cSrcweir 
1034*cdf0e10cSrcweir // Sicherstellen, dass TOS eine temporaere Variable ist
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir void SbiRuntime::TOSMakeTemp()
1037*cdf0e10cSrcweir {
1038*cdf0e10cSrcweir     SbxVariable* p = refExprStk->Get( nExprLvl - 1 );
1039*cdf0e10cSrcweir     if( p->GetRefCount() != 1 )
1040*cdf0e10cSrcweir     {
1041*cdf0e10cSrcweir         SbxVariable* pNew = new SbxVariable( *p );
1042*cdf0e10cSrcweir         pNew->SetFlag( SBX_READWRITE );
1043*cdf0e10cSrcweir         refExprStk->Put( pNew, nExprLvl - 1 );
1044*cdf0e10cSrcweir     }
1045*cdf0e10cSrcweir }
1046*cdf0e10cSrcweir 
1047*cdf0e10cSrcweir // Der GOSUB-Stack nimmt Returnadressen fuer GOSUBs auf
1048*cdf0e10cSrcweir 
1049*cdf0e10cSrcweir void SbiRuntime::PushGosub( const sal_uInt8* pc )
1050*cdf0e10cSrcweir {
1051*cdf0e10cSrcweir     if( ++nGosubLvl > MAXRECURSION )
1052*cdf0e10cSrcweir         StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
1053*cdf0e10cSrcweir     SbiGosubStack* p = new SbiGosubStack;
1054*cdf0e10cSrcweir     p->pCode  = pc;
1055*cdf0e10cSrcweir     p->pNext  = pGosubStk;
1056*cdf0e10cSrcweir     p->nStartForLvl = nForLvl;
1057*cdf0e10cSrcweir     pGosubStk = p;
1058*cdf0e10cSrcweir }
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir void SbiRuntime::PopGosub()
1061*cdf0e10cSrcweir {
1062*cdf0e10cSrcweir     if( !pGosubStk )
1063*cdf0e10cSrcweir         Error( SbERR_NO_GOSUB );
1064*cdf0e10cSrcweir     else
1065*cdf0e10cSrcweir     {
1066*cdf0e10cSrcweir         SbiGosubStack* p = pGosubStk;
1067*cdf0e10cSrcweir         pCode = p->pCode;
1068*cdf0e10cSrcweir         pGosubStk = p->pNext;
1069*cdf0e10cSrcweir         delete p;
1070*cdf0e10cSrcweir         nGosubLvl--;
1071*cdf0e10cSrcweir     }
1072*cdf0e10cSrcweir }
1073*cdf0e10cSrcweir 
1074*cdf0e10cSrcweir // Entleeren des GOSUB-Stacks
1075*cdf0e10cSrcweir 
1076*cdf0e10cSrcweir void SbiRuntime::ClearGosubStack()
1077*cdf0e10cSrcweir {
1078*cdf0e10cSrcweir     SbiGosubStack* p;
1079*cdf0e10cSrcweir     while(( p = pGosubStk ) != NULL )
1080*cdf0e10cSrcweir         pGosubStk = p->pNext, delete p;
1081*cdf0e10cSrcweir     nGosubLvl = 0;
1082*cdf0e10cSrcweir }
1083*cdf0e10cSrcweir 
1084*cdf0e10cSrcweir // Der Argv-Stack nimmt aktuelle Argument-Vektoren auf
1085*cdf0e10cSrcweir 
1086*cdf0e10cSrcweir void SbiRuntime::PushArgv()
1087*cdf0e10cSrcweir {
1088*cdf0e10cSrcweir     SbiArgvStack* p = new SbiArgvStack;
1089*cdf0e10cSrcweir     p->refArgv = refArgv;
1090*cdf0e10cSrcweir     p->nArgc = nArgc;
1091*cdf0e10cSrcweir     nArgc = 1;
1092*cdf0e10cSrcweir     refArgv.Clear();
1093*cdf0e10cSrcweir     p->pNext = pArgvStk;
1094*cdf0e10cSrcweir     pArgvStk = p;
1095*cdf0e10cSrcweir }
1096*cdf0e10cSrcweir 
1097*cdf0e10cSrcweir void SbiRuntime::PopArgv()
1098*cdf0e10cSrcweir {
1099*cdf0e10cSrcweir     if( pArgvStk )
1100*cdf0e10cSrcweir     {
1101*cdf0e10cSrcweir         SbiArgvStack* p = pArgvStk;
1102*cdf0e10cSrcweir         pArgvStk = p->pNext;
1103*cdf0e10cSrcweir         refArgv = p->refArgv;
1104*cdf0e10cSrcweir         nArgc = p->nArgc;
1105*cdf0e10cSrcweir         delete p;
1106*cdf0e10cSrcweir     }
1107*cdf0e10cSrcweir }
1108*cdf0e10cSrcweir 
1109*cdf0e10cSrcweir // Entleeren des Argv-Stacks
1110*cdf0e10cSrcweir 
1111*cdf0e10cSrcweir void SbiRuntime::ClearArgvStack()
1112*cdf0e10cSrcweir {
1113*cdf0e10cSrcweir     while( pArgvStk )
1114*cdf0e10cSrcweir         PopArgv();
1115*cdf0e10cSrcweir }
1116*cdf0e10cSrcweir 
1117*cdf0e10cSrcweir // Push des For-Stacks. Der Stack hat Inkrement, Ende, Beginn und Variable.
1118*cdf0e10cSrcweir // Nach Aufbau des Stack-Elements ist der Stack leer.
1119*cdf0e10cSrcweir 
1120*cdf0e10cSrcweir void SbiRuntime::PushFor()
1121*cdf0e10cSrcweir {
1122*cdf0e10cSrcweir     SbiForStack* p = new SbiForStack;
1123*cdf0e10cSrcweir     p->eForType = FOR_TO;
1124*cdf0e10cSrcweir     p->pNext = pForStk;
1125*cdf0e10cSrcweir     pForStk = p;
1126*cdf0e10cSrcweir     // Der Stack ist wie folgt aufgebaut:
1127*cdf0e10cSrcweir     p->refInc = PopVar();
1128*cdf0e10cSrcweir     p->refEnd = PopVar();
1129*cdf0e10cSrcweir     SbxVariableRef xBgn = PopVar();
1130*cdf0e10cSrcweir     p->refVar = PopVar();
1131*cdf0e10cSrcweir     *(p->refVar) = *xBgn;
1132*cdf0e10cSrcweir     nForLvl++;
1133*cdf0e10cSrcweir }
1134*cdf0e10cSrcweir 
1135*cdf0e10cSrcweir void SbiRuntime::PushForEach()
1136*cdf0e10cSrcweir {
1137*cdf0e10cSrcweir     SbiForStack* p = new SbiForStack;
1138*cdf0e10cSrcweir     p->pNext = pForStk;
1139*cdf0e10cSrcweir     pForStk = p;
1140*cdf0e10cSrcweir 
1141*cdf0e10cSrcweir     SbxVariableRef xObjVar = PopVar();
1142*cdf0e10cSrcweir     SbxBase* pObj = xObjVar.Is() ? xObjVar->GetObject() : NULL;
1143*cdf0e10cSrcweir     if( pObj == NULL )
1144*cdf0e10cSrcweir     {
1145*cdf0e10cSrcweir         Error( SbERR_NO_OBJECT );
1146*cdf0e10cSrcweir         return;
1147*cdf0e10cSrcweir     }
1148*cdf0e10cSrcweir 
1149*cdf0e10cSrcweir     bool bError_ = false;
1150*cdf0e10cSrcweir     BasicCollection* pCollection;
1151*cdf0e10cSrcweir     SbxDimArray* pArray;
1152*cdf0e10cSrcweir     SbUnoObject* pUnoObj;
1153*cdf0e10cSrcweir     if( (pArray = PTR_CAST(SbxDimArray,pObj)) != NULL )
1154*cdf0e10cSrcweir     {
1155*cdf0e10cSrcweir         p->eForType = FOR_EACH_ARRAY;
1156*cdf0e10cSrcweir         p->refEnd = (SbxVariable*)pArray;
1157*cdf0e10cSrcweir 
1158*cdf0e10cSrcweir         short nDims = pArray->GetDims();
1159*cdf0e10cSrcweir         p->pArrayLowerBounds = new sal_Int32[nDims];
1160*cdf0e10cSrcweir         p->pArrayUpperBounds = new sal_Int32[nDims];
1161*cdf0e10cSrcweir         p->pArrayCurIndices  = new sal_Int32[nDims];
1162*cdf0e10cSrcweir         sal_Int32 lBound, uBound;
1163*cdf0e10cSrcweir         for( short i = 0 ; i < nDims ; i++ )
1164*cdf0e10cSrcweir         {
1165*cdf0e10cSrcweir             pArray->GetDim32( i+1, lBound, uBound );
1166*cdf0e10cSrcweir             p->pArrayCurIndices[i] = p->pArrayLowerBounds[i] = lBound;
1167*cdf0e10cSrcweir             p->pArrayUpperBounds[i] = uBound;
1168*cdf0e10cSrcweir         }
1169*cdf0e10cSrcweir     }
1170*cdf0e10cSrcweir     else if( (pCollection = PTR_CAST(BasicCollection,pObj)) != NULL )
1171*cdf0e10cSrcweir     {
1172*cdf0e10cSrcweir         p->eForType = FOR_EACH_COLLECTION;
1173*cdf0e10cSrcweir         p->refEnd = pCollection;
1174*cdf0e10cSrcweir         p->nCurCollectionIndex = 0;
1175*cdf0e10cSrcweir     }
1176*cdf0e10cSrcweir     else if( (pUnoObj = PTR_CAST(SbUnoObject,pObj)) != NULL )
1177*cdf0e10cSrcweir     {
1178*cdf0e10cSrcweir         // XEnumerationAccess?
1179*cdf0e10cSrcweir         Any aAny = pUnoObj->getUnoAny();
1180*cdf0e10cSrcweir         Reference< XEnumerationAccess > xEnumerationAccess;
1181*cdf0e10cSrcweir         if( (aAny >>= xEnumerationAccess) )
1182*cdf0e10cSrcweir         {
1183*cdf0e10cSrcweir             p->xEnumeration = xEnumerationAccess->createEnumeration();
1184*cdf0e10cSrcweir             p->eForType = FOR_EACH_XENUMERATION;
1185*cdf0e10cSrcweir         }
1186*cdf0e10cSrcweir         else if ( isVBAEnabled() && pUnoObj->isNativeCOMObject() )
1187*cdf0e10cSrcweir         {
1188*cdf0e10cSrcweir             uno::Reference< script::XInvocation > xInvocation;
1189*cdf0e10cSrcweir             if ( ( aAny >>= xInvocation ) && xInvocation.is() )
1190*cdf0e10cSrcweir             {
1191*cdf0e10cSrcweir                 try
1192*cdf0e10cSrcweir                 {
1193*cdf0e10cSrcweir                     p->xEnumeration = new ComEnumerationWrapper( xInvocation );
1194*cdf0e10cSrcweir                     p->eForType = FOR_EACH_XENUMERATION;
1195*cdf0e10cSrcweir                 }
1196*cdf0e10cSrcweir                 catch( uno::Exception& )
1197*cdf0e10cSrcweir                 {}
1198*cdf0e10cSrcweir             }
1199*cdf0e10cSrcweir 
1200*cdf0e10cSrcweir             if ( !p->xEnumeration.is() )
1201*cdf0e10cSrcweir                 bError_ = true;
1202*cdf0e10cSrcweir         }
1203*cdf0e10cSrcweir         else
1204*cdf0e10cSrcweir         {
1205*cdf0e10cSrcweir             bError_ = true;
1206*cdf0e10cSrcweir         }
1207*cdf0e10cSrcweir     }
1208*cdf0e10cSrcweir     else
1209*cdf0e10cSrcweir     {
1210*cdf0e10cSrcweir         bError_ = true;
1211*cdf0e10cSrcweir     }
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir     if( bError_ )
1214*cdf0e10cSrcweir     {
1215*cdf0e10cSrcweir         Error( SbERR_CONVERSION );
1216*cdf0e10cSrcweir         return;
1217*cdf0e10cSrcweir     }
1218*cdf0e10cSrcweir 
1219*cdf0e10cSrcweir     // Container variable
1220*cdf0e10cSrcweir     p->refVar = PopVar();
1221*cdf0e10cSrcweir     nForLvl++;
1222*cdf0e10cSrcweir }
1223*cdf0e10cSrcweir 
1224*cdf0e10cSrcweir // Poppen des FOR-Stacks
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir void SbiRuntime::PopFor()
1227*cdf0e10cSrcweir {
1228*cdf0e10cSrcweir     if( pForStk )
1229*cdf0e10cSrcweir     {
1230*cdf0e10cSrcweir         SbiForStack* p = pForStk;
1231*cdf0e10cSrcweir         pForStk = p->pNext;
1232*cdf0e10cSrcweir         delete p;
1233*cdf0e10cSrcweir         nForLvl--;
1234*cdf0e10cSrcweir     }
1235*cdf0e10cSrcweir }
1236*cdf0e10cSrcweir 
1237*cdf0e10cSrcweir // Entleeren des FOR-Stacks
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir void SbiRuntime::ClearForStack()
1240*cdf0e10cSrcweir {
1241*cdf0e10cSrcweir     while( pForStk )
1242*cdf0e10cSrcweir         PopFor();
1243*cdf0e10cSrcweir }
1244*cdf0e10cSrcweir 
1245*cdf0e10cSrcweir SbiForStack* SbiRuntime::FindForStackItemForCollection( class BasicCollection* pCollection )
1246*cdf0e10cSrcweir {
1247*cdf0e10cSrcweir     SbiForStack* pRet = NULL;
1248*cdf0e10cSrcweir 
1249*cdf0e10cSrcweir     SbiForStack* p = pForStk;
1250*cdf0e10cSrcweir     while( p )
1251*cdf0e10cSrcweir     {
1252*cdf0e10cSrcweir         SbxVariable* pVar = p->refEnd.Is() ? (SbxVariable*)p->refEnd : NULL;
1253*cdf0e10cSrcweir         if( p->eForType == FOR_EACH_COLLECTION && pVar != NULL &&
1254*cdf0e10cSrcweir             (pCollection = PTR_CAST(BasicCollection,pVar)) == pCollection )
1255*cdf0e10cSrcweir         {
1256*cdf0e10cSrcweir             pRet = p;
1257*cdf0e10cSrcweir             break;
1258*cdf0e10cSrcweir         }
1259*cdf0e10cSrcweir     }
1260*cdf0e10cSrcweir 
1261*cdf0e10cSrcweir     return pRet;
1262*cdf0e10cSrcweir }
1263*cdf0e10cSrcweir 
1264*cdf0e10cSrcweir 
1265*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
1266*cdf0e10cSrcweir //
1267*cdf0e10cSrcweir //  DLL-Aufrufe
1268*cdf0e10cSrcweir //
1269*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
1270*cdf0e10cSrcweir 
1271*cdf0e10cSrcweir void SbiRuntime::DllCall
1272*cdf0e10cSrcweir     ( const String& aFuncName,  // Funktionsname
1273*cdf0e10cSrcweir       const String& aDLLName,   // Name der DLL
1274*cdf0e10cSrcweir       SbxArray* pArgs,          // Parameter (ab Index 1, kann NULL sein)
1275*cdf0e10cSrcweir       SbxDataType eResType,     // Returnwert
1276*cdf0e10cSrcweir       sal_Bool bCDecl )             // sal_True: nach C-Konventionen
1277*cdf0e10cSrcweir {
1278*cdf0e10cSrcweir     // No DllCall for "virtual" portal users
1279*cdf0e10cSrcweir     if( needSecurityRestrictions() )
1280*cdf0e10cSrcweir     {
1281*cdf0e10cSrcweir         StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
1282*cdf0e10cSrcweir         return;
1283*cdf0e10cSrcweir     }
1284*cdf0e10cSrcweir 
1285*cdf0e10cSrcweir     // MUSS NOCH IMPLEMENTIERT WERDEN
1286*cdf0e10cSrcweir     /*
1287*cdf0e10cSrcweir     String aMsg;
1288*cdf0e10cSrcweir     aMsg = "FUNC=";
1289*cdf0e10cSrcweir     aMsg += pFunc;
1290*cdf0e10cSrcweir     aMsg += " DLL=";
1291*cdf0e10cSrcweir     aMsg += pDLL;
1292*cdf0e10cSrcweir     MessBox( NULL, WB_OK, String( "DLL-CALL" ), aMsg ).Execute();
1293*cdf0e10cSrcweir     Error( SbERR_NOT_IMPLEMENTED );
1294*cdf0e10cSrcweir     */
1295*cdf0e10cSrcweir 
1296*cdf0e10cSrcweir     SbxVariable* pRes = new SbxVariable( eResType );
1297*cdf0e10cSrcweir     SbiDllMgr* pDllMgr = pInst->GetDllMgr();
1298*cdf0e10cSrcweir     SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl );
1299*cdf0e10cSrcweir     if( nErr )
1300*cdf0e10cSrcweir         Error( nErr );
1301*cdf0e10cSrcweir     PushVar( pRes );
1302*cdf0e10cSrcweir }
1303*cdf0e10cSrcweir 
1304*cdf0e10cSrcweir sal_uInt16 SbiRuntime::GetImageFlag( sal_uInt16 n ) const
1305*cdf0e10cSrcweir {
1306*cdf0e10cSrcweir     return pImg->GetFlag( n );
1307*cdf0e10cSrcweir }
1308*cdf0e10cSrcweir 
1309*cdf0e10cSrcweir sal_uInt16 SbiRuntime::GetBase()
1310*cdf0e10cSrcweir {
1311*cdf0e10cSrcweir     return pImg->GetBase();
1312*cdf0e10cSrcweir }
1313