Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <tools/fsys.hxx>
21 : : #include <vcl/svapp.hxx>
22 : : #include <tools/wldcrd.hxx>
23 : : #include <svl/zforlist.hxx>
24 : : #include <unotools/syslocale.hxx>
25 : : #include "runtime.hxx"
26 : : #include "sbintern.hxx"
27 : : #include "opcodes.hxx"
28 : : #include "codegen.hxx"
29 : : #include "iosys.hxx"
30 : : #include "image.hxx"
31 : : #include "ddectrl.hxx"
32 : : #include "dllmgr.hxx"
33 : : #include <comphelper/processfactory.hxx>
34 : : #include <com/sun/star/container/XEnumerationAccess.hpp>
35 : : #include "sbunoobj.hxx"
36 : : #include "errobject.hxx"
37 : :
38 : : #include "comenumwrapper.hxx"
39 : :
40 : : SbxVariable* getDefaultProp( SbxVariable* pRef );
41 : :
42 : : using namespace ::com::sun::star;
43 : :
44 : 19625 : bool SbiRuntime::isVBAEnabled()
45 : : {
46 : 19625 : bool result = false;
47 : 19625 : SbiInstance* pInst = GetSbData()->pInst;
48 [ + - ][ + + ]: 19625 : if ( pInst && GetSbData()->pInst->pRun )
[ + + ]
49 : 19540 : result = pInst->pRun->bVBAEnabled;
50 : 19625 : return result;
51 : : }
52 : :
53 : 134 : void StarBASIC::SetVBAEnabled( sal_Bool bEnabled )
54 : : {
55 [ + + ]: 134 : if ( bDocBasic )
56 : : {
57 : 74 : bVBAEnabled = bEnabled;
58 : : }
59 : 134 : }
60 : :
61 : 159 : sal_Bool StarBASIC::isVBAEnabled()
62 : : {
63 [ + + ]: 159 : if ( bDocBasic )
64 : : {
65 [ - + ]: 79 : if( SbiRuntime::isVBAEnabled() )
66 : 0 : return sal_True;
67 : 79 : return bVBAEnabled;
68 : : }
69 : 159 : return sal_False;
70 : : }
71 : :
72 : :
73 : 5036 : struct SbiArgvStack { // Argv stack:
74 : : SbiArgvStack* pNext; // Stack Chain
75 : : SbxArrayRef refArgv; // Argv
76 : : short nArgc; // Argc
77 : : };
78 : :
79 : : SbiRuntime::pStep0 SbiRuntime::aStep0[] = { // all opcodes without operands
80 : : &SbiRuntime::StepNOP,
81 : : &SbiRuntime::StepEXP,
82 : : &SbiRuntime::StepMUL,
83 : : &SbiRuntime::StepDIV,
84 : : &SbiRuntime::StepMOD,
85 : : &SbiRuntime::StepPLUS,
86 : : &SbiRuntime::StepMINUS,
87 : : &SbiRuntime::StepNEG,
88 : : &SbiRuntime::StepEQ,
89 : : &SbiRuntime::StepNE,
90 : : &SbiRuntime::StepLT,
91 : : &SbiRuntime::StepGT,
92 : : &SbiRuntime::StepLE,
93 : : &SbiRuntime::StepGE,
94 : : &SbiRuntime::StepIDIV,
95 : : &SbiRuntime::StepAND,
96 : : &SbiRuntime::StepOR,
97 : : &SbiRuntime::StepXOR,
98 : : &SbiRuntime::StepEQV,
99 : : &SbiRuntime::StepIMP,
100 : : &SbiRuntime::StepNOT,
101 : : &SbiRuntime::StepCAT,
102 : :
103 : : &SbiRuntime::StepLIKE,
104 : : &SbiRuntime::StepIS,
105 : : // load/save
106 : : &SbiRuntime::StepARGC, // establish new Argv
107 : : &SbiRuntime::StepARGV, // TOS ==> current Argv
108 : : &SbiRuntime::StepINPUT, // Input ==> TOS
109 : : &SbiRuntime::StepLINPUT, // Line Input ==> TOS
110 : : &SbiRuntime::StepGET, // touch TOS
111 : : &SbiRuntime::StepSET, // save object TOS ==> TOS-1
112 : : &SbiRuntime::StepPUT, // TOS ==> TOS-1
113 : : &SbiRuntime::StepPUTC, // TOS ==> TOS-1, then ReadOnly
114 : : &SbiRuntime::StepDIM, // DIM
115 : : &SbiRuntime::StepREDIM, // REDIM
116 : : &SbiRuntime::StepREDIMP, // REDIM PRESERVE
117 : : &SbiRuntime::StepERASE, // delete TOS
118 : : // branch
119 : : &SbiRuntime::StepSTOP, // program end
120 : : &SbiRuntime::StepINITFOR, // intitialize FOR-Variable
121 : : &SbiRuntime::StepNEXT, // increment FOR-Variable
122 : : &SbiRuntime::StepCASE, // beginning CASE
123 : : &SbiRuntime::StepENDCASE, // end CASE
124 : : &SbiRuntime::StepSTDERROR, // standard error handling
125 : : &SbiRuntime::StepNOERROR, // no error handling
126 : : &SbiRuntime::StepLEAVE, // leave UP
127 : : // E/A
128 : : &SbiRuntime::StepCHANNEL, // TOS = channel number
129 : : &SbiRuntime::StepPRINT, // print TOS
130 : : &SbiRuntime::StepPRINTF, // print TOS in field
131 : : &SbiRuntime::StepWRITE, // write TOS
132 : : &SbiRuntime::StepRENAME, // Rename Tos+1 to Tos
133 : : &SbiRuntime::StepPROMPT, // define Input Prompt from TOS
134 : : &SbiRuntime::StepRESTART, // Set restart point
135 : : &SbiRuntime::StepCHANNEL0, // set E/A-channel 0
136 : : &SbiRuntime::StepEMPTY, // empty expression on stack
137 : : &SbiRuntime::StepERROR, // TOS = error code
138 : : &SbiRuntime::StepLSET, // save object TOS ==> TOS-1
139 : : &SbiRuntime::StepRSET, // save object TOS ==> TOS-1
140 : : &SbiRuntime::StepREDIMP_ERASE,// Copy array object for REDIMP
141 : : &SbiRuntime::StepINITFOREACH,// Init for each loop
142 : : &SbiRuntime::StepVBASET,// vba-like set statement
143 : : &SbiRuntime::StepERASE_CLEAR,// vba-like set statement
144 : : &SbiRuntime::StepARRAYACCESS,// access TOS as array
145 : : &SbiRuntime::StepBYVAL, // access TOS as array
146 : : };
147 : :
148 : : SbiRuntime::pStep1 SbiRuntime::aStep1[] = { // all opcodes with one operand
149 : : &SbiRuntime::StepLOADNC, // loading a numeric constant (+ID)
150 : : &SbiRuntime::StepLOADSC, // loading a string constant (+ID)
151 : : &SbiRuntime::StepLOADI, // Immediate Load (+Wert)
152 : : &SbiRuntime::StepARGN, // save a named Args in Argv (+StringID)
153 : : &SbiRuntime::StepPAD, // bring string to a definite length (+length)
154 : : // branches
155 : : &SbiRuntime::StepJUMP, // jump (+Target)
156 : : &SbiRuntime::StepJUMPT, // evaluate TOS, conditional jump (+Target)
157 : : &SbiRuntime::StepJUMPF, // evaluate TOS, conditional jump (+Target)
158 : : &SbiRuntime::StepONJUMP, // evaluate TOS, jump into JUMP-table (+MaxVal)
159 : : &SbiRuntime::StepGOSUB, // UP-call (+Target)
160 : : &SbiRuntime::StepRETURN, // UP-return (+0 or Target)
161 : : &SbiRuntime::StepTESTFOR, // check FOR-variable, increment (+Endlabel)
162 : : &SbiRuntime::StepCASETO, // Tos+1 <= Case <= Tos), 2xremove (+Target)
163 : : &SbiRuntime::StepERRHDL, // error handler (+Offset)
164 : : &SbiRuntime::StepRESUME, // resume after errors (+0 or 1 or Label)
165 : : // E/A
166 : : &SbiRuntime::StepCLOSE, // (+channel/0)
167 : : &SbiRuntime::StepPRCHAR, // (+char)
168 : : // management
169 : : &SbiRuntime::StepSETCLASS, // check set + class names (+StringId)
170 : : &SbiRuntime::StepTESTCLASS, // Check TOS class (+StringId)
171 : : &SbiRuntime::StepLIB, // lib for declare-call (+StringId)
172 : : &SbiRuntime::StepBASED, // TOS is incremented by BASE, BASE is pushed before
173 : : &SbiRuntime::StepARGTYP, // convert last parameter in Argv (+Type)
174 : : &SbiRuntime::StepVBASETCLASS,// vba-like set statement
175 : : };
176 : :
177 : : SbiRuntime::pStep2 SbiRuntime::aStep2[] = {// all opcodes with two operands
178 : : &SbiRuntime::StepRTL, // load from RTL (+StringID+Typ)
179 : : &SbiRuntime::StepFIND, // load (+StringID+Typ)
180 : : &SbiRuntime::StepELEM, // load element (+StringID+Typ)
181 : : &SbiRuntime::StepPARAM, // Parameter (+Offset+Typ)
182 : : // Verzweigen
183 : : &SbiRuntime::StepCALL, // Declare-Call (+StringID+Typ)
184 : : &SbiRuntime::StepCALLC, // CDecl-Declare-Call (+StringID+Typ)
185 : : &SbiRuntime::StepCASEIS, // Case-Test (+Test-Opcode+False-Target)
186 : : // Verwaltung
187 : : &SbiRuntime::StepSTMNT, // beginning of a statement (+Line+Col)
188 : : // E/A
189 : : &SbiRuntime::StepOPEN, // (+SvStreamFlags+Flags)
190 : : // Objects
191 : : &SbiRuntime::StepLOCAL, // define local variable (+StringId+Typ)
192 : : &SbiRuntime::StepPUBLIC, // module global variable (+StringID+Typ)
193 : : &SbiRuntime::StepGLOBAL, // define global variable (+StringID+Typ)
194 : : &SbiRuntime::StepCREATE, // create object (+StringId+StringId)
195 : : &SbiRuntime::StepSTATIC, // static variable (+StringId+StringId)
196 : : &SbiRuntime::StepTCREATE, // user-defined objects (+StringId+StringId)
197 : : &SbiRuntime::StepDCREATE, // create object-array (+StringID+StringID)
198 : : &SbiRuntime::StepGLOBAL_P, // define global variable which is not overwritten
199 : : // by the Basic on a restart (+StringID+Typ)
200 : : &SbiRuntime::StepFIND_G, // finds global variable with special treatment because of _GLOBAL_P
201 : : &SbiRuntime::StepDCREATE_REDIMP, // redimension object array (+StringID+StringID)
202 : : &SbiRuntime::StepFIND_CM, // Search inside a class module (CM) to enable global search in time
203 : : &SbiRuntime::StepPUBLIC_P, // Search inside a class module (CM) to enable global search in time
204 : : &SbiRuntime::StepFIND_STATIC, // Search inside a class module (CM) to enable global search in time
205 : : };
206 : :
207 : :
208 : : // SbiRTLData //
209 : :
210 [ + - ]: 31 : SbiRTLData::SbiRTLData()
211 : : {
212 : 31 : pDir = 0;
213 : 31 : nDirFlags = 0;
214 : 31 : nCurDirPos = 0;
215 : 31 : pWildCard = NULL;
216 : 31 : }
217 : :
218 [ + - ]: 31 : SbiRTLData::~SbiRTLData()
219 : : {
220 [ - + ][ # # ]: 31 : delete pDir;
221 : 31 : pDir = 0;
222 [ - + ][ # # ]: 31 : delete pWildCard;
223 : 31 : }
224 : :
225 : : // SbiInstance //
226 : :
227 : : // 16.10.96: #31460 new concept for StepInto/Over/Out
228 : : // The decision whether StepPoint shall be called is done with the help of
229 : : // the CallLevel. It's stopped when the current CallLevel is <= nBreakCallLvl.
230 : : // The current CallLevel can never be smaller than 1, as it's also incremented
231 : : // during the call of a method (also main). Therefore a BreakCallLvl from 0
232 : : // means that the program isn't stopped at all.
233 : : // (also have a look at: step2.cxx, SbiRuntime::StepSTMNT() )
234 : :
235 : :
236 : 31 : void SbiInstance::CalcBreakCallLevel( sal_uInt16 nFlags )
237 : : {
238 : :
239 : 31 : nFlags &= ~((sal_uInt16)SbDEBUG_BREAK);
240 : :
241 : : sal_uInt16 nRet;
242 [ - - - + ]: 31 : switch( nFlags )
243 : : {
244 : : case SbDEBUG_STEPINTO:
245 : 0 : nRet = nCallLvl + 1; // CallLevel+1 is also stopped
246 : 0 : break;
247 : : case SbDEBUG_STEPOVER | SbDEBUG_STEPINTO:
248 : 0 : nRet = nCallLvl; // current CallLevel is stopped
249 : 0 : break;
250 : : case SbDEBUG_STEPOUT:
251 : 0 : nRet = nCallLvl - 1; // smaller CallLevel is stopped
252 : 0 : break;
253 : : case SbDEBUG_CONTINUE:
254 : : // Basic-IDE returns 0 instead of SbDEBUG_CONTINUE, so also default=continue
255 : : default:
256 : 31 : nRet = 0; // CallLevel is always > 0 -> no StepPoint
257 : : }
258 : 31 : nBreakCallLvl = nRet; // take result
259 : 31 : }
260 : :
261 [ + - ][ + - ]: 31 : SbiInstance::SbiInstance( StarBASIC* p )
262 : : {
263 : 31 : pBasic = p;
264 : 31 : pNext = NULL;
265 : 31 : pRun = NULL;
266 [ + - ][ + - ]: 31 : pIosys = new SbiIoSystem;
267 [ + - ][ + - ]: 31 : pDdeCtrl = new SbiDdeControl;
268 : 31 : pDllMgr = 0; // on demand
269 : 31 : pNumberFormatter = 0; // on demand
270 : 31 : nCallLvl = 0;
271 : 31 : nBreakCallLvl = 0;
272 : : nErr =
273 : 31 : nErl = 0;
274 : 31 : bReschedule = sal_True;
275 : 31 : bCompatibility = sal_False;
276 : 31 : }
277 : :
278 [ + - ]: 31 : SbiInstance::~SbiInstance()
279 : : {
280 [ - + ]: 31 : while( pRun )
281 : : {
282 : 0 : SbiRuntime* p = pRun->pNext;
283 [ # # ][ # # ]: 0 : delete pRun;
284 : 0 : pRun = p;
285 : : }
286 [ + - ][ + - ]: 31 : delete pIosys;
287 [ + - ][ + - ]: 31 : delete pDdeCtrl;
288 [ - + ][ # # ]: 31 : delete pDllMgr;
289 [ - + ][ # # ]: 31 : delete pNumberFormatter;
290 : :
291 : : try
292 : : {
293 : 31 : int nSize = ComponentVector.size();
294 [ - + ]: 31 : if( nSize )
295 : : {
296 [ # # ]: 0 : for( int i = nSize - 1 ; i >= 0 ; --i )
297 : : {
298 : 0 : Reference< XComponent > xDlgComponent = ComponentVector[i];
299 [ # # ]: 0 : if( xDlgComponent.is() )
300 [ # # ][ # # ]: 0 : xDlgComponent->dispose();
301 [ # # ]: 0 : }
302 : : }
303 : : }
304 [ # # ]: 0 : catch( const Exception& )
305 : : {
306 : : OSL_FAIL( "SbiInstance::~SbiInstance: caught an exception while disposing the components!" );
307 : : }
308 : :
309 : 31 : ComponentVector.clear();
310 : 31 : }
311 : :
312 : 0 : SbiDllMgr* SbiInstance::GetDllMgr()
313 : : {
314 [ # # ]: 0 : if( !pDllMgr )
315 [ # # ]: 0 : pDllMgr = new SbiDllMgr;
316 : 0 : return pDllMgr;
317 : : }
318 : :
319 : : // #39629 create NumberFormatter with the help of a static method now
320 : 0 : SvNumberFormatter* SbiInstance::GetNumberFormatter()
321 : : {
322 [ # # ][ # # ]: 0 : LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
[ # # ]
323 [ # # ]: 0 : SvtSysLocale aSysLocale;
324 [ # # ][ # # ]: 0 : DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
325 [ # # ]: 0 : if( pNumberFormatter )
326 : : {
327 [ # # ][ # # ]: 0 : if( eLangType != meFormatterLangType ||
328 : : eDate != meFormatterDateFormat )
329 : : {
330 [ # # ][ # # ]: 0 : delete pNumberFormatter;
331 : 0 : pNumberFormatter = NULL;
332 : : }
333 : : }
334 : 0 : meFormatterLangType = eLangType;
335 : 0 : meFormatterDateFormat = eDate;
336 [ # # ]: 0 : if( !pNumberFormatter )
337 : : PrepareNumberFormatter( pNumberFormatter, nStdDateIdx, nStdTimeIdx, nStdDateTimeIdx,
338 [ # # ]: 0 : &meFormatterLangType, &meFormatterDateFormat );
339 [ # # ]: 0 : return pNumberFormatter;
340 : : }
341 : :
342 : : // #39629 offer NumberFormatter static too
343 : 0 : void SbiInstance::PrepareNumberFormatter( SvNumberFormatter*& rpNumberFormatter,
344 : : sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx,
345 : : LanguageType* peFormatterLangType, DateFormat* peFormatterDateFormat )
346 : : {
347 : : com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
348 [ # # ]: 0 : xFactory = comphelper::getProcessServiceFactory();
349 : :
350 : : LanguageType eLangType;
351 [ # # ]: 0 : if( peFormatterLangType )
352 : 0 : eLangType = *peFormatterLangType;
353 : : else
354 [ # # ][ # # ]: 0 : eLangType = GetpApp()->GetSettings().GetLanguage();
[ # # ]
355 : :
356 : : DateFormat eDate;
357 [ # # ]: 0 : if( peFormatterDateFormat )
358 : 0 : eDate = *peFormatterDateFormat;
359 : : else
360 : : {
361 [ # # ]: 0 : SvtSysLocale aSysLocale;
362 [ # # ][ # # ]: 0 : eDate = aSysLocale.GetLocaleData().getDateFormat();
[ # # ]
363 : : }
364 : :
365 [ # # ][ # # ]: 0 : rpNumberFormatter = new SvNumberFormatter( xFactory, eLangType );
366 : :
367 : 0 : xub_StrLen nCheckPos = 0; short nType;
368 [ # # ]: 0 : rnStdTimeIdx = rpNumberFormatter->GetStandardFormat( NUMBERFORMAT_TIME, eLangType );
369 : :
370 : : // the formatter's standard templates have only got a two-digit date
371 : : // -> registering an own format
372 : :
373 : : // HACK, beause the numberformatter doesn't swap the place holders
374 : : // for month, day and year according to the system setting.
375 : : // Problem: Print Year(Date) under engl. BS
376 : : // also have a look at: svtools\source\sbx\sbxdate.cxx
377 : :
378 [ # # ]: 0 : String aDateStr;
379 [ # # # # ]: 0 : switch( eDate )
380 : : {
381 [ # # ][ # # ]: 0 : case MDY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") ); break;
[ # # ]
382 [ # # ][ # # ]: 0 : case DMY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("TT.MM.JJJJ") ); break;
[ # # ]
383 [ # # ][ # # ]: 0 : case YMD: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("JJJJ.MM.TT") ); break;
[ # # ]
384 [ # # ][ # # ]: 0 : default: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") );
[ # # ]
385 : : }
386 [ # # ]: 0 : String aStr( aDateStr );
387 : : rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
388 [ # # ]: 0 : rnStdDateIdx, LANGUAGE_GERMAN, eLangType );
389 : 0 : nCheckPos = 0;
390 [ # # ]: 0 : String aStrHHMMSS( RTL_CONSTASCII_USTRINGPARAM(" HH:MM:SS") );
391 [ # # ]: 0 : aStr = aDateStr;
392 [ # # ]: 0 : aStr += aStrHHMMSS;
393 : : rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
394 [ # # ][ # # ]: 0 : rnStdDateTimeIdx, LANGUAGE_GERMAN, eLangType );
[ # # ][ # # ]
395 : 0 : }
396 : :
397 : :
398 : :
399 : : // Let engine run. If Flags == SbDEBUG_CONTINUE, take Flags over
400 : :
401 : 0 : void SbiInstance::Stop()
402 : : {
403 [ # # ]: 0 : for( SbiRuntime* p = pRun; p; p = p->pNext )
404 : 0 : p->Stop();
405 : 0 : }
406 : :
407 : : // Allows Basic IDE to set watch mode to suppress errors
408 : : static bool bWatchMode = false;
409 : :
410 : 0 : void setBasicWatchMode( bool bOn )
411 : : {
412 : 0 : bWatchMode = bOn;
413 : 0 : }
414 : :
415 : 0 : void SbiInstance::Error( SbError n )
416 : : {
417 [ # # ]: 0 : Error( n, String() );
418 : 0 : }
419 : :
420 : 4 : void SbiInstance::Error( SbError n, const String& rMsg )
421 : : {
422 [ + - ]: 4 : if( !bWatchMode )
423 : : {
424 : 4 : aErrorMsg = rMsg;
425 : 4 : pRun->Error( n );
426 : : }
427 : 4 : }
428 : :
429 : 0 : void SbiInstance::ErrorVB( sal_Int32 nVBNumber, const String& rMsg )
430 : : {
431 [ # # ]: 0 : if( !bWatchMode )
432 : : {
433 : 0 : SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
434 [ # # ]: 0 : if ( !n )
435 : 0 : n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
436 : :
437 : 0 : aErrorMsg = rMsg;
438 : 0 : SbiRuntime::translateErrorToVba( n, aErrorMsg );
439 : :
440 : 0 : bool bVBATranslationAlreadyDone = true;
441 : 0 : pRun->Error( SbERR_BASIC_COMPAT, bVBATranslationAlreadyDone );
442 : : }
443 : 0 : }
444 : :
445 : 0 : void SbiInstance::setErrorVB( sal_Int32 nVBNumber, const String& rMsg )
446 : : {
447 : 0 : SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
448 [ # # ]: 0 : if( !n )
449 : 0 : n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
450 : :
451 : 0 : aErrorMsg = rMsg;
452 : 0 : SbiRuntime::translateErrorToVba( n, aErrorMsg );
453 : :
454 : 0 : nErr = n;
455 : 0 : }
456 : :
457 : :
458 : 0 : void SbiInstance::FatalError( SbError n )
459 : : {
460 : 0 : pRun->FatalError( n );
461 : 0 : }
462 : :
463 : 0 : void SbiInstance::FatalError( SbError _errCode, const String& _details )
464 : : {
465 : 0 : pRun->FatalError( _errCode, _details );
466 : 0 : }
467 : :
468 : 0 : void SbiInstance::Abort()
469 : : {
470 : 0 : StarBASIC* pErrBasic = GetCurrentBasic( pBasic );
471 : 0 : pErrBasic->RTError( nErr, aErrorMsg, pRun->nLine, pRun->nCol1, pRun->nCol2 );
472 : 0 : pBasic->Stop();
473 : 0 : }
474 : :
475 : : // can be unequal to pRTBasic
476 : 0 : StarBASIC* GetCurrentBasic( StarBASIC* pRTBasic )
477 : : {
478 : 0 : StarBASIC* pCurBasic = pRTBasic;
479 : 0 : SbModule* pActiveModule = pRTBasic->GetActiveModule();
480 [ # # ]: 0 : if( pActiveModule )
481 : : {
482 : 0 : SbxObject* pParent = pActiveModule->GetParent();
483 [ # # ][ # # ]: 0 : if( pParent && pParent->ISA(StarBASIC) )
[ # # ]
484 : 0 : pCurBasic = (StarBASIC*)pParent;
485 : : }
486 : 0 : return pCurBasic;
487 : : }
488 : :
489 : 0 : SbModule* SbiInstance::GetActiveModule()
490 : : {
491 [ # # ]: 0 : if( pRun )
492 : 0 : return pRun->GetModule();
493 : : else
494 : 0 : return NULL;
495 : : }
496 : :
497 : 0 : SbMethod* SbiInstance::GetCaller( sal_uInt16 nLevel )
498 : : {
499 : 0 : SbiRuntime* p = pRun;
500 [ # # ][ # # ]: 0 : while( nLevel-- && p )
[ # # ]
501 : 0 : p = p->pNext;
502 [ # # ]: 0 : if( p )
503 : 0 : return p->GetCaller();
504 : : else
505 : 0 : return NULL;
506 : : }
507 : :
508 : : // SbiInstance //
509 : :
510 : : // Attention: pMeth can also be NULL (on a call of the init-code)
511 : :
512 : 921 : SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, sal_uInt32 nStart )
513 : 921 : : rBasic( *(StarBASIC*)pm->pParent ), pInst( GetSbData()->pInst ),
514 [ + - ]: 921 : pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), mpExtCaller(0), m_nLastTime(0)
515 : : {
516 [ + + ]: 921 : nFlags = pe ? pe->GetDebugFlags() : 0;
517 : 921 : pIosys = pInst->pIosys;
518 : 921 : pArgvStk = NULL;
519 : 921 : pGosubStk = NULL;
520 : 921 : pForStk = NULL;
521 : 921 : pError = NULL;
522 : : pErrCode =
523 : : pErrStmnt =
524 : 921 : pRestart = NULL;
525 : 921 : pNext = NULL;
526 : : pCode =
527 : 921 : pStmnt = (const sal_uInt8* ) pImg->GetCode() + nStart;
528 : : bRun =
529 : 921 : bError = true;
530 : 921 : bInError = false;
531 : 921 : bBlocked = false;
532 : 921 : nLine = 0;
533 : 921 : nCol1 = 0;
534 : 921 : nCol2 = 0;
535 : 921 : nExprLvl = 0;
536 : 921 : nArgc = 0;
537 : 921 : nError = 0;
538 : 921 : nGosubLvl = 0;
539 : 921 : nForLvl = 0;
540 : 921 : nOps = 0;
541 [ + - ][ + - ]: 921 : refExprStk = new SbxArray;
[ + - ]
542 [ + - ]: 921 : SetVBAEnabled( pMod->IsVBACompat() );
543 : : #if defined GCC
544 [ + - ][ + - ]: 921 : SetParameters( pe ? pe->GetParameters() : (class SbxArray *)NULL );
[ + + ]
545 : : #else
546 : : SetParameters( pe ? pe->GetParameters() : NULL );
547 : : #endif
548 : 921 : pRefSaveList = NULL;
549 : 921 : pItemStoreList = NULL;
550 : 921 : }
551 : :
552 [ + - ][ + - ]: 921 : SbiRuntime::~SbiRuntime()
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
553 : : {
554 : 921 : ClearGosubStack();
555 [ + - ]: 921 : ClearArgvStack();
556 [ + - ]: 921 : ClearForStack();
557 : :
558 : : // #74254 free items for saving temporary references
559 [ + - ]: 921 : ClearRefs();
560 [ + + ]: 1151 : while( pItemStoreList )
561 : : {
562 : 230 : RefSaveItem* pToDeleteItem = pItemStoreList;
563 : 230 : pItemStoreList = pToDeleteItem->pNext;
564 [ + - ][ + - ]: 230 : delete pToDeleteItem;
565 : : }
566 : 921 : }
567 : :
568 : 921 : void SbiRuntime::SetVBAEnabled(bool bEnabled )
569 : : {
570 : 921 : bVBAEnabled = bEnabled;
571 [ + + ]: 921 : if ( bVBAEnabled )
572 : : {
573 [ + + ]: 120 : if ( pMeth )
574 : 118 : mpExtCaller = pMeth->mCaller;
575 : : }
576 : : else
577 : 801 : mpExtCaller = 0;
578 : 921 : }
579 : :
580 : : // Construction of the parameter list. All ByRef-parameters are directly
581 : : // taken over; copies of ByVal-parameters are created. If a particular
582 : : // data type is requested, it is converted.
583 : :
584 : 921 : void SbiRuntime::SetParameters( SbxArray* pParams )
585 : : {
586 [ + - ]: 921 : refParams = new SbxArray;
587 : : // for the return value
588 : 921 : refParams->Put( pMeth, 0 );
589 : :
590 [ + + ]: 921 : SbxInfo* pInfo = pMeth ? pMeth->GetInfo() : NULL;
591 [ + + ]: 921 : sal_uInt16 nParamCount = pParams ? pParams->Count() : 1;
592 [ + + ]: 921 : if( nParamCount > 1 )
593 : : {
594 [ + + ]: 2406 : for( sal_uInt16 i = 1 ; i < nParamCount ; i++ )
595 : : {
596 [ + - ]: 1598 : const SbxParamInfo* p = pInfo ? pInfo->GetParam( i ) : NULL;
597 : :
598 : : // #111897 ParamArray
599 [ + + ][ - + ]: 1598 : if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
600 : : {
601 [ # # ]: 0 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
602 : 0 : sal_uInt16 nParamArrayParamCount = nParamCount - i;
603 : 0 : pArray->unoAddDim( 0, nParamArrayParamCount - 1 );
604 [ # # ]: 0 : for( sal_uInt16 j = i ; j < nParamCount ; j++ )
605 : : {
606 [ # # ]: 0 : SbxVariable* v = pParams->Get( j );
607 : 0 : short nDimIndex = j - i;
608 [ # # ]: 0 : pArray->Put( v, &nDimIndex );
609 : : }
610 [ # # ]: 0 : SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
611 : 0 : pArrayVar->SetFlag( SBX_READWRITE );
612 : 0 : pArrayVar->PutObject( pArray );
613 : 0 : refParams->Put( pArrayVar, i );
614 : :
615 : : // Block ParamArray for missing parameter
616 : 0 : pInfo = NULL;
617 : 0 : break;
618 : : }
619 : :
620 : 1598 : SbxVariable* v = pParams->Get( i );
621 : : // methods are always byval!
622 : 1598 : sal_Bool bByVal = v->IsA( TYPE(SbxMethod) );
623 : 1598 : SbxDataType t = v->GetType();
624 : 1598 : bool bTargetTypeIsArray = false;
625 [ + + ]: 1598 : if( p )
626 : : {
627 : 1530 : bByVal |= sal_Bool( ( p->eType & SbxBYREF ) == 0 );
628 : 1530 : t = (SbxDataType) ( p->eType & 0x0FFF );
629 : :
630 [ + - ][ + - : 4032 : if( !bByVal && t != SbxVARIANT &&
+ + - + ]
[ + + ]
631 : 2502 : (!v->IsFixed() || (SbxDataType)(v->GetType() & 0x0FFF ) != t) )
632 : 558 : bByVal = sal_True;
633 : :
634 : 1530 : bTargetTypeIsArray = (p->nUserData & PARAM_INFO_WITHBRACKETS) != 0;
635 : : }
636 [ + + ]: 1598 : if( bByVal )
637 : : {
638 [ - + ]: 558 : if( bTargetTypeIsArray )
639 : 0 : t = SbxOBJECT;
640 [ + - ]: 558 : SbxVariable* v2 = new SbxVariable( t );
641 : 558 : v2->SetFlag( SBX_READWRITE );
642 : 558 : *v2 = *v;
643 : 558 : refParams->Put( v2, i );
644 : : }
645 : : else
646 : : {
647 [ + - ][ - + ]: 1040 : if( t != SbxVARIANT && t != ( v->GetType() & 0x0FFF ) )
[ - + ]
648 : : {
649 [ # # ][ # # ]: 0 : if( p && (p->eType & SbxARRAY) )
650 : 0 : Error( SbERR_CONVERSION );
651 : : else
652 : 0 : v->Convert( t );
653 : : }
654 : 1040 : refParams->Put( v, i );
655 : : }
656 [ + + ]: 1598 : if( p )
657 : 1530 : refParams->PutAlias( p->aName, i );
658 : : }
659 : : }
660 : :
661 : : // ParamArray for missing parameter
662 [ + + ]: 921 : if( pInfo )
663 : : {
664 : : // #111897 Check first missing parameter for ParamArray
665 : 913 : const SbxParamInfo* p = pInfo->GetParam( nParamCount );
666 [ # # ][ - + ]: 913 : if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
667 : : {
668 [ # # ]: 0 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
669 : 0 : pArray->unoAddDim( 0, -1 );
670 [ # # ]: 0 : SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
671 : 0 : pArrayVar->SetFlag( SBX_READWRITE );
672 : 0 : pArrayVar->PutObject( pArray );
673 : 0 : refParams->Put( pArrayVar, nParamCount );
674 : : }
675 : : }
676 : 921 : }
677 : :
678 : :
679 : : // execute a P-Code
680 : :
681 : 53180 : bool SbiRuntime::Step()
682 : : {
683 [ + - ]: 53180 : if( bRun )
684 : : {
685 : : // in any case check casually!
686 [ + + ][ + - ]: 53180 : if( !( ++nOps & 0xF ) && pInst->IsReschedule() )
[ + + ]
687 : : {
688 : 2982 : sal_uInt32 nTime = osl_getGlobalTimer();
689 [ + + ]: 2982 : if (nTime - m_nLastTime > 5 ) // 20 ms
690 : : {
691 : 1284 : Application::Reschedule();
692 : 1284 : m_nLastTime = nTime;
693 : : }
694 : : }
695 : :
696 : : // #i48868 blocked by next call level?
697 [ - + ]: 53180 : while( bBlocked )
698 : : {
699 [ # # ]: 0 : if( pInst->IsReschedule() )
700 : 0 : Application::Reschedule();
701 : : }
702 : :
703 : 53180 : SbiOpcode eOp = (SbiOpcode ) ( *pCode++ );
704 : : sal_uInt32 nOp1, nOp2;
705 [ + + ]: 53180 : if (eOp < SbOP0_END)
706 : : {
707 [ + - ]: 16339 : (this->*( aStep0[ eOp ] ) )();
708 : : }
709 [ + - ][ + + ]: 36841 : else if (eOp >= SbOP1_START && eOp < SbOP1_END)
710 : : {
711 : 9010 : nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
712 : :
713 [ + - ]: 9010 : (this->*( aStep1[ eOp - SbOP1_START ] ) )( nOp1 );
714 : : }
715 [ + - ][ + - ]: 27831 : else if (eOp >= SbOP2_START && eOp < SbOP2_END)
716 : : {
717 : 27831 : nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
718 : 27831 : nOp2 = *pCode++; nOp2 |= *pCode++ << 8; nOp2 |= *pCode++ << 16; nOp2 |= *pCode++ << 24;
719 [ + - ]: 27831 : (this->*( aStep2[ eOp - SbOP2_START ] ) )( nOp1, nOp2 );
720 : : }
721 : : else
722 : 0 : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
723 : :
724 : :
725 : 53180 : SbError nSbError = SbxBase::GetError();
726 : 53180 : Error( ERRCODE_TOERROR(nSbError) );
727 : :
728 : : // from 13.2.1997, new error handling:
729 : : // ATTENTION: nError can be set already even if !nSbError
730 : : // since nError can now also be set from other RT-instances
731 : :
732 [ + + ]: 53180 : if( nError )
733 : 4 : SbxBase::ResetError();
734 : :
735 : : // from 15.3.96: display errors only if BASIC is still active
736 : : // (especially not after compiler errors at the runtime)
737 [ + + ][ + - ]: 53180 : if( nError && bRun )
738 : : {
739 : 4 : SbError err = nError;
740 : 4 : ClearExprStack();
741 : 4 : nError = 0;
742 : 4 : pInst->nErr = err;
743 : 4 : pInst->nErl = nLine;
744 : 4 : pErrCode = pCode;
745 : 4 : pErrStmnt = pStmnt;
746 : : // An error occurred in an error handler
747 : : // force parent handler ( if there is one )
748 : : // to handle the error
749 : 4 : bool bLetParentHandleThis = false;
750 : :
751 : : // in the error handler? so std-error
752 [ + - ]: 4 : if ( !bInError )
753 : : {
754 : 4 : bInError = true;
755 : :
756 [ - + ]: 4 : if( !bError ) // On Error Resume Next
757 : 0 : StepRESUME( 1 );
758 [ + - ]: 4 : else if( pError ) // On Error Goto ...
759 : 4 : pCode = pError;
760 : : else
761 : 0 : bLetParentHandleThis = true;
762 : : }
763 : : else
764 : : {
765 : 0 : bLetParentHandleThis = true;
766 : 0 : pError = NULL; //terminate the handler
767 : : }
768 [ - + ]: 4 : if ( bLetParentHandleThis )
769 : : {
770 : : // from 13.2.1997, new error handling:
771 : : // consider superior error handlers
772 : :
773 : : // there's no error handler -> find one farther above
774 : 0 : SbiRuntime* pRtErrHdl = NULL;
775 : 0 : SbiRuntime* pRt = this;
776 [ # # ]: 0 : while( NULL != (pRt = pRt->pNext) )
777 : : {
778 [ # # ][ # # ]: 0 : if( !pRt->bError || pRt->pError != NULL )
779 : : {
780 : 0 : pRtErrHdl = pRt;
781 : 0 : break;
782 : : }
783 : : }
784 : :
785 : :
786 [ # # ]: 0 : if( pRtErrHdl )
787 : : {
788 : : // manipulate all the RTs that are below in the call-stack
789 : 0 : pRt = this;
790 [ # # ]: 0 : do
791 : : {
792 : 0 : pRt->nError = err;
793 [ # # ]: 0 : if( pRt != pRtErrHdl )
794 : 0 : pRt->bRun = false;
795 : : else
796 : 0 : break;
797 : 0 : pRt = pRt->pNext;
798 : : }
799 : : while( pRt );
800 : : }
801 : : // no error-hdl found -> old behaviour
802 : : else
803 : : {
804 : 0 : pInst->Abort();
805 : : }
806 : :
807 : : }
808 : : }
809 : : }
810 : 53180 : return bRun;
811 : : }
812 : :
813 : 53802 : void SbiRuntime::Error( SbError n, bool bVBATranslationAlreadyDone )
814 : : {
815 [ + + ]: 53802 : if( n )
816 : : {
817 : 4 : nError = n;
818 [ + - ][ + - ]: 4 : if( isVBAEnabled() && !bVBATranslationAlreadyDone )
[ + - ]
819 : : {
820 [ + - ]: 4 : String aMsg = pInst->GetErrorMsg();
821 [ + - ]: 4 : sal_Int32 nVBAErrorNumber = translateErrorToVba( nError, aMsg );
822 [ + - ][ + - ]: 4 : SbxVariable* pSbxErrObjVar = SbxErrObject::getErrObject();
823 : 4 : SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pSbxErrObjVar );
824 [ + - ]: 4 : if( pGlobErr != NULL )
825 [ + - ][ + - ]: 4 : pGlobErr->setNumberAndDescription( nVBAErrorNumber, aMsg );
826 : :
827 [ + - ]: 4 : pInst->aErrorMsg = aMsg;
828 [ + - ]: 4 : nError = SbERR_BASIC_COMPAT;
829 : : }
830 : : }
831 : 53802 : }
832 : :
833 : 0 : void SbiRuntime::Error( SbError _errCode, const String& _details )
834 : : {
835 [ # # ]: 0 : if ( _errCode )
836 : : {
837 : : // Not correct for class module usage, remove for now
838 : : //OSL_ENSURE( pInst->pRun == this, "SbiRuntime::Error: can't propagate the error message details!" );
839 [ # # ]: 0 : if ( pInst->pRun == this )
840 : : {
841 : 0 : pInst->Error( _errCode, _details );
842 : : //OSL_POSTCOND( nError == _errCode, "SbiRuntime::Error: the instance is expecte to propagate the error code back to me!" );
843 : : }
844 : : else
845 : : {
846 : 0 : nError = _errCode;
847 : : }
848 : : }
849 : 0 : }
850 : :
851 : 0 : void SbiRuntime::FatalError( SbError n )
852 : : {
853 : 0 : StepSTDERROR();
854 : 0 : Error( n );
855 : 0 : }
856 : :
857 : 0 : void SbiRuntime::FatalError( SbError _errCode, const String& _details )
858 : : {
859 : 0 : StepSTDERROR();
860 : 0 : Error( _errCode, _details );
861 : 0 : }
862 : :
863 : 4 : sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, String& rMsg )
864 : : {
865 : : // If a message is defined use that ( in preference to
866 : : // the defined one for the error ) NB #TODO
867 : : // if there is an error defined it more than likely
868 : : // is not the one you want ( some are the same though )
869 : : // we really need a new vba compatible error list
870 [ - + ]: 4 : if ( !rMsg.Len() )
871 : : {
872 : : // TEST, has to be vb here always
873 : : #ifdef DBG_UTIL
874 : : SbError nTmp = StarBASIC::GetSfxFromVBError( (sal_uInt16)nError );
875 : : DBG_ASSERT( nTmp, "No VB error!" );
876 : : #endif
877 : :
878 [ # # ]: 0 : StarBASIC::MakeErrorText( nError, rMsg );
879 : 0 : rMsg = StarBASIC::GetErrorText();
880 [ # # ]: 0 : if ( !rMsg.Len() ) // no message for err no, need localized resource here
881 [ # # ]: 0 : rMsg = String( RTL_CONSTASCII_USTRINGPARAM("Internal Object Error:") );
882 : : }
883 : : // no num? most likely then it *is* really a vba err
884 : 4 : sal_uInt16 nVBErrorCode = StarBASIC::GetVBErrorCode( nError );
885 [ + - ]: 4 : sal_Int32 nVBAErrorNumber = ( nVBErrorCode == 0 ) ? nError : nVBErrorCode;
886 : 4 : return nVBAErrorNumber;
887 : : }
888 : :
889 : : // Parameter, Locals, Caller
890 : :
891 : 0 : SbMethod* SbiRuntime::GetCaller()
892 : : {
893 : 0 : return pMeth;
894 : : }
895 : :
896 : : // Stacks
897 : :
898 : : // The expression-stack is available for the continous evaluation
899 : : // of expressions.
900 : :
901 : 20344 : void SbiRuntime::PushVar( SbxVariable* pVar )
902 : : {
903 [ + - ]: 20344 : if( pVar )
904 : 20344 : refExprStk->Put( pVar, nExprLvl++ );
905 : 20344 : }
906 : :
907 : 20344 : SbxVariableRef SbiRuntime::PopVar()
908 : : {
909 : : #ifdef DBG_UTIL
910 : : if( !nExprLvl )
911 : : {
912 : : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
913 : : return new SbxVariable;
914 : : }
915 : : #endif
916 : 20344 : SbxVariableRef xVar = refExprStk->Get( --nExprLvl );
917 : : #ifdef DBG_UTIL
918 : : if ( xVar->GetName().EqualsAscii( "Cells" ) )
919 : : OSL_TRACE( "" );
920 : : #endif
921 : : // methods hold themselves in parameter 0
922 [ + - ][ + + ]: 20344 : if( xVar->IsA( TYPE(SbxMethod) ) )
[ + - ]
923 [ + - ]: 2325 : xVar->SetParameters(0);
924 : 20344 : return xVar;
925 : : }
926 : :
927 : 9758 : bool SbiRuntime::ClearExprStack()
928 : : {
929 : : // Attention: Clear() doesn't suffice as methods must be deleted
930 [ + + ]: 10194 : while ( nExprLvl )
931 : : {
932 : 436 : PopVar();
933 : : }
934 : 9758 : refExprStk->Clear();
935 : 9758 : return false;
936 : : }
937 : :
938 : : // Take variable from the expression-stack without removing it
939 : : // n counts from 0
940 : :
941 : 3287 : SbxVariable* SbiRuntime::GetTOS( short n )
942 : : {
943 : 3287 : n = nExprLvl - n - 1;
944 : : #ifdef DBG_UTIL
945 : : if( n < 0 )
946 : : {
947 : : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
948 : : return new SbxVariable;
949 : : }
950 : : #endif
951 : 3287 : return refExprStk->Get( (sal_uInt16) n );
952 : : }
953 : :
954 : :
955 : 2859 : void SbiRuntime::TOSMakeTemp()
956 : : {
957 : 2859 : SbxVariable* p = refExprStk->Get( nExprLvl - 1 );
958 [ - + ]: 2859 : if ( p->GetType() == SbxEMPTY )
959 : 0 : p->Broadcast( SBX_HINT_DATAWANTED );
960 : :
961 : 2859 : SbxVariable* pDflt = NULL;
962 [ + + ][ + - ]: 2859 : if ( bVBAEnabled && ( p->GetType() == SbxOBJECT || p->GetType() == SbxVARIANT ) && ((pDflt = getDefaultProp(p)) != NULL) )
[ - + ][ # # ]
[ - + ]
963 : : {
964 : 0 : pDflt->Broadcast( SBX_HINT_DATAWANTED );
965 : : // replacing new p on stack causes object pointed by
966 : : // pDft->pParent to be deleted, when p2->Compute() is
967 : : // called below pParent is accessed ( but its deleted )
968 : : // so set it to NULL now
969 : 0 : pDflt->SetParent( NULL );
970 [ # # ]: 0 : p = new SbxVariable( *pDflt );
971 : 0 : p->SetFlag( SBX_READWRITE );
972 : 0 : refExprStk->Put( p, nExprLvl - 1 );
973 : : }
974 : :
975 [ + + ]: 2859 : else if( p->GetRefCount() != 1 )
976 : : {
977 [ + - ]: 2525 : SbxVariable* pNew = new SbxVariable( *p );
978 : 2525 : pNew->SetFlag( SBX_READWRITE );
979 : 2525 : refExprStk->Put( pNew, nExprLvl - 1 );
980 : : }
981 : 2859 : }
982 : :
983 : : // the GOSUB-stack collects return-addresses for GOSUBs
984 : 0 : void SbiRuntime::PushGosub( const sal_uInt8* pc )
985 : : {
986 [ # # ]: 0 : if( ++nGosubLvl > MAXRECURSION )
987 : 0 : StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
988 : 0 : SbiGosubStack* p = new SbiGosubStack;
989 : 0 : p->pCode = pc;
990 : 0 : p->pNext = pGosubStk;
991 : 0 : p->nStartForLvl = nForLvl;
992 : 0 : pGosubStk = p;
993 : 0 : }
994 : :
995 : 0 : void SbiRuntime::PopGosub()
996 : : {
997 [ # # ]: 0 : if( !pGosubStk )
998 : 0 : Error( SbERR_NO_GOSUB );
999 : : else
1000 : : {
1001 : 0 : SbiGosubStack* p = pGosubStk;
1002 : 0 : pCode = p->pCode;
1003 : 0 : pGosubStk = p->pNext;
1004 : 0 : delete p;
1005 : 0 : nGosubLvl--;
1006 : : }
1007 : 0 : }
1008 : :
1009 : :
1010 : 921 : void SbiRuntime::ClearGosubStack()
1011 : : {
1012 : : SbiGosubStack* p;
1013 [ - + ]: 921 : while(( p = pGosubStk ) != NULL )
1014 : 0 : pGosubStk = p->pNext, delete p;
1015 : 921 : nGosubLvl = 0;
1016 : 921 : }
1017 : :
1018 : : // the Argv-stack collects current argument-vectors
1019 : :
1020 : 2518 : void SbiRuntime::PushArgv()
1021 : : {
1022 [ + - ]: 2518 : SbiArgvStack* p = new SbiArgvStack;
1023 : 2518 : p->refArgv = refArgv;
1024 : 2518 : p->nArgc = nArgc;
1025 : 2518 : nArgc = 1;
1026 : 2518 : refArgv.Clear();
1027 : 2518 : p->pNext = pArgvStk;
1028 : 2518 : pArgvStk = p;
1029 : 2518 : }
1030 : :
1031 : 2518 : void SbiRuntime::PopArgv()
1032 : : {
1033 [ + - ]: 2518 : if( pArgvStk )
1034 : : {
1035 : 2518 : SbiArgvStack* p = pArgvStk;
1036 : 2518 : pArgvStk = p->pNext;
1037 : 2518 : refArgv = p->refArgv;
1038 : 2518 : nArgc = p->nArgc;
1039 [ + - ]: 2518 : delete p;
1040 : : }
1041 : 2518 : }
1042 : :
1043 : :
1044 : 921 : void SbiRuntime::ClearArgvStack()
1045 : : {
1046 [ - + ]: 921 : while( pArgvStk )
1047 : 0 : PopArgv();
1048 : 921 : }
1049 : :
1050 : : // Push of the for-stack. The stack has increment, end, begin and variable.
1051 : : // After the creation of the stack-element the stack's empty.
1052 : :
1053 : 64 : void SbiRuntime::PushFor()
1054 : : {
1055 [ + - ][ + - ]: 64 : SbiForStack* p = new SbiForStack;
1056 : 64 : p->eForType = FOR_TO;
1057 : 64 : p->pNext = pForStk;
1058 : 64 : pForStk = p;
1059 : :
1060 [ + - ][ + - ]: 64 : p->refInc = PopVar();
[ + - ]
1061 [ + - ][ + - ]: 64 : p->refEnd = PopVar();
[ + - ]
1062 [ + - ]: 64 : SbxVariableRef xBgn = PopVar();
1063 [ + - ][ + - ]: 64 : p->refVar = PopVar();
[ + - ]
1064 [ + - ]: 64 : *(p->refVar) = *xBgn;
1065 [ + - ]: 64 : nForLvl++;
1066 : 64 : }
1067 : :
1068 : 0 : void SbiRuntime::PushForEach()
1069 : : {
1070 [ # # ][ # # ]: 0 : SbiForStack* p = new SbiForStack;
1071 : 0 : p->pNext = pForStk;
1072 : 0 : pForStk = p;
1073 : :
1074 [ # # ]: 0 : SbxVariableRef xObjVar = PopVar();
1075 [ # # ][ # # ]: 0 : SbxBase* pObj = xObjVar.Is() ? xObjVar->GetObject() : NULL;
1076 [ # # ]: 0 : if( pObj == NULL )
1077 : : {
1078 [ # # ]: 0 : Error( SbERR_NO_OBJECT );
1079 : : return;
1080 : : }
1081 : :
1082 : 0 : bool bError_ = false;
1083 : : BasicCollection* pCollection;
1084 : : SbxDimArray* pArray;
1085 : : SbUnoObject* pUnoObj;
1086 [ # # ][ # # ]: 0 : if( (pArray = PTR_CAST(SbxDimArray,pObj)) != NULL )
[ # # ][ # # ]
[ # # ]
1087 : : {
1088 : 0 : p->eForType = FOR_EACH_ARRAY;
1089 [ # # ]: 0 : p->refEnd = (SbxVariable*)pArray;
1090 : :
1091 [ # # ]: 0 : short nDims = pArray->GetDims();
1092 [ # # ]: 0 : p->pArrayLowerBounds = new sal_Int32[nDims];
1093 [ # # ]: 0 : p->pArrayUpperBounds = new sal_Int32[nDims];
1094 [ # # ]: 0 : p->pArrayCurIndices = new sal_Int32[nDims];
1095 : : sal_Int32 lBound, uBound;
1096 [ # # ]: 0 : for( short i = 0 ; i < nDims ; i++ )
1097 : : {
1098 [ # # ]: 0 : pArray->GetDim32( i+1, lBound, uBound );
1099 : 0 : p->pArrayCurIndices[i] = p->pArrayLowerBounds[i] = lBound;
1100 : 0 : p->pArrayUpperBounds[i] = uBound;
1101 : : }
1102 : : }
1103 [ # # ][ # # ]: 0 : else if( (pCollection = PTR_CAST(BasicCollection,pObj)) != NULL )
[ # # ][ # # ]
[ # # ]
1104 : : {
1105 : 0 : p->eForType = FOR_EACH_COLLECTION;
1106 [ # # ]: 0 : p->refEnd = pCollection;
1107 : 0 : p->nCurCollectionIndex = 0;
1108 : : }
1109 [ # # ][ # # ]: 0 : else if( (pUnoObj = PTR_CAST(SbUnoObject,pObj)) != NULL )
[ # # ][ # # ]
[ # # ]
1110 : : {
1111 : : // XEnumerationAccess?
1112 [ # # ]: 0 : Any aAny = pUnoObj->getUnoAny();
1113 : 0 : Reference< XEnumerationAccess > xEnumerationAccess;
1114 [ # # ][ # # ]: 0 : if( (aAny >>= xEnumerationAccess) )
1115 : : {
1116 [ # # ][ # # ]: 0 : p->xEnumeration = xEnumerationAccess->createEnumeration();
[ # # ]
1117 : 0 : p->eForType = FOR_EACH_XENUMERATION;
1118 : : }
1119 [ # # ][ # # ]: 0 : else if ( isVBAEnabled() && pUnoObj->isNativeCOMObject() )
[ # # ][ # # ]
1120 : : {
1121 : 0 : uno::Reference< script::XInvocation > xInvocation;
1122 [ # # ][ # # ]: 0 : if ( ( aAny >>= xInvocation ) && xInvocation.is() )
[ # # ][ # # ]
1123 : : {
1124 : : try
1125 : : {
1126 [ # # ][ # # ]: 0 : p->xEnumeration = new ComEnumerationWrapper( xInvocation );
[ # # # # ]
1127 : 0 : p->eForType = FOR_EACH_XENUMERATION;
1128 : : }
1129 [ # # ]: 0 : catch(const uno::Exception& )
1130 : : {}
1131 : : }
1132 : :
1133 [ # # ]: 0 : if ( !p->xEnumeration.is() )
1134 : 0 : bError_ = true;
1135 : : }
1136 : : else
1137 : : {
1138 : 0 : bError_ = true;
1139 : 0 : }
1140 : : }
1141 : : else
1142 : : {
1143 : 0 : bError_ = true;
1144 : : }
1145 : :
1146 [ # # ]: 0 : if( bError_ )
1147 : : {
1148 [ # # ]: 0 : Error( SbERR_CONVERSION );
1149 : : return;
1150 : : }
1151 : :
1152 : : // Container variable
1153 [ # # ][ # # ]: 0 : p->refVar = PopVar();
[ # # ]
1154 [ # # ][ # # ]: 0 : nForLvl++;
1155 : : }
1156 : :
1157 : :
1158 : 64 : void SbiRuntime::PopFor()
1159 : : {
1160 [ + - ]: 64 : if( pForStk )
1161 : : {
1162 : 64 : SbiForStack* p = pForStk;
1163 : 64 : pForStk = p->pNext;
1164 [ + - ]: 64 : delete p;
1165 : 64 : nForLvl--;
1166 : : }
1167 : 64 : }
1168 : :
1169 : :
1170 : 921 : void SbiRuntime::ClearForStack()
1171 : : {
1172 [ - + ]: 921 : while( pForStk )
1173 : 0 : PopFor();
1174 : 921 : }
1175 : :
1176 : 0 : SbiForStack* SbiRuntime::FindForStackItemForCollection( class BasicCollection* pCollection )
1177 : : {
1178 [ # # ]: 0 : for (SbiForStack *p = pForStk; p; p = p->pNext)
1179 : : {
1180 [ # # ]: 0 : SbxVariable* pVar = p->refEnd.Is() ? (SbxVariable*)p->refEnd : NULL;
1181 [ # # ][ # # ]: 0 : if( p->eForType == FOR_EACH_COLLECTION && pVar != NULL &&
[ # # # # ]
[ # # ][ # # ]
1182 : 0 : PTR_CAST(BasicCollection,pVar) == pCollection )
1183 : : {
1184 : 0 : return p;
1185 : : }
1186 : : }
1187 : :
1188 : 0 : return NULL;
1189 : : }
1190 : :
1191 : :
1192 : : //////////////////////////////////////////////////////////////////////////
1193 : : //
1194 : : // DLL-calls
1195 : :
1196 : 0 : void SbiRuntime::DllCall
1197 : : ( const String& aFuncName,
1198 : : const String& aDLLName,
1199 : : SbxArray* pArgs, // parameter (from index 1, can be NULL)
1200 : : SbxDataType eResType, // return value
1201 : : bool bCDecl ) // true: according to C-conventions
1202 : : {
1203 : : // No DllCall for "virtual" portal users
1204 [ # # ]: 0 : if( needSecurityRestrictions() )
1205 : : {
1206 : 0 : StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
1207 : 0 : return;
1208 : : }
1209 : :
1210 : : // NOT YET IMPLEMENTED
1211 : :
1212 [ # # ]: 0 : SbxVariable* pRes = new SbxVariable( eResType );
1213 : 0 : SbiDllMgr* pDllMgr = pInst->GetDllMgr();
1214 [ # # ][ # # ]: 0 : SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl );
1215 [ # # ]: 0 : if( nErr )
1216 : 0 : Error( nErr );
1217 : 0 : PushVar( pRes );
1218 : : }
1219 : :
1220 : 2 : sal_uInt16 SbiRuntime::GetImageFlag( sal_uInt16 n ) const
1221 : : {
1222 : 2 : return pImg->GetFlag( n );
1223 : : }
1224 : :
1225 : 0 : sal_uInt16 SbiRuntime::GetBase()
1226 : : {
1227 : 0 : return pImg->GetBase();
1228 : : }
1229 : :
1230 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|