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 89 : bool SbiRuntime::isVBAEnabled()
45 : {
46 89 : bool result = false;
47 89 : SbiInstance* pInst = GetSbData()->pInst;
48 89 : if ( pInst && GetSbData()->pInst->pRun )
49 72 : result = pInst->pRun->bVBAEnabled;
50 89 : return result;
51 : }
52 :
53 256 : void StarBASIC::SetVBAEnabled( bool bEnabled )
54 : {
55 256 : if ( bDocBasic )
56 : {
57 246 : bVBAEnabled = bEnabled;
58 : }
59 256 : }
60 :
61 23 : bool StarBASIC::isVBAEnabled()
62 : {
63 23 : if ( bDocBasic )
64 : {
65 15 : if( SbiRuntime::isVBAEnabled() )
66 0 : return true;
67 15 : return bVBAEnabled;
68 : }
69 8 : return false;
70 : }
71 :
72 :
73 4 : 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 7 : SbiRTLData::SbiRTLData()
211 : {
212 7 : pDir = 0;
213 7 : nDirFlags = 0;
214 7 : nCurDirPos = 0;
215 7 : pWildCard = NULL;
216 7 : }
217 :
218 14 : SbiRTLData::~SbiRTLData()
219 : {
220 7 : delete pDir;
221 7 : pDir = 0;
222 7 : delete pWildCard;
223 7 : }
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 7 : void SbiInstance::CalcBreakCallLevel( sal_uInt16 nFlags )
237 : {
238 :
239 7 : nFlags &= ~((sal_uInt16)SbDEBUG_BREAK);
240 :
241 : sal_uInt16 nRet;
242 7 : 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 7 : nRet = 0; // CallLevel is always > 0 -> no StepPoint
257 : }
258 7 : nBreakCallLvl = nRet; // take result
259 7 : }
260 :
261 7 : SbiInstance::SbiInstance( StarBASIC* p )
262 : {
263 7 : pBasic = p;
264 7 : pNext = NULL;
265 7 : pRun = NULL;
266 7 : pIosys = new SbiIoSystem;
267 7 : pDdeCtrl = new SbiDdeControl;
268 7 : pDllMgr = 0; // on demand
269 7 : pNumberFormatter = 0; // on demand
270 7 : nCallLvl = 0;
271 7 : nBreakCallLvl = 0;
272 : nErr =
273 7 : nErl = 0;
274 7 : bReschedule = sal_True;
275 7 : bCompatibility = sal_False;
276 7 : }
277 :
278 14 : SbiInstance::~SbiInstance()
279 : {
280 14 : while( pRun )
281 : {
282 0 : SbiRuntime* p = pRun->pNext;
283 0 : delete pRun;
284 0 : pRun = p;
285 : }
286 7 : delete pIosys;
287 7 : delete pDdeCtrl;
288 7 : delete pDllMgr;
289 7 : delete pNumberFormatter;
290 :
291 : try
292 : {
293 7 : int nSize = ComponentVector.size();
294 7 : 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 7 : ComponentVector.clear();
310 7 : }
311 :
312 0 : SbiDllMgr* SbiInstance::GetDllMgr()
313 : {
314 0 : if( !pDllMgr )
315 : {
316 0 : pDllMgr = new SbiDllMgr;
317 : }
318 0 : return pDllMgr;
319 : }
320 :
321 : // #39629 create NumberFormatter with the help of a static method now
322 0 : SvNumberFormatter* SbiInstance::GetNumberFormatter()
323 : {
324 0 : LanguageType eLangType = GetpApp()->GetSettings().GetLanguageTag().getLanguageType();
325 0 : SvtSysLocale aSysLocale;
326 0 : DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
327 0 : if( pNumberFormatter )
328 : {
329 0 : if( eLangType != meFormatterLangType ||
330 : eDate != meFormatterDateFormat )
331 : {
332 0 : delete pNumberFormatter;
333 0 : pNumberFormatter = NULL;
334 : }
335 : }
336 0 : meFormatterLangType = eLangType;
337 0 : meFormatterDateFormat = eDate;
338 0 : if( !pNumberFormatter )
339 : {
340 : PrepareNumberFormatter( pNumberFormatter, nStdDateIdx, nStdTimeIdx, nStdDateTimeIdx,
341 0 : &meFormatterLangType, &meFormatterDateFormat );
342 : }
343 0 : return pNumberFormatter;
344 : }
345 :
346 : // #39629 offer NumberFormatter static too
347 0 : void SbiInstance::PrepareNumberFormatter( SvNumberFormatter*& rpNumberFormatter,
348 : sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx,
349 : LanguageType* peFormatterLangType, DateFormat* peFormatterDateFormat )
350 : {
351 : com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
352 0 : xFactory = comphelper::getProcessServiceFactory();
353 :
354 : LanguageType eLangType;
355 0 : if( peFormatterLangType )
356 : {
357 0 : eLangType = *peFormatterLangType;
358 : }
359 : else
360 : {
361 0 : eLangType = GetpApp()->GetSettings().GetLanguageTag().getLanguageType();
362 : }
363 : DateFormat eDate;
364 0 : if( peFormatterDateFormat )
365 : {
366 0 : eDate = *peFormatterDateFormat;
367 : }
368 : else
369 : {
370 0 : SvtSysLocale aSysLocale;
371 0 : eDate = aSysLocale.GetLocaleData().getDateFormat();
372 : }
373 :
374 0 : rpNumberFormatter = new SvNumberFormatter( xFactory, eLangType );
375 :
376 0 : sal_Int32 nCheckPos = 0; short nType;
377 0 : rnStdTimeIdx = rpNumberFormatter->GetStandardFormat( NUMBERFORMAT_TIME, eLangType );
378 :
379 : // the formatter's standard templates have only got a two-digit date
380 : // -> registering an own format
381 :
382 : // HACK, beause the numberformatter doesn't swap the place holders
383 : // for month, day and year according to the system setting.
384 : // Problem: Print Year(Date) under engl. BS
385 : // also have a look at: svtools\source\sbx\sbxdate.cxx
386 :
387 0 : OUString aDateStr;
388 0 : switch( eDate )
389 : {
390 0 : case MDY: aDateStr = "MM.TT.JJJJ"; break;
391 0 : case DMY: aDateStr = "TT.MM.JJJJ"; break;
392 0 : case YMD: aDateStr = "JJJJ.MM.TT"; break;
393 0 : default: aDateStr = "MM.TT.JJJJ"; break;
394 : }
395 : rpNumberFormatter->PutandConvertEntry( aDateStr, nCheckPos, nType,
396 0 : rnStdDateIdx, LANGUAGE_GERMAN, eLangType );
397 0 : nCheckPos = 0;
398 0 : OUString aStrHHMMSS(" HH:MM:SS");
399 0 : aDateStr += aStrHHMMSS;
400 : rpNumberFormatter->PutandConvertEntry( aDateStr, nCheckPos, nType,
401 0 : rnStdDateTimeIdx, LANGUAGE_GERMAN, eLangType );
402 0 : }
403 :
404 :
405 : // Let engine run. If Flags == SbDEBUG_CONTINUE, take Flags over
406 :
407 0 : void SbiInstance::Stop()
408 : {
409 0 : for( SbiRuntime* p = pRun; p; p = p->pNext )
410 : {
411 0 : p->Stop();
412 : }
413 0 : }
414 :
415 : // Allows Basic IDE to set watch mode to suppress errors
416 : static bool bWatchMode = false;
417 :
418 0 : void setBasicWatchMode( bool bOn )
419 : {
420 0 : bWatchMode = bOn;
421 0 : }
422 :
423 0 : void SbiInstance::Error( SbError n )
424 : {
425 0 : Error( n, OUString() );
426 0 : }
427 :
428 0 : void SbiInstance::Error( SbError n, const OUString& rMsg )
429 : {
430 0 : if( !bWatchMode )
431 : {
432 0 : aErrorMsg = rMsg;
433 0 : pRun->Error( n );
434 : }
435 0 : }
436 :
437 0 : void SbiInstance::ErrorVB( sal_Int32 nVBNumber, const OUString& rMsg )
438 : {
439 0 : if( !bWatchMode )
440 : {
441 0 : SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
442 0 : if ( !n )
443 : {
444 0 : n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
445 : }
446 0 : aErrorMsg = rMsg;
447 0 : SbiRuntime::translateErrorToVba( n, aErrorMsg );
448 :
449 0 : bool bVBATranslationAlreadyDone = true;
450 0 : pRun->Error( SbERR_BASIC_COMPAT, bVBATranslationAlreadyDone );
451 : }
452 0 : }
453 :
454 0 : void SbiInstance::setErrorVB( sal_Int32 nVBNumber, const OUString& rMsg )
455 : {
456 0 : SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
457 0 : if( !n )
458 : {
459 0 : n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
460 : }
461 0 : aErrorMsg = rMsg;
462 0 : SbiRuntime::translateErrorToVba( n, aErrorMsg );
463 :
464 0 : nErr = n;
465 0 : }
466 :
467 :
468 0 : void SbiInstance::FatalError( SbError n )
469 : {
470 0 : pRun->FatalError( n );
471 0 : }
472 :
473 0 : void SbiInstance::FatalError( SbError _errCode, const OUString& _details )
474 : {
475 0 : pRun->FatalError( _errCode, _details );
476 0 : }
477 :
478 0 : void SbiInstance::Abort()
479 : {
480 0 : StarBASIC* pErrBasic = GetCurrentBasic( pBasic );
481 0 : pErrBasic->RTError( nErr, aErrorMsg, pRun->nLine, pRun->nCol1, pRun->nCol2 );
482 0 : pBasic->Stop();
483 0 : }
484 :
485 : // can be unequal to pRTBasic
486 0 : StarBASIC* GetCurrentBasic( StarBASIC* pRTBasic )
487 : {
488 0 : StarBASIC* pCurBasic = pRTBasic;
489 0 : SbModule* pActiveModule = pRTBasic->GetActiveModule();
490 0 : if( pActiveModule )
491 : {
492 0 : SbxObject* pParent = pActiveModule->GetParent();
493 0 : if( pParent && pParent->ISA(StarBASIC) )
494 : {
495 0 : pCurBasic = (StarBASIC*)pParent;
496 : }
497 : }
498 0 : return pCurBasic;
499 : }
500 :
501 0 : SbModule* SbiInstance::GetActiveModule()
502 : {
503 0 : if( pRun )
504 : {
505 0 : return pRun->GetModule();
506 : }
507 : else
508 : {
509 0 : return NULL;
510 : }
511 : }
512 :
513 0 : SbMethod* SbiInstance::GetCaller( sal_uInt16 nLevel )
514 : {
515 0 : SbiRuntime* p = pRun;
516 0 : while( nLevel-- && p )
517 : {
518 0 : p = p->pNext;
519 : }
520 0 : return p ? p->GetCaller() : NULL;
521 : }
522 :
523 : // SbiInstance //
524 :
525 : // Attention: pMeth can also be NULL (on a call of the init-code)
526 :
527 7 : SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, sal_uInt32 nStart )
528 7 : : rBasic( *(StarBASIC*)pm->pParent ), pInst( GetSbData()->pInst ),
529 14 : pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), mpExtCaller(0), m_nLastTime(0)
530 : {
531 7 : nFlags = pe ? pe->GetDebugFlags() : 0;
532 7 : pIosys = pInst->pIosys;
533 7 : pArgvStk = NULL;
534 7 : pGosubStk = NULL;
535 7 : pForStk = NULL;
536 7 : pError = NULL;
537 : pErrCode =
538 : pErrStmnt =
539 7 : pRestart = NULL;
540 7 : pNext = NULL;
541 : pCode =
542 7 : pStmnt = (const sal_uInt8* ) pImg->GetCode() + nStart;
543 : bRun =
544 7 : bError = true;
545 7 : bInError = false;
546 7 : bBlocked = false;
547 7 : nLine = 0;
548 7 : nCol1 = 0;
549 7 : nCol2 = 0;
550 7 : nExprLvl = 0;
551 7 : nArgc = 0;
552 7 : nError = 0;
553 7 : nGosubLvl = 0;
554 7 : nForLvl = 0;
555 7 : nOps = 0;
556 7 : refExprStk = new SbxArray;
557 7 : SetVBAEnabled( pMod->IsVBACompat() );
558 : #if defined GCC
559 7 : SetParameters( pe ? pe->GetParameters() : (class SbxArray *)NULL );
560 : #else
561 : SetParameters( pe ? pe->GetParameters() : NULL );
562 : #endif
563 7 : pRefSaveList = NULL;
564 7 : pItemStoreList = NULL;
565 7 : }
566 :
567 14 : SbiRuntime::~SbiRuntime()
568 : {
569 7 : ClearGosubStack();
570 7 : ClearArgvStack();
571 7 : ClearForStack();
572 :
573 : // #74254 free items for saving temporary references
574 7 : ClearRefs();
575 24 : while( pItemStoreList )
576 : {
577 10 : RefSaveItem* pToDeleteItem = pItemStoreList;
578 10 : pItemStoreList = pToDeleteItem->pNext;
579 10 : delete pToDeleteItem;
580 : }
581 7 : }
582 :
583 7 : void SbiRuntime::SetVBAEnabled(bool bEnabled )
584 : {
585 7 : bVBAEnabled = bEnabled;
586 7 : if ( bVBAEnabled )
587 : {
588 0 : if ( pMeth )
589 : {
590 0 : mpExtCaller = pMeth->mCaller;
591 : }
592 : }
593 : else
594 : {
595 7 : mpExtCaller = 0;
596 : }
597 7 : }
598 :
599 : // Construction of the parameter list. All ByRef-parameters are directly
600 : // taken over; copies of ByVal-parameters are created. If a particular
601 : // data type is requested, it is converted.
602 :
603 7 : void SbiRuntime::SetParameters( SbxArray* pParams )
604 : {
605 7 : refParams = new SbxArray;
606 : // for the return value
607 7 : refParams->Put( pMeth, 0 );
608 :
609 7 : SbxInfo* pInfo = pMeth ? pMeth->GetInfo() : NULL;
610 7 : sal_uInt16 nParamCount = pParams ? pParams->Count() : 1;
611 7 : if( nParamCount > 1 )
612 : {
613 0 : for( sal_uInt16 i = 1 ; i < nParamCount ; i++ )
614 : {
615 0 : const SbxParamInfo* p = pInfo ? pInfo->GetParam( i ) : NULL;
616 :
617 : // #111897 ParamArray
618 0 : if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
619 : {
620 0 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
621 0 : sal_uInt16 nParamArrayParamCount = nParamCount - i;
622 0 : pArray->unoAddDim( 0, nParamArrayParamCount - 1 );
623 0 : for( sal_uInt16 j = i ; j < nParamCount ; j++ )
624 : {
625 0 : SbxVariable* v = pParams->Get( j );
626 0 : short nDimIndex = j - i;
627 0 : pArray->Put( v, &nDimIndex );
628 : }
629 0 : SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
630 0 : pArrayVar->SetFlag( SBX_READWRITE );
631 0 : pArrayVar->PutObject( pArray );
632 0 : refParams->Put( pArrayVar, i );
633 :
634 : // Block ParamArray for missing parameter
635 0 : pInfo = NULL;
636 0 : break;
637 : }
638 :
639 0 : SbxVariable* v = pParams->Get( i );
640 : // methods are always byval!
641 0 : sal_Bool bByVal = v->IsA( TYPE(SbxMethod) );
642 0 : SbxDataType t = v->GetType();
643 0 : bool bTargetTypeIsArray = false;
644 0 : if( p )
645 : {
646 0 : bByVal |= sal_Bool( ( p->eType & SbxBYREF ) == 0 );
647 0 : t = (SbxDataType) ( p->eType & 0x0FFF );
648 :
649 0 : if( !bByVal && t != SbxVARIANT &&
650 0 : (!v->IsFixed() || (SbxDataType)(v->GetType() & 0x0FFF ) != t) )
651 : {
652 0 : bByVal = sal_True;
653 : }
654 :
655 0 : bTargetTypeIsArray = (p->nUserData & PARAM_INFO_WITHBRACKETS) != 0;
656 : }
657 0 : if( bByVal )
658 : {
659 0 : if( bTargetTypeIsArray )
660 : {
661 0 : t = SbxOBJECT;
662 : }
663 0 : SbxVariable* v2 = new SbxVariable( t );
664 0 : v2->SetFlag( SBX_READWRITE );
665 0 : *v2 = *v;
666 0 : refParams->Put( v2, i );
667 : }
668 : else
669 : {
670 0 : if( t != SbxVARIANT && t != ( v->GetType() & 0x0FFF ) )
671 : {
672 0 : if( p && (p->eType & SbxARRAY) )
673 : {
674 0 : Error( SbERR_CONVERSION );
675 : }
676 : else
677 : {
678 0 : v->Convert( t );
679 : }
680 : }
681 0 : refParams->Put( v, i );
682 : }
683 0 : if( p )
684 : {
685 0 : refParams->PutAlias( p->aName, i );
686 : }
687 : }
688 : }
689 :
690 : // ParamArray for missing parameter
691 7 : if( pInfo )
692 : {
693 : // #111897 Check first missing parameter for ParamArray
694 7 : const SbxParamInfo* p = pInfo->GetParam( nParamCount );
695 7 : if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
696 : {
697 0 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
698 0 : pArray->unoAddDim( 0, -1 );
699 0 : SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
700 0 : pArrayVar->SetFlag( SBX_READWRITE );
701 0 : pArrayVar->PutObject( pArray );
702 0 : refParams->Put( pArrayVar, nParamCount );
703 : }
704 : }
705 7 : }
706 :
707 :
708 : // execute a P-Code
709 :
710 210 : bool SbiRuntime::Step()
711 : {
712 210 : if( bRun )
713 : {
714 : // in any case check casually!
715 210 : if( !( ++nOps & 0xF ) && pInst->IsReschedule() )
716 : {
717 10 : sal_uInt32 nTime = osl_getGlobalTimer();
718 10 : if (nTime - m_nLastTime > 5 ) // 20 ms
719 : {
720 7 : Application::Reschedule();
721 7 : m_nLastTime = nTime;
722 : }
723 : }
724 :
725 : // #i48868 blocked by next call level?
726 420 : while( bBlocked )
727 : {
728 0 : if( pInst->IsReschedule() )
729 : {
730 0 : Application::Reschedule();
731 : }
732 : }
733 :
734 210 : SbiOpcode eOp = (SbiOpcode ) ( *pCode++ );
735 : sal_uInt32 nOp1, nOp2;
736 210 : if (eOp <= SbOP0_END)
737 : {
738 47 : (this->*( aStep0[ eOp ] ) )();
739 : }
740 163 : else if (eOp >= SbOP1_START && eOp <= SbOP1_END)
741 : {
742 22 : nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
743 :
744 22 : (this->*( aStep1[ eOp - SbOP1_START ] ) )( nOp1 );
745 : }
746 141 : else if (eOp >= SbOP2_START && eOp <= SbOP2_END)
747 : {
748 141 : nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
749 141 : nOp2 = *pCode++; nOp2 |= *pCode++ << 8; nOp2 |= *pCode++ << 16; nOp2 |= *pCode++ << 24;
750 141 : (this->*( aStep2[ eOp - SbOP2_START ] ) )( nOp1, nOp2 );
751 : }
752 : else
753 : {
754 0 : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
755 : }
756 :
757 210 : SbError nSbError = SbxBase::GetError();
758 210 : Error( ERRCODE_TOERROR(nSbError) );
759 :
760 : // from 13.2.1997, new error handling:
761 : // ATTENTION: nError can be set already even if !nSbError
762 : // since nError can now also be set from other RT-instances
763 :
764 210 : if( nError )
765 : {
766 0 : SbxBase::ResetError();
767 : }
768 :
769 : // from 15.3.96: display errors only if BASIC is still active
770 : // (especially not after compiler errors at the runtime)
771 210 : if( nError && bRun )
772 : {
773 0 : SbError err = nError;
774 0 : ClearExprStack();
775 0 : nError = 0;
776 0 : pInst->nErr = err;
777 0 : pInst->nErl = nLine;
778 0 : pErrCode = pCode;
779 0 : pErrStmnt = pStmnt;
780 : // An error occurred in an error handler
781 : // force parent handler ( if there is one )
782 : // to handle the error
783 0 : bool bLetParentHandleThis = false;
784 :
785 : // in the error handler? so std-error
786 0 : if ( !bInError )
787 : {
788 0 : bInError = true;
789 :
790 0 : if( !bError ) // On Error Resume Next
791 : {
792 0 : StepRESUME( 1 );
793 : }
794 0 : else if( pError ) // On Error Goto ...
795 : {
796 0 : pCode = pError;
797 : }
798 : else
799 : {
800 0 : bLetParentHandleThis = true;
801 : }
802 : }
803 : else
804 : {
805 0 : bLetParentHandleThis = true;
806 0 : pError = NULL; //terminate the handler
807 : }
808 0 : if ( bLetParentHandleThis )
809 : {
810 : // from 13.2.1997, new error handling:
811 : // consider superior error handlers
812 :
813 : // there's no error handler -> find one farther above
814 0 : SbiRuntime* pRtErrHdl = NULL;
815 0 : SbiRuntime* pRt = this;
816 0 : while( NULL != (pRt = pRt->pNext) )
817 : {
818 0 : if( !pRt->bError || pRt->pError != NULL )
819 : {
820 0 : pRtErrHdl = pRt;
821 0 : break;
822 : }
823 : }
824 :
825 :
826 0 : if( pRtErrHdl )
827 : {
828 : // manipulate all the RTs that are below in the call-stack
829 0 : pRt = this;
830 0 : do
831 : {
832 0 : pRt->nError = err;
833 0 : if( pRt != pRtErrHdl )
834 : {
835 0 : pRt->bRun = false;
836 : }
837 : else
838 : {
839 0 : break;
840 : }
841 0 : pRt = pRt->pNext;
842 : }
843 : while( pRt );
844 : }
845 : // no error-hdl found -> old behaviour
846 : else
847 : {
848 0 : pInst->Abort();
849 : }
850 : }
851 : }
852 : }
853 210 : return bRun;
854 : }
855 :
856 210 : void SbiRuntime::Error( SbError n, bool bVBATranslationAlreadyDone )
857 : {
858 210 : if( n )
859 : {
860 0 : nError = n;
861 0 : if( isVBAEnabled() && !bVBATranslationAlreadyDone )
862 : {
863 0 : OUString aMsg = pInst->GetErrorMsg();
864 0 : sal_Int32 nVBAErrorNumber = translateErrorToVba( nError, aMsg );
865 0 : SbxVariable* pSbxErrObjVar = SbxErrObject::getErrObject();
866 0 : SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pSbxErrObjVar );
867 0 : if( pGlobErr != NULL )
868 : {
869 0 : pGlobErr->setNumberAndDescription( nVBAErrorNumber, aMsg );
870 : }
871 0 : pInst->aErrorMsg = aMsg;
872 0 : nError = SbERR_BASIC_COMPAT;
873 : }
874 : }
875 210 : }
876 :
877 0 : void SbiRuntime::Error( SbError _errCode, const OUString& _details )
878 : {
879 0 : if ( _errCode )
880 : {
881 : // Not correct for class module usage, remove for now
882 : //OSL_ENSURE( pInst->pRun == this, "SbiRuntime::Error: can't propagate the error message details!" );
883 0 : if ( pInst->pRun == this )
884 : {
885 0 : pInst->Error( _errCode, _details );
886 : //OSL_POSTCOND( nError == _errCode, "SbiRuntime::Error: the instance is expecte to propagate the error code back to me!" );
887 : }
888 : else
889 : {
890 0 : nError = _errCode;
891 : }
892 : }
893 0 : }
894 :
895 0 : void SbiRuntime::FatalError( SbError n )
896 : {
897 0 : StepSTDERROR();
898 0 : Error( n );
899 0 : }
900 :
901 0 : void SbiRuntime::FatalError( SbError _errCode, const OUString& _details )
902 : {
903 0 : StepSTDERROR();
904 0 : Error( _errCode, _details );
905 0 : }
906 :
907 0 : sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, OUString& rMsg )
908 : {
909 : // If a message is defined use that ( in preference to
910 : // the defined one for the error ) NB #TODO
911 : // if there is an error defined it more than likely
912 : // is not the one you want ( some are the same though )
913 : // we really need a new vba compatible error list
914 0 : if ( rMsg.isEmpty() )
915 : {
916 : // TEST, has to be vb here always
917 : #ifdef DBG_UTIL
918 : SbError nTmp = StarBASIC::GetSfxFromVBError( (sal_uInt16)nError );
919 : DBG_ASSERT( nTmp, "No VB error!" );
920 : #endif
921 :
922 0 : StarBASIC::MakeErrorText( nError, rMsg );
923 0 : rMsg = StarBASIC::GetErrorText();
924 0 : if ( rMsg.isEmpty() ) // no message for err no, need localized resource here
925 : {
926 0 : rMsg = "Internal Object Error:";
927 : }
928 : }
929 : // no num? most likely then it *is* really a vba err
930 0 : sal_uInt16 nVBErrorCode = StarBASIC::GetVBErrorCode( nError );
931 0 : sal_Int32 nVBAErrorNumber = ( nVBErrorCode == 0 ) ? nError : nVBErrorCode;
932 0 : return nVBAErrorNumber;
933 : }
934 :
935 : // Parameter, Locals, Caller
936 :
937 0 : SbMethod* SbiRuntime::GetCaller()
938 : {
939 0 : return pMeth;
940 : }
941 :
942 : // Stacks
943 :
944 : // The expression-stack is available for the continous evaluation
945 : // of expressions.
946 :
947 98 : void SbiRuntime::PushVar( SbxVariable* pVar )
948 : {
949 98 : if( pVar )
950 : {
951 98 : refExprStk->Put( pVar, nExprLvl++ );
952 : }
953 98 : }
954 :
955 98 : SbxVariableRef SbiRuntime::PopVar()
956 : {
957 : #ifdef DBG_UTIL
958 : if( !nExprLvl )
959 : {
960 : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
961 : return new SbxVariable;
962 : }
963 : #endif
964 98 : SbxVariableRef xVar = refExprStk->Get( --nExprLvl );
965 : #ifdef DBG_UTIL
966 : if ( xVar->GetName().equalsAscii( "Cells" ) )
967 : OSL_TRACE( "" );
968 : #endif
969 : // methods hold themselves in parameter 0
970 98 : if( xVar->IsA( TYPE(SbxMethod) ) )
971 : {
972 9 : xVar->SetParameters(0);
973 : }
974 98 : return xVar;
975 : }
976 :
977 50 : bool SbiRuntime::ClearExprStack()
978 : {
979 : // Attention: Clear() doesn't suffice as methods must be deleted
980 100 : while ( nExprLvl )
981 : {
982 0 : PopVar();
983 : }
984 50 : refExprStk->Clear();
985 50 : return false;
986 : }
987 :
988 : // Take variable from the expression-stack without removing it
989 : // n counts from 0
990 :
991 3 : SbxVariable* SbiRuntime::GetTOS( short n )
992 : {
993 3 : n = nExprLvl - n - 1;
994 : #ifdef DBG_UTIL
995 : if( n < 0 )
996 : {
997 : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
998 : return new SbxVariable;
999 : }
1000 : #endif
1001 3 : return refExprStk->Get( (sal_uInt16) n );
1002 : }
1003 :
1004 :
1005 3 : void SbiRuntime::TOSMakeTemp()
1006 : {
1007 3 : SbxVariable* p = refExprStk->Get( nExprLvl - 1 );
1008 3 : if ( p->GetType() == SbxEMPTY )
1009 : {
1010 0 : p->Broadcast( SBX_HINT_DATAWANTED );
1011 : }
1012 :
1013 3 : SbxVariable* pDflt = NULL;
1014 3 : if ( bVBAEnabled && ( p->GetType() == SbxOBJECT || p->GetType() == SbxVARIANT ) && ((pDflt = getDefaultProp(p)) != NULL) )
1015 : {
1016 0 : pDflt->Broadcast( SBX_HINT_DATAWANTED );
1017 : // replacing new p on stack causes object pointed by
1018 : // pDft->pParent to be deleted, when p2->Compute() is
1019 : // called below pParent is accessed ( but its deleted )
1020 : // so set it to NULL now
1021 0 : pDflt->SetParent( NULL );
1022 0 : p = new SbxVariable( *pDflt );
1023 0 : p->SetFlag( SBX_READWRITE );
1024 0 : refExprStk->Put( p, nExprLvl - 1 );
1025 : }
1026 3 : else if( p->GetRefCount() != 1 )
1027 : {
1028 3 : SbxVariable* pNew = new SbxVariable( *p );
1029 3 : pNew->SetFlag( SBX_READWRITE );
1030 3 : refExprStk->Put( pNew, nExprLvl - 1 );
1031 : }
1032 3 : }
1033 :
1034 : // the GOSUB-stack collects return-addresses for GOSUBs
1035 0 : void SbiRuntime::PushGosub( const sal_uInt8* pc )
1036 : {
1037 0 : if( ++nGosubLvl > MAXRECURSION )
1038 : {
1039 0 : StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
1040 : }
1041 0 : SbiGosubStack* p = new SbiGosubStack;
1042 0 : p->pCode = pc;
1043 0 : p->pNext = pGosubStk;
1044 0 : p->nStartForLvl = nForLvl;
1045 0 : pGosubStk = p;
1046 0 : }
1047 :
1048 0 : void SbiRuntime::PopGosub()
1049 : {
1050 0 : if( !pGosubStk )
1051 : {
1052 0 : Error( SbERR_NO_GOSUB );
1053 : }
1054 : else
1055 : {
1056 0 : SbiGosubStack* p = pGosubStk;
1057 0 : pCode = p->pCode;
1058 0 : pGosubStk = p->pNext;
1059 0 : delete p;
1060 0 : nGosubLvl--;
1061 : }
1062 0 : }
1063 :
1064 :
1065 7 : void SbiRuntime::ClearGosubStack()
1066 : {
1067 : SbiGosubStack* p;
1068 14 : while(( p = pGosubStk ) != NULL )
1069 : {
1070 0 : pGosubStk = p->pNext, delete p;
1071 : }
1072 7 : nGosubLvl = 0;
1073 7 : }
1074 :
1075 : // the Argv-stack collects current argument-vectors
1076 :
1077 2 : void SbiRuntime::PushArgv()
1078 : {
1079 2 : SbiArgvStack* p = new SbiArgvStack;
1080 2 : p->refArgv = refArgv;
1081 2 : p->nArgc = nArgc;
1082 2 : nArgc = 1;
1083 2 : refArgv.Clear();
1084 2 : p->pNext = pArgvStk;
1085 2 : pArgvStk = p;
1086 2 : }
1087 :
1088 2 : void SbiRuntime::PopArgv()
1089 : {
1090 2 : if( pArgvStk )
1091 : {
1092 2 : SbiArgvStack* p = pArgvStk;
1093 2 : pArgvStk = p->pNext;
1094 2 : refArgv = p->refArgv;
1095 2 : nArgc = p->nArgc;
1096 2 : delete p;
1097 : }
1098 2 : }
1099 :
1100 :
1101 7 : void SbiRuntime::ClearArgvStack()
1102 : {
1103 14 : while( pArgvStk )
1104 : {
1105 0 : PopArgv();
1106 : }
1107 7 : }
1108 :
1109 : // Push of the for-stack. The stack has increment, end, begin and variable.
1110 : // After the creation of the stack-element the stack's empty.
1111 :
1112 0 : void SbiRuntime::PushFor()
1113 : {
1114 0 : SbiForStack* p = new SbiForStack;
1115 0 : p->eForType = FOR_TO;
1116 0 : p->pNext = pForStk;
1117 0 : pForStk = p;
1118 :
1119 0 : p->refInc = PopVar();
1120 0 : p->refEnd = PopVar();
1121 0 : SbxVariableRef xBgn = PopVar();
1122 0 : p->refVar = PopVar();
1123 0 : *(p->refVar) = *xBgn;
1124 0 : nForLvl++;
1125 0 : }
1126 :
1127 0 : void SbiRuntime::PushForEach()
1128 : {
1129 0 : SbiForStack* p = new SbiForStack;
1130 0 : p->pNext = pForStk;
1131 0 : pForStk = p;
1132 :
1133 0 : SbxVariableRef xObjVar = PopVar();
1134 0 : SbxBase* pObj = xObjVar.Is() ? xObjVar->GetObject() : NULL;
1135 0 : if( pObj == NULL )
1136 : {
1137 0 : Error( SbERR_NO_OBJECT );
1138 : return;
1139 : }
1140 :
1141 0 : bool bError_ = false;
1142 : BasicCollection* pCollection;
1143 : SbxDimArray* pArray;
1144 : SbUnoObject* pUnoObj;
1145 0 : if( (pArray = PTR_CAST(SbxDimArray,pObj)) != NULL )
1146 : {
1147 0 : p->eForType = FOR_EACH_ARRAY;
1148 0 : p->refEnd = (SbxVariable*)pArray;
1149 :
1150 0 : short nDims = pArray->GetDims();
1151 0 : p->pArrayLowerBounds = new sal_Int32[nDims];
1152 0 : p->pArrayUpperBounds = new sal_Int32[nDims];
1153 0 : p->pArrayCurIndices = new sal_Int32[nDims];
1154 : sal_Int32 lBound, uBound;
1155 0 : for( short i = 0 ; i < nDims ; i++ )
1156 : {
1157 0 : pArray->GetDim32( i+1, lBound, uBound );
1158 0 : p->pArrayCurIndices[i] = p->pArrayLowerBounds[i] = lBound;
1159 0 : p->pArrayUpperBounds[i] = uBound;
1160 : }
1161 : }
1162 0 : else if( (pCollection = PTR_CAST(BasicCollection,pObj)) != NULL )
1163 : {
1164 0 : p->eForType = FOR_EACH_COLLECTION;
1165 0 : p->refEnd = pCollection;
1166 0 : p->nCurCollectionIndex = 0;
1167 : }
1168 0 : else if( (pUnoObj = PTR_CAST(SbUnoObject,pObj)) != NULL )
1169 : {
1170 : // XEnumerationAccess?
1171 0 : Any aAny = pUnoObj->getUnoAny();
1172 0 : Reference< XEnumerationAccess > xEnumerationAccess;
1173 0 : if( (aAny >>= xEnumerationAccess) )
1174 : {
1175 0 : p->xEnumeration = xEnumerationAccess->createEnumeration();
1176 0 : p->eForType = FOR_EACH_XENUMERATION;
1177 : }
1178 0 : else if ( isVBAEnabled() && pUnoObj->isNativeCOMObject() )
1179 : {
1180 0 : uno::Reference< script::XInvocation > xInvocation;
1181 0 : if ( ( aAny >>= xInvocation ) && xInvocation.is() )
1182 : {
1183 : try
1184 : {
1185 0 : p->xEnumeration = new ComEnumerationWrapper( xInvocation );
1186 0 : p->eForType = FOR_EACH_XENUMERATION;
1187 : }
1188 0 : catch(const uno::Exception& )
1189 : {}
1190 : }
1191 0 : if ( !p->xEnumeration.is() )
1192 : {
1193 0 : bError_ = true;
1194 0 : }
1195 : }
1196 : else
1197 : {
1198 0 : bError_ = true;
1199 0 : }
1200 : }
1201 : else
1202 : {
1203 0 : bError_ = true;
1204 : }
1205 :
1206 0 : if( bError_ )
1207 : {
1208 0 : Error( SbERR_CONVERSION );
1209 : return;
1210 : }
1211 :
1212 : // Container variable
1213 0 : p->refVar = PopVar();
1214 0 : nForLvl++;
1215 : }
1216 :
1217 :
1218 0 : void SbiRuntime::PopFor()
1219 : {
1220 0 : if( pForStk )
1221 : {
1222 0 : SbiForStack* p = pForStk;
1223 0 : pForStk = p->pNext;
1224 0 : delete p;
1225 0 : nForLvl--;
1226 : }
1227 0 : }
1228 :
1229 :
1230 7 : void SbiRuntime::ClearForStack()
1231 : {
1232 14 : while( pForStk )
1233 : {
1234 0 : PopFor();
1235 : }
1236 7 : }
1237 :
1238 0 : SbiForStack* SbiRuntime::FindForStackItemForCollection( class BasicCollection* pCollection )
1239 : {
1240 0 : for (SbiForStack *p = pForStk; p; p = p->pNext)
1241 : {
1242 0 : SbxVariable* pVar = p->refEnd.Is() ? (SbxVariable*)p->refEnd : NULL;
1243 0 : if( p->eForType == FOR_EACH_COLLECTION && pVar != NULL &&
1244 0 : PTR_CAST(BasicCollection,pVar) == pCollection )
1245 : {
1246 0 : return p;
1247 : }
1248 : }
1249 :
1250 0 : return NULL;
1251 : }
1252 :
1253 :
1254 : //////////////////////////////////////////////////////////////////////////
1255 : //
1256 : // DLL-calls
1257 :
1258 0 : void SbiRuntime::DllCall
1259 : ( const OUString& aFuncName,
1260 : const OUString& aDLLName,
1261 : SbxArray* pArgs, // parameter (from index 1, can be NULL)
1262 : SbxDataType eResType, // return value
1263 : bool bCDecl ) // true: according to C-conventions
1264 : {
1265 : // No DllCall for "virtual" portal users
1266 0 : if( needSecurityRestrictions() )
1267 : {
1268 0 : StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
1269 0 : return;
1270 : }
1271 :
1272 : // NOT YET IMPLEMENTED
1273 :
1274 0 : SbxVariable* pRes = new SbxVariable( eResType );
1275 0 : SbiDllMgr* pDllMgr = pInst->GetDllMgr();
1276 0 : SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl );
1277 0 : if( nErr )
1278 : {
1279 0 : Error( nErr );
1280 : }
1281 0 : PushVar( pRes );
1282 : }
1283 :
1284 0 : sal_uInt16 SbiRuntime::GetImageFlag( sal_uInt16 n ) const
1285 : {
1286 0 : return pImg->GetFlag( n );
1287 : }
1288 :
1289 0 : sal_uInt16 SbiRuntime::GetBase()
1290 : {
1291 0 : return pImg->GetBase();
1292 : }
1293 :
1294 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|