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 : :
21 : : #include "runtime.hxx"
22 : : #include "iosys.hxx"
23 : : #include "image.hxx"
24 : : #include "sbintern.hxx"
25 : : #include "sbunoobj.hxx"
26 : : #include "opcodes.hxx"
27 : :
28 : : #include <com/sun/star/container/XIndexAccess.hpp>
29 : : #include <com/sun/star/script/XDefaultMethod.hpp>
30 : : #include <com/sun/star/beans/XPropertySet.hpp>
31 : : #include <com/sun/star/uno/Any.hxx>
32 : : #include <comphelper/processfactory.hxx>
33 : :
34 : : using namespace com::sun::star::uno;
35 : : using namespace com::sun::star::container;
36 : : using namespace com::sun::star::lang;
37 : : using namespace com::sun::star::beans;
38 : : using namespace com::sun::star::script;
39 : :
40 : : using com::sun::star::uno::Reference;
41 : :
42 : : SbxVariable* getVBAConstant( const String& rName );
43 : :
44 : :
45 : : // the bits in the String-ID:
46 : : // 0x8000 - Argv is reserved
47 : :
48 : 12353 : SbxVariable* SbiRuntime::FindElement
49 : : ( SbxObject* pObj, sal_uInt32 nOp1, sal_uInt32 nOp2, SbError nNotFound, bool bLocal, bool bStatic )
50 : : {
51 : 12353 : bool bIsVBAInterOp = SbiRuntime::isVBAEnabled();
52 [ + + ]: 12353 : if( bIsVBAInterOp )
53 : : {
54 : 1014 : StarBASIC* pMSOMacroRuntimeLib = GetSbData()->pMSOMacroRuntimLib;
55 [ - + ]: 1014 : if( pMSOMacroRuntimeLib != NULL )
56 : 0 : pMSOMacroRuntimeLib->ResetFlag( SBX_EXTSEARCH );
57 : : }
58 : :
59 : 12353 : SbxVariable* pElem = NULL;
60 [ - + ]: 12353 : if( !pObj )
61 : : {
62 : 0 : Error( SbERR_NO_OBJECT );
63 [ # # ]: 0 : pElem = new SbxVariable;
64 : : }
65 : : else
66 : : {
67 : 12353 : bool bFatalError = false;
68 : 12353 : SbxDataType t = (SbxDataType) nOp2;
69 [ + - ]: 12353 : String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) );
70 : : // Hacky capture of Evaluate [] syntax
71 : : // this should be tackled I feel at the pcode level
72 [ + + ][ + - ]: 12353 : if ( bIsVBAInterOp && aName.Search('[') == 0 )
[ - + ][ - + ]
73 : : {
74 : : // emulate pcode here
75 [ # # ]: 0 : StepARGC();
76 : : // psuedo StepLOADSC
77 [ # # ]: 0 : String sArg = aName.Copy( 1, aName.Len() - 2 );
78 [ # # ][ # # ]: 0 : SbxVariable* p = new SbxVariable;
79 [ # # ][ # # ]: 0 : p->PutString( sArg );
80 [ # # ]: 0 : PushVar( p );
81 [ # # ]: 0 : StepARGV();
82 : 0 : nOp1 = nOp1 | 0x8000; // indicate params are present
83 [ # # ][ # # ]: 0 : aName = rtl::OUString("Evaluate");
84 : : }
85 [ + + ]: 12353 : if( bLocal )
86 : : {
87 [ - + ]: 10944 : if ( bStatic )
88 : : {
89 [ # # ]: 0 : if ( pMeth )
90 [ # # ][ # # ]: 0 : pElem = pMeth->GetStatics()->Find( aName, SbxCLASS_DONTCARE );
[ # # ]
91 : : }
92 : :
93 [ + - ]: 10944 : if ( !pElem )
94 [ + - ][ + - ]: 10944 : pElem = refLocals->Find( aName, SbxCLASS_DONTCARE );
95 : : }
96 [ + + ]: 12353 : if( !pElem )
97 : : {
98 : 8644 : sal_Bool bSave = rBasic.bNoRtl;
99 : 8644 : rBasic.bNoRtl = sal_True;
100 [ + - ][ + - ]: 8644 : pElem = pObj->Find( aName, SbxCLASS_DONTCARE );
101 : :
102 : : // #110004, #112015: Make private really private
103 [ + + ][ + + ]: 8644 : if( bLocal && pElem ) // Local as flag for global search
104 : : {
105 [ + + ]: 7120 : if( pElem->IsSet( SBX_PRIVATE ) )
106 : : {
107 [ + - ]: 216 : SbiInstance* pInst_ = GetSbData()->pInst;
108 [ + - ][ + - ]: 216 : if( pInst_ && pInst_->IsCompatibility() && pObj != pElem->GetParent() )
[ + - ][ - + ]
[ - + ]
109 : 0 : pElem = NULL; // Found but in wrong module!
110 : :
111 : : // Interfaces: Use SBX_EXTFOUND
112 : : }
113 : : }
114 : 8644 : rBasic.bNoRtl = bSave;
115 : :
116 : : // is it a global uno-identifier?
117 [ + + ][ + + ]: 8644 : if( bLocal && !pElem )
118 : : {
119 : 115 : bool bSetName = true; // preserve normal behaviour
120 : :
121 : : // i#i68894# if VBAInterOp favour searching vba globals
122 : : // over searching for uno classess
123 [ + + ]: 115 : if ( bVBAEnabled )
124 : : {
125 : : // Try Find in VBA symbols space
126 [ + - ][ + - ]: 28 : pElem = rBasic.VBAFind( aName, SbxCLASS_DONTCARE );
127 [ + + ]: 28 : if ( pElem )
128 : 20 : bSetName = false; // don't overwrite uno name
129 : : else
130 [ + - ][ + - ]: 8 : pElem = VBAConstantHelper::instance().getVBAConstant( aName );
[ + - ]
131 : : }
132 : :
133 [ + + ]: 115 : if( !pElem )
134 : : {
135 : : // #72382 ATTENTION! ALWAYS returns a result now
136 : : // because of unknown modules!
137 [ + - ][ + - ]: 93 : SbUnoClass* pUnoClass = findUnoClass( aName );
138 [ + + ]: 93 : if( pUnoClass )
139 : : {
140 [ + - ][ + - ]: 2 : pElem = new SbxVariable( t );
141 : 2 : SbxValues aRes( SbxOBJECT );
142 : 2 : aRes.pObj = pUnoClass;
143 [ + - ]: 2 : pElem->SbxVariable::Put( aRes );
144 : : }
145 : : }
146 : :
147 : : // #62939 If an uno-class has been found, the wrapper
148 : : // object has to be held, because the uno-class, e. g.
149 : : // "stardiv", has to be read out of the registry
150 : : // every time again otherwise
151 [ + + ]: 115 : if( pElem )
152 : : {
153 : : // #63774 May not be saved too!!!
154 : 24 : pElem->SetFlag( SBX_DONTSTORE );
155 : 24 : pElem->SetFlag( SBX_NO_MODIFY);
156 : :
157 : : // #72382 save locally, all variables that have been declared
158 : : // implicit would become global automatically otherwise!
159 [ + + ]: 24 : if ( bSetName )
160 [ + - ]: 4 : pElem->SetName( aName );
161 [ + - ][ + - ]: 24 : refLocals->Put( pElem, refLocals->Count() );
162 : : }
163 : : }
164 : :
165 [ + + ]: 8644 : if( !pElem )
166 : : {
167 : : // not there and not in the object?
168 : : // don't establish if that thing has parameters!
169 [ - + ]: 91 : if( nOp1 & 0x8000 )
170 : 0 : bFatalError = true;
171 : :
172 : : // else, if there are parameters, use different error code
173 [ + - ][ - + ]: 91 : if( !bLocal || pImg->GetFlag( SBIMG_EXPLICIT ) )
[ - + ]
174 : : {
175 : : // #39108 if explicit and as ELEM always a fatal error
176 : 0 : bFatalError = true;
177 : :
178 : :
179 [ # # ][ # # ]: 0 : if( !( nOp1 & 0x8000 ) && nNotFound == SbERR_PROC_UNDEFINED )
180 : 0 : nNotFound = SbERR_VAR_UNDEFINED;
181 : : }
182 [ - + ]: 91 : if( bFatalError )
183 : : {
184 : : // #39108 use dummy variable instead of fatal error
185 [ # # ]: 0 : if( !xDummyVar.Is() )
186 [ # # ][ # # ]: 0 : xDummyVar = new SbxVariable( SbxVARIANT );
[ # # ]
187 : 0 : pElem = xDummyVar;
188 : :
189 [ # # ]: 0 : ClearArgvStack();
190 : :
191 [ # # ]: 0 : Error( nNotFound, aName );
192 : : }
193 : : else
194 : : {
195 [ - + ]: 91 : if ( bStatic )
196 [ # # ]: 0 : pElem = StepSTATIC_Impl( aName, t );
197 [ + - ]: 91 : if ( !pElem )
198 : : {
199 [ + - ][ + - ]: 91 : pElem = new SbxVariable( t );
200 [ + + ]: 91 : if( t != SbxVARIANT )
201 : 4 : pElem->SetFlag( SBX_FIXED );
202 [ + - ]: 91 : pElem->SetName( aName );
203 [ + - ][ + - ]: 91 : refLocals->Put( pElem, refLocals->Count() );
204 : : }
205 : : }
206 : : }
207 : : }
208 : : // #39108 Args can already be deleted!
209 [ + - ]: 12353 : if( !bFatalError )
210 [ + - ]: 12353 : SetupArgs( pElem, nOp1 );
211 : :
212 : : // because a particular call-type is requested
213 [ + - ][ + - ]: 12353 : if( pElem->IsA( TYPE(SbxMethod) ) )
[ + + ]
214 : : {
215 : : // shall the type be converted?
216 [ + - ]: 1744 : SbxDataType t2 = pElem->GetType();
217 : 1744 : bool bSet = false;
218 [ + + ]: 1744 : if( !( pElem->GetFlags() & SBX_FIXED ) )
219 : : {
220 [ + + ][ + + ]: 564 : if( t != SbxVARIANT && t != t2 &&
[ + - ][ - + ]
221 : : t >= SbxINTEGER && t <= SbxSTRING )
222 [ # # ]: 0 : pElem->SetType( t ), bSet = true;
223 : : }
224 : : // assign pElem to a Ref, to delete a temp-var if applicable
225 : 1744 : SbxVariableRef refTemp = pElem;
226 : :
227 : : // remove potential rests of the last call of the SbxMethod
228 : : // free Write before, so that there's no error
229 : 1744 : sal_uInt16 nSavFlags = pElem->GetFlags();
230 : 1744 : pElem->SetFlag( SBX_READWRITE | SBX_NO_BROADCAST );
231 [ + - ]: 1744 : pElem->SbxValue::Clear();
232 : 1744 : pElem->SetFlags( nSavFlags );
233 : :
234 : : // don't touch before setting, as e. g. LEFT()
235 : : // has to know the difference between Left$() and Left()
236 : :
237 : : // because the methods' parameters are cut away in PopVar()
238 [ + - ][ + - ]: 1744 : SbxVariable* pNew = new SbxMethod( *((SbxMethod*)pElem) );
239 : : //OLD: SbxVariable* pNew = new SbxVariable( *pElem );
240 : :
241 [ + - ]: 1744 : pElem->SetParameters(0);
242 : 1744 : pNew->SetFlag( SBX_READWRITE );
243 : :
244 [ - + ]: 1744 : if( bSet )
245 [ # # ]: 0 : pElem->SetType( t2 );
246 [ + - ]: 1744 : pElem = pNew;
247 : : }
248 : : // consider index-access for UnoObjects
249 : : // definitely we want this for VBA where properties are often
250 : : // collections ( which need index access ), but lets only do
251 : : // this if we actually have params following
252 [ + + ][ + - ]: 10609 : else if( bVBAEnabled && pElem->ISA(SbUnoProperty) && pElem->GetParameters() )
[ + - ][ + + ]
[ + - ][ - + ]
[ - + ]
253 : : {
254 : 0 : SbxVariableRef refTemp = pElem;
255 : :
256 : : // dissolve the notify while copying variable
257 [ # # ][ # # ]: 0 : SbxVariable* pNew = new SbxVariable( *((SbxVariable*)pElem) );
258 [ # # ]: 0 : pElem->SetParameters( NULL );
259 [ # # ]: 0 : pElem = pNew;
260 [ + - ]: 12353 : }
261 : : }
262 : 12353 : return CheckArray( pElem );
263 : : }
264 : :
265 : : // for current scope (e. g. query from BASIC-IDE)
266 : 0 : SbxBase* SbiRuntime::FindElementExtern( const String& rName )
267 : : {
268 : : // don't expect pMeth to be != 0, as there are none set
269 : : // in the RunInit yet
270 : :
271 : 0 : SbxVariable* pElem = NULL;
272 [ # # ][ # # ]: 0 : if( !pMod || !rName.Len() )
[ # # ]
273 : 0 : return NULL;
274 : :
275 [ # # ]: 0 : if( refLocals )
276 [ # # ]: 0 : pElem = refLocals->Find( rName, SbxCLASS_DONTCARE );
277 : :
278 [ # # ][ # # ]: 0 : if ( !pElem && pMeth )
279 : : {
280 : : // for statics, set the method's name in front
281 [ # # ][ # # ]: 0 : String aMethName = pMeth->GetName();
282 [ # # ]: 0 : aMethName += ':';
283 [ # # ]: 0 : aMethName += rName;
284 [ # # ][ # # ]: 0 : pElem = pMod->Find(aMethName, SbxCLASS_DONTCARE);
[ # # ]
285 : : }
286 : :
287 : : // search in parameter list
288 [ # # ][ # # ]: 0 : if( !pElem && pMeth )
289 : : {
290 : 0 : SbxInfo* pInfo = pMeth->GetInfo();
291 [ # # ][ # # ]: 0 : if( pInfo && refParams )
[ # # ]
292 : : {
293 : 0 : sal_uInt16 nParamCount = refParams->Count();
294 : 0 : sal_uInt16 j = 1;
295 : 0 : const SbxParamInfo* pParam = pInfo->GetParam( j );
296 [ # # ]: 0 : while( pParam )
297 : : {
298 [ # # ]: 0 : if( pParam->aName.EqualsIgnoreCaseAscii( rName ) )
299 : : {
300 [ # # ]: 0 : if( j >= nParamCount )
301 : : {
302 : : // Parameter is missing
303 [ # # ]: 0 : pElem = new SbxVariable( SbxSTRING );
304 [ # # ][ # # ]: 0 : pElem->PutString( String( RTL_CONSTASCII_USTRINGPARAM("<missing parameter>" ) ) );
305 : : }
306 : : else
307 : : {
308 : 0 : pElem = refParams->Get( j );
309 : : }
310 : 0 : break;
311 : : }
312 : 0 : pParam = pInfo->GetParam( ++j );
313 : : }
314 : : }
315 : : }
316 : :
317 : : // search in module
318 [ # # ]: 0 : if( !pElem )
319 : : {
320 : 0 : sal_Bool bSave = rBasic.bNoRtl;
321 : 0 : rBasic.bNoRtl = sal_True;
322 [ # # ]: 0 : pElem = pMod->Find( rName, SbxCLASS_DONTCARE );
323 : 0 : rBasic.bNoRtl = bSave;
324 : : }
325 : 0 : return pElem;
326 : : }
327 : :
328 : :
329 : :
330 : 15022 : void SbiRuntime::SetupArgs( SbxVariable* p, sal_uInt32 nOp1 )
331 : : {
332 [ + + ]: 15022 : if( nOp1 & 0x8000 )
333 : : {
334 [ - + ]: 2518 : if( !refArgv )
335 : 0 : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
336 : 2518 : bool bHasNamed = false;
337 : : sal_uInt16 i;
338 : 2518 : sal_uInt16 nArgCount = refArgv->Count();
339 [ + + ]: 6778 : for( i = 1 ; i < nArgCount ; i++ )
340 : : {
341 [ + + ]: 4298 : if( refArgv->GetAlias( i ).Len() )
342 : : {
343 : 38 : bHasNamed = true; break;
344 : : }
345 : : }
346 [ + + ]: 2518 : if( bHasNamed )
347 : : {
348 : 38 : SbxInfo* pInfo = p->GetInfo();
349 [ - + ]: 38 : if( !pInfo )
350 : : {
351 : 0 : bool bError_ = true;
352 : :
353 [ # # ][ # # ]: 0 : SbUnoMethod* pUnoMethod = PTR_CAST(SbUnoMethod,p);
354 [ # # ][ # # ]: 0 : SbUnoProperty* pUnoProperty = PTR_CAST(SbUnoProperty,p);
355 [ # # ][ # # ]: 0 : if( pUnoMethod || pUnoProperty )
356 : : {
357 [ # # ][ # # ]: 0 : SbUnoObject* pParentUnoObj = PTR_CAST( SbUnoObject,p->GetParent() );
358 [ # # ]: 0 : if( pParentUnoObj )
359 : : {
360 [ # # ]: 0 : Any aUnoAny = pParentUnoObj->getUnoAny();
361 : 0 : Reference< XInvocation > xInvocation;
362 [ # # ]: 0 : aUnoAny >>= xInvocation;
363 [ # # ]: 0 : if( xInvocation.is() ) // TODO: if( xOLEAutomation.is() )
364 : : {
365 : 0 : bError_ = false;
366 : :
367 : 0 : sal_uInt16 nCurPar = 1;
368 : : AutomationNamedArgsSbxArray* pArg =
369 [ # # ][ # # ]: 0 : new AutomationNamedArgsSbxArray( nArgCount );
370 [ # # ]: 0 : ::rtl::OUString* pNames = pArg->getNames().getArray();
371 [ # # ]: 0 : for( i = 1 ; i < nArgCount ; i++ )
372 : : {
373 [ # # ]: 0 : SbxVariable* pVar = refArgv->Get( i );
374 [ # # ]: 0 : const String& rName = refArgv->GetAlias( i );
375 [ # # ]: 0 : if( rName.Len() )
376 [ # # ]: 0 : pNames[i] = rName;
377 [ # # ]: 0 : pArg->Put( pVar, nCurPar++ );
378 : : }
379 [ # # ]: 0 : refArgv = pArg;
380 : 0 : }
381 : 0 : }
382 : : }
383 [ # # ][ # # ]: 0 : else if( bVBAEnabled && p->GetType() == SbxOBJECT && (!p->ISA(SbxMethod) || !p->IsBroadcaster()) )
[ # # ][ # # ]
[ # # ]
384 : : {
385 : : // Check for default method with named parameters
386 [ # # ]: 0 : SbxBaseRef pObj = (SbxBase*)p->GetObject();
387 [ # # ][ # # ]: 0 : if( pObj && pObj->ISA(SbUnoObject) )
[ # # ][ # # ]
[ # # ]
388 : : {
389 : 0 : SbUnoObject* pUnoObj = (SbUnoObject*)(SbxBase*)pObj;
390 [ # # ]: 0 : Any aAny = pUnoObj->getUnoAny();
391 : :
392 [ # # ]: 0 : if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
393 : : {
394 : 0 : Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue();
395 [ # # ]: 0 : Reference< XDefaultMethod > xDfltMethod( x, UNO_QUERY );
396 : :
397 : 0 : rtl::OUString sDefaultMethod;
398 [ # # ]: 0 : if ( xDfltMethod.is() )
399 [ # # ][ # # ]: 0 : sDefaultMethod = xDfltMethod->getDefaultMethodName();
400 [ # # ]: 0 : if ( !sDefaultMethod.isEmpty() )
401 : : {
402 [ # # ]: 0 : SbxVariable* meth = pUnoObj->Find( sDefaultMethod, SbxCLASS_METHOD );
403 [ # # ]: 0 : if( meth != NULL )
404 [ # # ]: 0 : pInfo = meth->GetInfo();
405 [ # # ]: 0 : if( pInfo )
406 : 0 : bError_ = false;
407 : 0 : }
408 : 0 : }
409 [ # # ]: 0 : }
410 : : }
411 [ # # ]: 0 : if( bError_ )
412 : 0 : Error( SbERR_NO_NAMED_ARGS );
413 : : }
414 : : else
415 : : {
416 : 38 : sal_uInt16 nCurPar = 1;
417 [ + - ]: 38 : SbxArray* pArg = new SbxArray;
418 [ + + ]: 78 : for( i = 1 ; i < nArgCount ; i++ )
419 : : {
420 : 40 : SbxVariable* pVar = refArgv->Get( i );
421 : 40 : const String& rName = refArgv->GetAlias( i );
422 [ + - ]: 40 : if( rName.Len() )
423 : : {
424 : : // nCurPar is set to the found parameter
425 : 40 : sal_uInt16 j = 1;
426 : 40 : const SbxParamInfo* pParam = pInfo->GetParam( j );
427 [ + - ]: 122 : while( pParam )
428 : : {
429 [ + + ]: 122 : if( pParam->aName.EqualsIgnoreCaseAscii( rName ) )
430 : : {
431 : 40 : nCurPar = j;
432 : 40 : break;
433 : : }
434 : 82 : pParam = pInfo->GetParam( ++j );
435 : : }
436 [ - + ]: 40 : if( !pParam )
437 : : {
438 : 0 : Error( SbERR_NAMED_NOT_FOUND ); break;
439 : : }
440 : : }
441 : 40 : pArg->Put( pVar, nCurPar++ );
442 : : }
443 : 38 : refArgv = pArg;
444 : : }
445 : : }
446 : : // own var as parameter 0
447 : 2518 : refArgv->Put( p, 0 );
448 : 2518 : p->SetParameters( refArgv );
449 : 2518 : PopArgv();
450 : : }
451 : : else
452 : 12504 : p->SetParameters( NULL );
453 : 15022 : }
454 : :
455 : : // getting an array element
456 : :
457 : 15022 : SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem )
458 : : {
459 : : SbxArray* pPar;
460 [ + + ][ + - ]: 15022 : if( ( pElem->GetType() & SbxARRAY ) && (SbxVariable*)refRedim != pElem )
[ + + ]
461 : : {
462 : 970 : SbxBase* pElemObj = pElem->GetObject();
463 [ + - ][ + - ]: 970 : SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
464 : 970 : pPar = pElem->GetParameters();
465 [ + - ]: 970 : if( pDimArray )
466 : : {
467 : : // parameters may be missing, if an array is
468 : : // passed as an argument
469 [ + + ]: 970 : if( pPar )
470 : 900 : pElem = pDimArray->Get( pPar );
471 : : }
472 : : else
473 : : {
474 [ # # ][ # # ]: 0 : SbxArray* pArray = PTR_CAST(SbxArray,pElemObj);
475 [ # # ]: 0 : if( pArray )
476 : : {
477 [ # # ]: 0 : if( !pPar )
478 : : {
479 : 0 : Error( SbERR_OUT_OF_RANGE );
480 [ # # ]: 0 : pElem = new SbxVariable;
481 : : }
482 : : else
483 : 0 : pElem = pArray->Get( pPar->Get( 1 )->GetInteger() );
484 : : }
485 : : }
486 : :
487 : : // #42940, set parameter 0 to NULL so that var doesn't contain itself
488 [ + + ]: 970 : if( pPar )
489 : 900 : pPar->Put( NULL, 0 );
490 : : }
491 : : // consider index-access for UnoObjects
492 [ + + ][ + + ]: 14052 : else if( pElem->GetType() == SbxOBJECT && !pElem->ISA(SbxMethod) && ( !bVBAEnabled || ( bVBAEnabled && !pElem->ISA(SbxProperty) ) ) )
[ + + ][ + - ]
[ + + ][ + + ]
493 : : {
494 : 970 : pPar = pElem->GetParameters();
495 [ + + ]: 970 : if ( pPar )
496 : : {
497 : : // is it an uno-object?
498 [ + - ]: 60 : SbxBaseRef pObj = (SbxBase*)pElem->GetObject();
499 [ + + ]: 60 : if( pObj )
500 : : {
501 [ + - ][ + - ]: 4 : if( pObj->ISA(SbUnoObject) )
[ + - ]
502 : : {
503 : 4 : SbUnoObject* pUnoObj = (SbUnoObject*)(SbxBase*)pObj;
504 [ + - ]: 4 : Any aAny = pUnoObj->getUnoAny();
505 : :
506 [ + - ]: 4 : if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
507 : : {
508 : 4 : Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue();
509 [ + - ]: 4 : Reference< XIndexAccess > xIndexAccess( x, UNO_QUERY );
510 [ + - ]: 4 : if ( !bVBAEnabled )
511 : : {
512 [ + - ]: 4 : if( xIndexAccess.is() )
513 : : {
514 [ + - ]: 4 : sal_uInt32 nParamCount = (sal_uInt32)pPar->Count() - 1;
515 [ - + ]: 4 : if( nParamCount != 1 )
516 : : {
517 [ # # ]: 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
518 : 0 : return pElem;
519 : : }
520 : :
521 : : // get index
522 [ + - ][ + - ]: 4 : sal_Int32 nIndex = pPar->Get( 1 )->GetLong();
523 : 4 : Reference< XInterface > xRet;
524 : : try
525 : : {
526 [ + - ][ + - ]: 4 : Any aAny2 = xIndexAccess->getByIndex( nIndex );
527 : 4 : TypeClass eType = aAny2.getValueType().getTypeClass();
528 [ + - ]: 4 : if( eType == TypeClass_INTERFACE )
529 [ + - ]: 4 : xRet = *(Reference< XInterface >*)aAny2.getValue();
530 : : }
531 [ # # # # ]: 0 : catch (const IndexOutOfBoundsException&)
532 : : {
533 : : // usually expect converting problem
534 [ # # ]: 0 : StarBASIC::Error( SbERR_OUT_OF_RANGE );
535 : : }
536 : :
537 : : // #57847 always create a new variable, else error
538 : : // due to PutObject(NULL) at ReadOnly-properties
539 [ + - ][ + - ]: 4 : pElem = new SbxVariable( SbxVARIANT );
540 [ + - ]: 4 : if( xRet.is() )
541 : : {
542 [ + - ]: 4 : aAny <<= xRet;
543 : :
544 : : // #67173 don't specify a name so that the real class name is entered
545 [ + - ]: 4 : String aName;
546 [ + - ][ + - ]: 4 : SbxObjectRef xWrapper = (SbxObject*)new SbUnoObject( aName, aAny );
[ + - ]
547 [ + - ][ + - ]: 4 : pElem->PutObject( xWrapper );
[ + - ]
548 : : }
549 : : else
550 : : {
551 [ # # ]: 0 : pElem->PutObject( NULL );
552 : 4 : }
553 : : }
554 : : }
555 : : else
556 : : {
557 : 0 : rtl::OUString sDefaultMethod;
558 : :
559 [ # # ]: 0 : Reference< XDefaultMethod > xDfltMethod( x, UNO_QUERY );
560 : :
561 [ # # ]: 0 : if ( xDfltMethod.is() )
562 [ # # ][ # # ]: 0 : sDefaultMethod = xDfltMethod->getDefaultMethodName();
563 [ # # ]: 0 : else if( xIndexAccess.is() )
564 [ # # ]: 0 : sDefaultMethod = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getByIndex" ) );
565 : :
566 [ # # ]: 0 : if ( !sDefaultMethod.isEmpty() )
567 : : {
568 [ # # ]: 0 : SbxVariable* meth = pUnoObj->Find( sDefaultMethod, SbxCLASS_METHOD );
569 : 0 : SbxVariableRef refTemp = meth;
570 [ # # ]: 0 : if ( refTemp )
571 : : {
572 [ # # ]: 0 : meth->SetParameters( pPar );
573 [ # # ][ # # ]: 0 : SbxVariable* pNew = new SbxMethod( *(SbxMethod*)meth );
574 : 0 : pElem = pNew;
575 [ # # ]: 0 : }
576 : 4 : }
577 [ - + ][ + - ]: 4 : }
578 : : }
579 : :
580 : : // #42940, set parameter 0 to NULL so that var doesn't contain itself
581 [ + - ][ + - ]: 4 : pPar->Put( NULL, 0 );
582 : : }
583 [ # # ][ # # ]: 0 : else if( pObj->ISA(BasicCollection) )
[ # # ]
584 : : {
585 : 0 : BasicCollection* pCol = (BasicCollection*)(SbxBase*)pObj;
586 [ # # ][ # # ]: 0 : pElem = new SbxVariable( SbxVARIANT );
587 [ # # ]: 0 : pPar->Put( pElem, 0 );
588 [ # # ]: 0 : pCol->CollItem( pPar );
589 : : }
590 : : }
591 [ - + ]: 56 : else if( bVBAEnabled ) // !pObj
592 : : {
593 [ # # ]: 0 : SbxArray* pParam = pElem->GetParameters();
594 [ # # ][ # # ]: 0 : if( pParam != NULL && !pElem->IsSet( SBX_VAR_TO_DIM ) )
[ # # ]
595 [ # # ]: 60 : Error( SbERR_NO_OBJECT );
596 [ + - ][ + - ]: 60 : }
597 : : }
598 : : }
599 : :
600 : 15022 : return pElem;
601 : : }
602 : :
603 : : // loading an element from the runtime-library (+StringID+type)
604 : :
605 : 658 : void SbiRuntime::StepRTL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
606 : : {
607 : 658 : PushVar( FindElement( rBasic.pRtl, nOp1, nOp2, SbERR_PROC_UNDEFINED, false ) );
608 : 658 : }
609 : :
610 : : void
611 : 10944 : SbiRuntime::StepFIND_Impl( SbxObject* pObj, sal_uInt32 nOp1, sal_uInt32 nOp2, SbError nNotFound, bool bLocal, bool bStatic )
612 : : {
613 [ + + ]: 10944 : if( !refLocals )
614 [ + - ]: 340 : refLocals = new SbxArray;
615 : 10944 : PushVar( FindElement( pObj, nOp1, nOp2, nNotFound, bLocal, bStatic ) );
616 : 10944 : }
617 : : // loading a local/global variable (+StringID+type)
618 : :
619 : 10944 : void SbiRuntime::StepFIND( sal_uInt32 nOp1, sal_uInt32 nOp2 )
620 : : {
621 : 10944 : StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, true );
622 : 10944 : }
623 : :
624 : : // Search inside a class module (CM) to enable global search in time
625 : 0 : void SbiRuntime::StepFIND_CM( sal_uInt32 nOp1, sal_uInt32 nOp2 )
626 : : {
627 : :
628 [ # # ][ # # ]: 0 : SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pMod);
629 [ # # ]: 0 : if( pClassModuleObject )
630 : 0 : pMod->SetFlag( SBX_GBLSEARCH );
631 : :
632 : 0 : StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, true );
633 : :
634 [ # # ]: 0 : if( pClassModuleObject )
635 : 0 : pMod->ResetFlag( SBX_GBLSEARCH );
636 : 0 : }
637 : :
638 : 0 : void SbiRuntime::StepFIND_STATIC( sal_uInt32 nOp1, sal_uInt32 nOp2 )
639 : : {
640 : 0 : StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, true, true );
641 : 0 : }
642 : :
643 : : // loading an object-element (+StringID+type)
644 : : // the object lies on TOS
645 : :
646 : 751 : void SbiRuntime::StepELEM( sal_uInt32 nOp1, sal_uInt32 nOp2 )
647 : : {
648 [ + - ]: 751 : SbxVariableRef pObjVar = PopVar();
649 : :
650 [ + - ][ + - ]: 751 : SbxObject* pObj = PTR_CAST(SbxObject,(SbxVariable*) pObjVar);
[ + - ][ + + ]
651 [ + + ]: 751 : if( !pObj )
652 : : {
653 [ + - ]: 653 : SbxBase* pObjVarObj = pObjVar->GetObject();
654 [ + - ][ + - ]: 653 : pObj = PTR_CAST(SbxObject,pObjVarObj);
[ + - ][ + - ]
655 : : }
656 : :
657 : : // #56368 save reference at StepElem, otherwise objects could
658 : : // lose their reference too early in qualification chains like
659 : : // ActiveComponent.Selection(0).Text
660 : : // #74254 now per list
661 [ + - ]: 751 : if( pObj )
662 [ + - ]: 751 : SaveRef( (SbxVariable*)pObj );
663 : :
664 [ + - ][ + - ]: 751 : PushVar( FindElement( pObj, nOp1, nOp2, SbERR_NO_METHOD, false ) );
[ + - ]
665 : 751 : }
666 : :
667 : : // loading a parameter (+offset+type)
668 : : // If the data type is wrong, create a copy.
669 : : // The data type SbxEMPTY shows that no parameters are given.
670 : : // Get( 0 ) may be EMPTY
671 : :
672 : 2669 : void SbiRuntime::StepPARAM( sal_uInt32 nOp1, sal_uInt32 nOp2 )
673 : : {
674 : 2669 : sal_uInt16 i = static_cast<sal_uInt16>( nOp1 & 0x7FFF );
675 : 2669 : SbxDataType t = (SbxDataType) nOp2;
676 : : SbxVariable* p;
677 : :
678 : : // #57915 solve missing in a cleaner way
679 : 2669 : sal_uInt16 nParamCount = refParams->Count();
680 [ - + ]: 2669 : if( i >= nParamCount )
681 : : {
682 : 0 : sal_Int16 iLoop = i;
683 [ # # ]: 0 : while( iLoop >= nParamCount )
684 : : {
685 [ # # ]: 0 : p = new SbxVariable();
686 : :
687 [ # # ][ # # ]: 0 : if( SbiRuntime::isVBAEnabled() &&
[ # # ][ # # ]
688 : : (t == SbxOBJECT || t == SbxSTRING) )
689 : : {
690 [ # # ]: 0 : if( t == SbxOBJECT )
691 : 0 : p->PutObject( NULL );
692 : : else
693 [ # # ][ # # ]: 0 : p->PutString( String() );
694 : : }
695 : : else
696 : 0 : p->PutErr( 448 ); // like in VB: Error-Code 448 (SbERR_NAMED_NOT_FOUND)
697 : :
698 : 0 : refParams->Put( p, iLoop );
699 : 0 : iLoop--;
700 : : }
701 : : }
702 : 2669 : p = refParams->Get( i );
703 : :
704 [ # # ][ - + ]: 2669 : if( p->GetType() == SbxERROR && ( i ) )
[ - + ]
705 : : {
706 : : // if there's a parameter missing, it can be OPTIONAL
707 : 0 : bool bOpt = false;
708 [ # # ]: 0 : if( pMeth )
709 : : {
710 : 0 : SbxInfo* pInfo = pMeth->GetInfo();
711 [ # # ]: 0 : if ( pInfo )
712 : : {
713 : 0 : const SbxParamInfo* pParam = pInfo->GetParam( i );
714 [ # # ][ # # ]: 0 : if( pParam && ( (pParam->nFlags & SBX_OPTIONAL) != 0 ) )
715 : : {
716 : : // Default value?
717 : : sal_uInt16 nDefaultId = sal::static_int_cast< sal_uInt16 >(
718 : 0 : pParam->nUserData & 0xffff );
719 [ # # ]: 0 : if( nDefaultId > 0 )
720 : : {
721 [ # # ]: 0 : String aDefaultStr = pImg->GetString( nDefaultId );
722 [ # # ][ # # ]: 0 : p = new SbxVariable();
723 [ # # ][ # # ]: 0 : p->PutString( aDefaultStr );
724 [ # # ][ # # ]: 0 : refParams->Put( p, i );
725 : : }
726 : 0 : bOpt = true;
727 : : }
728 : : }
729 : : }
730 [ # # ]: 0 : if( !bOpt )
731 : 0 : Error( SbERR_NOT_OPTIONAL );
732 : : }
733 [ + + ][ + + ]: 2669 : else if( t != SbxVARIANT && (SbxDataType)(p->GetType() & 0x0FFF ) != t )
[ + + ]
734 : : {
735 [ + - ]: 12 : SbxVariable* q = new SbxVariable( t );
736 : 12 : SaveRef( q );
737 : 12 : *q = *p;
738 : 12 : p = q;
739 [ - + ]: 12 : if ( i )
740 : 0 : refParams->Put( p, i );
741 : : }
742 : 2669 : SetupArgs( p, nOp1 );
743 : 2669 : PushVar( CheckArray( p ) );
744 : 2669 : }
745 : :
746 : : // Case-Test (+True-Target+Test-Opcode)
747 : :
748 : 2098 : void SbiRuntime::StepCASEIS( sal_uInt32 nOp1, sal_uInt32 nOp2 )
749 : : {
750 [ + - ][ - + ]: 2098 : if( !refCaseStk || !refCaseStk->Count() )
[ - + ]
751 : 0 : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
752 : : else
753 : : {
754 [ + - ]: 2098 : SbxVariableRef xComp = PopVar();
755 [ + - ][ + - ]: 2098 : SbxVariableRef xCase = refCaseStk->Get( refCaseStk->Count() - 1 );
756 [ + + ][ + - ]: 2098 : if( xCase->Compare( (SbxOperator) nOp2, *xComp ) )
757 [ + - ][ + - ]: 2098 : StepJUMP( nOp1 );
[ + - ]
758 : : }
759 : 2098 : }
760 : :
761 : : // call of a DLL-procedure (+StringID+type)
762 : : // the StringID's MSB shows that Argv is occupied
763 : :
764 : 0 : void SbiRuntime::StepCALL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
765 : : {
766 [ # # ]: 0 : String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) );
767 : 0 : SbxArray* pArgs = NULL;
768 [ # # ]: 0 : if( nOp1 & 0x8000 )
769 : 0 : pArgs = refArgv;
770 [ # # ]: 0 : DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, false );
771 [ # # ][ # # ]: 0 : aLibName = String();
[ # # ]
772 [ # # ]: 0 : if( nOp1 & 0x8000 )
773 [ # # ][ # # ]: 0 : PopArgv();
774 : 0 : }
775 : :
776 : : // call of a DLL-procedure after CDecl (+StringID+type)
777 : :
778 : 0 : void SbiRuntime::StepCALLC( sal_uInt32 nOp1, sal_uInt32 nOp2 )
779 : : {
780 [ # # ]: 0 : String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) );
781 : 0 : SbxArray* pArgs = NULL;
782 [ # # ]: 0 : if( nOp1 & 0x8000 )
783 : 0 : pArgs = refArgv;
784 [ # # ]: 0 : DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, true );
785 [ # # ][ # # ]: 0 : aLibName = String();
[ # # ]
786 [ # # ]: 0 : if( nOp1 & 0x8000 )
787 [ # # ][ # # ]: 0 : PopArgv();
788 : 0 : }
789 : :
790 : :
791 : : // beginning of a statement (+Line+Col)
792 : :
793 : 9754 : void SbiRuntime::StepSTMNT( sal_uInt32 nOp1, sal_uInt32 nOp2 )
794 : : {
795 : : // If the Expr-Stack at the beginning of a statement constains a variable,
796 : : // some fool has called X as a function, although it's a variable!
797 : 9754 : bool bFatalExpr = false;
798 [ + - ]: 9754 : String sUnknownMethodName;
799 [ - + ]: 9754 : if( nExprLvl > 1 )
800 : 0 : bFatalExpr = true;
801 [ + + ]: 9754 : else if( nExprLvl )
802 : : {
803 [ + - ]: 428 : SbxVariable* p = refExprStk->Get( 0 );
804 [ - + # # ]: 856 : if( p->GetRefCount() > 1
[ # # ][ - + ]
805 [ # # ][ # # ]: 428 : && refLocals.Is() && refLocals->Find( p->GetName(), p->GetClass() ) )
[ # # ][ # # ]
[ - + ][ # # ]
806 : : {
807 [ # # ][ # # ]: 0 : sUnknownMethodName = p->GetName();
808 : 0 : bFatalExpr = true;
809 : : }
810 : : }
811 : :
812 [ + - ]: 9754 : ClearExprStack();
813 : :
814 [ + - ]: 9754 : ClearRefs();
815 : :
816 : : // We have to cancel hard here because line and column
817 : : // would be wrong later otherwise!
818 [ - + ]: 9754 : if( bFatalExpr)
819 : : {
820 [ # # ]: 0 : StarBASIC::FatalError( SbERR_NO_METHOD, sUnknownMethodName );
821 : 9754 : return;
822 : : }
823 : 9754 : pStmnt = pCode - 9;
824 : 9754 : sal_uInt16 nOld = nLine;
825 : 9754 : nLine = static_cast<short>( nOp1 );
826 : :
827 : : // #29955 & 0xFF, to filter out for-loop-level
828 : 9754 : nCol1 = static_cast<short>( nOp2 & 0xFF );
829 : :
830 : : // find the next STMNT-command to set the final column
831 : : // of this statement
832 : :
833 : 9754 : nCol2 = 0xffff;
834 : : sal_uInt16 n1, n2;
835 [ + - ]: 9754 : const sal_uInt8* p = pMod->FindNextStmnt( pCode, n1, n2 );
836 [ + + ]: 9754 : if( p )
837 : : {
838 [ + + ]: 9679 : if( n1 == nOp1 )
839 : : {
840 : : // #29955 & 0xFF, to filter out for-loop-level
841 : 70 : nCol2 = (n2 & 0xFF) - 1;
842 : : }
843 : : }
844 : :
845 : : // #29955 correct for-loop-level, #67452 NOT in the error-handler
846 [ + + ]: 9754 : if( !bInError )
847 : : {
848 : : // (there's a difference here in case of a jump out of a loop)
849 : 9742 : sal_uInt16 nExspectedForLevel = static_cast<sal_uInt16>( nOp2 / 0x100 );
850 [ - + ]: 9742 : if( pGosubStk )
851 : 0 : nExspectedForLevel = nExspectedForLevel + pGosubStk->nStartForLvl;
852 : :
853 : : // if the actual for-level is too small it'd jump out
854 : : // of a loop -> corrected
855 [ - + ]: 9742 : while( nForLvl > nExspectedForLevel )
856 [ # # ]: 0 : PopFor();
857 : : }
858 : :
859 : : // 16.10.96: #31460 new concept for StepInto/Over/Out
860 : : // see explanation at _ImplGetBreakCallLevel
861 [ - + ]: 9754 : if( pInst->nCallLvl <= pInst->nBreakCallLvl )
862 : : {
863 [ # # ]: 0 : StarBASIC* pStepBasic = GetCurrentBasic( &rBasic );
864 [ # # ]: 0 : sal_uInt16 nNewFlags = pStepBasic->StepPoint( nLine, nCol1, nCol2 );
865 : :
866 [ # # ]: 0 : pInst->CalcBreakCallLevel( nNewFlags );
867 : : }
868 : :
869 : : // break points only at STMNT-commands in a new line!
870 [ + - ][ - + ]: 9754 : else if( ( nOp1 != nOld )
[ # # ][ - + ]
871 : : && ( nFlags & SbDEBUG_BREAK )
872 [ # # ]: 0 : && pMod->IsBP( static_cast<sal_uInt16>( nOp1 ) ) )
873 : : {
874 [ # # ]: 0 : StarBASIC* pBreakBasic = GetCurrentBasic( &rBasic );
875 [ # # ]: 0 : sal_uInt16 nNewFlags = pBreakBasic->BreakPoint( nLine, nCol1, nCol2 );
876 : :
877 [ # # ]: 9754 : pInst->CalcBreakCallLevel( nNewFlags );
878 [ + - ][ + - ]: 9754 : }
879 : : }
880 : :
881 : : // (+SvStreamFlags+Flags)
882 : : // Stack: block length
883 : : // channel number
884 : : // file name
885 : :
886 : 24 : void SbiRuntime::StepOPEN( sal_uInt32 nOp1, sal_uInt32 nOp2 )
887 : : {
888 [ + - ]: 24 : SbxVariableRef pName = PopVar();
889 [ + - ]: 24 : SbxVariableRef pChan = PopVar();
890 [ + - ]: 24 : SbxVariableRef pLen = PopVar();
891 [ + - ]: 24 : short nBlkLen = pLen->GetInteger();
892 [ + - ]: 24 : short nChan = pChan->GetInteger();
893 [ + - ][ + - ]: 24 : rtl::OString aName(rtl::OUStringToOString(pName->GetString(), osl_getThreadTextEncoding()));
[ + - ][ + - ]
894 : : pIosys->Open( nChan, aName, static_cast<short>( nOp1 ),
895 [ + - ]: 24 : static_cast<short>( nOp2 ), nBlkLen );
896 [ + - ][ + - ]: 24 : Error( pIosys->GetError() );
[ + - ][ + - ]
[ + - ]
897 : 24 : }
898 : :
899 : : // create object (+StringID+StringID)
900 : :
901 : 20 : void SbiRuntime::StepCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 )
902 : : {
903 [ + - ]: 20 : String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
904 [ + - ][ + - ]: 20 : SbxObject *pObj = SbxBase::CreateObject( aClass );
905 [ - + ]: 20 : if( !pObj )
906 [ # # ]: 0 : Error( SbERR_INVALID_OBJECT );
907 : : else
908 : : {
909 [ + - ]: 20 : String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
910 [ + - ]: 20 : pObj->SetName( aName );
911 : : // the object must be able to call the BASIC
912 [ + - ]: 20 : pObj->SetParent( &rBasic );
913 [ + - ][ + - ]: 20 : SbxVariable* pNew = new SbxVariable;
914 [ + - ]: 20 : pNew->PutObject( pObj );
915 [ + - ][ + - ]: 20 : PushVar( pNew );
916 [ + - ]: 20 : }
917 : 20 : }
918 : :
919 : 12 : void SbiRuntime::StepDCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 )
920 : : {
921 : 12 : StepDCREATE_IMPL( nOp1, nOp2 );
922 : 12 : }
923 : :
924 : 0 : void SbiRuntime::StepDCREATE_REDIMP( sal_uInt32 nOp1, sal_uInt32 nOp2 )
925 : : {
926 : 0 : StepDCREATE_IMPL( nOp1, nOp2 );
927 : 0 : }
928 : :
929 : :
930 : : // Helper function for StepDCREATE_IMPL / bRedimp = true
931 : 0 : void implCopyDimArray_DCREATE( SbxDimArray* pNewArray, SbxDimArray* pOldArray, short nMaxDimIndex,
932 : : short nActualDim, sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
933 : : {
934 : 0 : sal_Int32& ri = pActualIndices[nActualDim];
935 [ # # ]: 0 : for( ri = pLowerBounds[nActualDim] ; ri <= pUpperBounds[nActualDim] ; ri++ )
936 : : {
937 [ # # ]: 0 : if( nActualDim < nMaxDimIndex )
938 : : {
939 : : implCopyDimArray_DCREATE( pNewArray, pOldArray, nMaxDimIndex, nActualDim + 1,
940 : 0 : pActualIndices, pLowerBounds, pUpperBounds );
941 : : }
942 : : else
943 : : {
944 : 0 : SbxVariable* pSource = pOldArray->Get32( pActualIndices );
945 : 0 : pNewArray->Put32( pSource, pActualIndices );
946 : : }
947 : : }
948 : 0 : }
949 : :
950 : : // #56204 create object array (+StringID+StringID), DCREATE == Dim-Create
951 : 12 : void SbiRuntime::StepDCREATE_IMPL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
952 : : {
953 [ + - ]: 12 : SbxVariableRef refVar = PopVar();
954 : :
955 [ + - ][ + - ]: 12 : DimImpl( refVar );
956 : :
957 : : // fill the array with instances of the requested class
958 [ + - ]: 12 : SbxBaseRef xObj = (SbxBase*)refVar->GetObject();
959 [ - + ]: 12 : if( !xObj )
960 : : {
961 [ # # ]: 0 : StarBASIC::Error( SbERR_INVALID_OBJECT );
962 : 12 : return;
963 : : }
964 : :
965 : 12 : SbxDimArray* pArray = 0;
966 [ + - ][ + - ]: 12 : if( xObj->ISA(SbxDimArray) )
[ + - ]
967 : : {
968 : 12 : SbxBase* pObj = (SbxBase*)xObj;
969 : 12 : pArray = (SbxDimArray*)pObj;
970 : :
971 [ + - ]: 12 : short nDims = pArray->GetDims();
972 : 12 : sal_Int32 nTotalSize = 0;
973 : :
974 : : // must be a one-dimensional array
975 : : sal_Int32 nLower, nUpper, nSize;
976 : : sal_Int32 i;
977 [ + + ]: 24 : for( i = 0 ; i < nDims ; i++ )
978 : : {
979 [ + - ]: 12 : pArray->GetDim32( i+1, nLower, nUpper );
980 : 12 : nSize = nUpper - nLower + 1;
981 [ + - ]: 12 : if( i == 0 )
982 : 12 : nTotalSize = nSize;
983 : : else
984 : 0 : nTotalSize *= nSize;
985 : : }
986 : :
987 : : // create objects and insert them into the array
988 [ + - ]: 12 : String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
989 [ + + ]: 16 : for( i = 0 ; i < nTotalSize ; i++ )
990 : : {
991 [ + - ][ + - ]: 4 : SbxObject *pClassObj = SbxBase::CreateObject( aClass );
992 [ - + ]: 4 : if( !pClassObj )
993 : : {
994 [ # # ]: 0 : Error( SbERR_INVALID_OBJECT );
995 : 0 : break;
996 : : }
997 : : else
998 : : {
999 [ + - ]: 4 : String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
1000 [ + - ]: 4 : pClassObj->SetName( aName );
1001 : : // the object must be able to call the basic
1002 [ + - ]: 4 : pClassObj->SetParent( &rBasic );
1003 [ + - ][ + - ]: 4 : pArray->SbxArray::Put32( pClassObj, i );
1004 : : }
1005 [ + - ]: 12 : }
1006 : : }
1007 : :
1008 : 12 : SbxDimArray* pOldArray = (SbxDimArray*)(SbxArray*)refRedimpArray;
1009 [ - + ][ + - ]: 12 : if( pArray && pOldArray )
1010 : : {
1011 [ # # ]: 0 : short nDimsNew = pArray->GetDims();
1012 [ # # ]: 0 : short nDimsOld = pOldArray->GetDims();
1013 : 0 : short nDims = nDimsNew;
1014 : 0 : bool bRangeError = false;
1015 : :
1016 : : // Store dims to use them for copying later
1017 [ # # ]: 0 : sal_Int32* pLowerBounds = new sal_Int32[nDims];
1018 [ # # ]: 0 : sal_Int32* pUpperBounds = new sal_Int32[nDims];
1019 [ # # ]: 0 : sal_Int32* pActualIndices = new sal_Int32[nDims];
1020 [ # # ]: 0 : if( nDimsOld != nDimsNew )
1021 : : {
1022 : 0 : bRangeError = true;
1023 : : }
1024 : : else
1025 : : {
1026 : : // Compare bounds
1027 [ # # ]: 0 : for( short i = 1 ; i <= nDims ; i++ )
1028 : : {
1029 : : sal_Int32 lBoundNew, uBoundNew;
1030 : : sal_Int32 lBoundOld, uBoundOld;
1031 [ # # ]: 0 : pArray->GetDim32( i, lBoundNew, uBoundNew );
1032 [ # # ]: 0 : pOldArray->GetDim32( i, lBoundOld, uBoundOld );
1033 : :
1034 [ # # ]: 0 : lBoundNew = std::max( lBoundNew, lBoundOld );
1035 [ # # ]: 0 : uBoundNew = std::min( uBoundNew, uBoundOld );
1036 : 0 : short j = i - 1;
1037 : 0 : pActualIndices[j] = pLowerBounds[j] = lBoundNew;
1038 : 0 : pUpperBounds[j] = uBoundNew;
1039 : : }
1040 : : }
1041 : :
1042 [ # # ]: 0 : if( bRangeError )
1043 : : {
1044 [ # # ]: 0 : StarBASIC::Error( SbERR_OUT_OF_RANGE );
1045 : : }
1046 : : else
1047 : : {
1048 : : // Copy data from old array by going recursively through all dimensions
1049 : : // (It would be faster to work on the flat internal data array of an
1050 : : // SbyArray but this solution is clearer and easier)
1051 : : implCopyDimArray_DCREATE( pArray, pOldArray, nDims - 1,
1052 [ # # ]: 0 : 0, pActualIndices, pLowerBounds, pUpperBounds );
1053 : : }
1054 [ # # ]: 0 : delete [] pUpperBounds;
1055 [ # # ]: 0 : delete [] pLowerBounds;
1056 [ # # ]: 0 : delete [] pActualIndices;
1057 [ # # ]: 12 : refRedimpArray = NULL;
1058 [ + - ][ - + ]: 12 : }
[ + - ][ + - ]
1059 : : }
1060 : :
1061 : : // create object from user-type (+StringID+StringID)
1062 : :
1063 : : SbxObject* createUserTypeImpl( const String& rClassName ); // sb.cxx
1064 : :
1065 : 0 : void SbiRuntime::StepTCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 )
1066 : : {
1067 [ # # ]: 0 : String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
1068 [ # # ]: 0 : String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
1069 : :
1070 [ # # ]: 0 : SbxObject* pCopyObj = createUserTypeImpl( aClass );
1071 [ # # ]: 0 : if( pCopyObj )
1072 [ # # ]: 0 : pCopyObj->SetName( aName );
1073 [ # # ][ # # ]: 0 : SbxVariable* pNew = new SbxVariable;
1074 [ # # ]: 0 : pNew->PutObject( pCopyObj );
1075 [ # # ]: 0 : pNew->SetDeclareClassName( aClass );
1076 [ # # ][ # # ]: 0 : PushVar( pNew );
[ # # ]
1077 : 0 : }
1078 : :
1079 : 657 : void SbiRuntime::implHandleSbxFlags( SbxVariable* pVar, SbxDataType t, sal_uInt32 nOp2 )
1080 : : {
1081 [ + + ][ - + ]: 657 : bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0);
1082 [ - + ]: 657 : if( bWithEvents )
1083 : 0 : pVar->SetFlag( SBX_WITH_EVENTS );
1084 : :
1085 : 657 : bool bDimAsNew = ((nOp2 & SBX_TYPE_DIM_AS_NEW_FLAG) != 0);
1086 [ - + ]: 657 : if( bDimAsNew )
1087 : 0 : pVar->SetFlag( SBX_DIM_AS_NEW );
1088 : :
1089 [ + + ][ - + ]: 657 : bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0);
1090 [ - + ]: 657 : if( bFixedString )
1091 : : {
1092 : 0 : sal_uInt16 nCount = static_cast<sal_uInt16>( nOp2 >> 17 ); // len = all bits above 0x10000
1093 [ # # ]: 0 : String aStr;
1094 [ # # ]: 0 : aStr.Fill( nCount, 0 );
1095 [ # # ][ # # ]: 0 : pVar->PutString( aStr );
[ # # ]
1096 : : }
1097 : :
1098 : 657 : bool bVarToDim = ((nOp2 & SBX_TYPE_VAR_TO_DIM_FLAG) != 0);
1099 [ + + ]: 657 : if( bVarToDim )
1100 : 64 : pVar->SetFlag( SBX_VAR_TO_DIM );
1101 : 657 : }
1102 : :
1103 : : // establishing a local variable (+StringID+type)
1104 : :
1105 : 647 : void SbiRuntime::StepLOCAL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
1106 : : {
1107 [ + + ]: 647 : if( !refLocals.Is() )
1108 [ + - ][ + - ]: 339 : refLocals = new SbxArray;
[ + - ]
1109 [ + - ]: 647 : String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
1110 [ + - ][ + - ]: 647 : if( refLocals->Find( aName, SbxCLASS_DONTCARE ) == NULL )
[ + - ]
1111 : : {
1112 : 647 : SbxDataType t = (SbxDataType)(nOp2 & 0xffff);
1113 [ + - ][ + - ]: 647 : SbxVariable* p = new SbxVariable( t );
1114 [ + - ]: 647 : p->SetName( aName );
1115 [ + - ]: 647 : implHandleSbxFlags( p, t, nOp2 );
1116 [ + - ][ + - ]: 647 : refLocals->Put( p, refLocals->Count() );
1117 [ + - ]: 647 : }
1118 : 647 : }
1119 : :
1120 : : // establishing a module-global variable (+StringID+type)
1121 : :
1122 : 10 : void SbiRuntime::StepPUBLIC_Impl( sal_uInt32 nOp1, sal_uInt32 nOp2, bool bUsedForClassModule )
1123 : : {
1124 [ + - ]: 10 : String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
1125 : 10 : SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);;
1126 : 10 : sal_Bool bFlag = pMod->IsSet( SBX_NO_MODIFY );
1127 : 10 : pMod->SetFlag( SBX_NO_MODIFY );
1128 [ + - ][ + - ]: 10 : SbxVariableRef p = pMod->Find( aName, SbxCLASS_PROPERTY );
1129 [ - + ]: 10 : if( p.Is() )
1130 [ # # ]: 0 : pMod->Remove (p);
1131 [ + - ]: 10 : SbProperty* pProp = pMod->GetProperty( aName, t );
1132 [ + - ]: 10 : if( !bUsedForClassModule )
1133 : 10 : pProp->SetFlag( SBX_PRIVATE );
1134 [ + - ]: 10 : if( !bFlag )
1135 : 10 : pMod->ResetFlag( SBX_NO_MODIFY );
1136 [ + - ]: 10 : if( pProp )
1137 : : {
1138 : 10 : pProp->SetFlag( SBX_DONTSTORE );
1139 : : // from 2.7.1996: HACK because of 'reference can't be saved'
1140 : 10 : pProp->SetFlag( SBX_NO_MODIFY);
1141 : :
1142 [ + - ]: 10 : implHandleSbxFlags( pProp, t, nOp2 );
1143 [ + - ][ + - ]: 10 : }
1144 : 10 : }
1145 : :
1146 : 2 : void SbiRuntime::StepPUBLIC( sal_uInt32 nOp1, sal_uInt32 nOp2 )
1147 : : {
1148 : 2 : StepPUBLIC_Impl( nOp1, nOp2, false );
1149 : 2 : }
1150 : :
1151 : 8 : void SbiRuntime::StepPUBLIC_P( sal_uInt32 nOp1, sal_uInt32 nOp2 )
1152 : : {
1153 : : // Creates module variable that isn't reinitialised when
1154 : : // between invocations ( for VBASupport & document basic only )
1155 [ + - ]: 8 : if( pMod->pImage->bFirstInit )
1156 : : {
1157 : 8 : bool bUsedForClassModule = pImg->GetFlag( SBIMG_CLASSMODULE );
1158 : 8 : StepPUBLIC_Impl( nOp1, nOp2, bUsedForClassModule );
1159 : : }
1160 : 8 : }
1161 : :
1162 : : // establishing a global variable (+StringID+type)
1163 : :
1164 : 244 : void SbiRuntime::StepGLOBAL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
1165 : : {
1166 [ - + ]: 244 : if( pImg->GetFlag( SBIMG_CLASSMODULE ) )
1167 [ # # ]: 0 : StepPUBLIC_Impl( nOp1, nOp2, true );
1168 : :
1169 [ + - ]: 244 : String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
1170 : 244 : SbxDataType t = (SbxDataType)(nOp2 & 0xffff);
1171 : :
1172 : : // Store module scope variables at module scope
1173 : : // in non vba mode these are stored at the library level :/
1174 : : // not sure if this really should not be enabled for ALL basic
1175 : 244 : SbxObject* pStorage = &rBasic;
1176 [ + - ][ - + ]: 244 : if ( SbiRuntime::isVBAEnabled() )
1177 : : {
1178 : 0 : pStorage = pMod;
1179 [ # # ]: 0 : pMod->AddVarName( aName );
1180 : : }
1181 : :
1182 : 244 : sal_Bool bFlag = pStorage->IsSet( SBX_NO_MODIFY );
1183 : 244 : rBasic.SetFlag( SBX_NO_MODIFY );
1184 [ + - ][ + - ]: 244 : SbxVariableRef p = pStorage->Find( aName, SbxCLASS_PROPERTY );
1185 [ - + ]: 244 : if( p.Is() )
1186 [ # # ]: 0 : pStorage->Remove (p);
1187 [ + - ][ + - ]: 244 : p = pStorage->Make( aName, SbxCLASS_PROPERTY, t );
1188 [ + - ]: 244 : if( !bFlag )
1189 : 244 : pStorage->ResetFlag( SBX_NO_MODIFY );
1190 [ + - ]: 244 : if( p )
1191 : : {
1192 : 244 : p->SetFlag( SBX_DONTSTORE );
1193 : : // from 2.7.1996: HACK because of 'reference can't be saved'
1194 : 244 : p->SetFlag( SBX_NO_MODIFY);
1195 [ + - ][ + - ]: 244 : }
1196 : 244 : }
1197 : :
1198 : :
1199 : : // Creates global variable that isn't reinitialised when
1200 : : // basic is restarted, P=PERSIST (+StringID+Typ)
1201 : :
1202 : 244 : void SbiRuntime::StepGLOBAL_P( sal_uInt32 nOp1, sal_uInt32 nOp2 )
1203 : : {
1204 [ + - ]: 244 : if( pMod->pImage->bFirstInit )
1205 : : {
1206 : 244 : StepGLOBAL( nOp1, nOp2 );
1207 : : }
1208 : 244 : }
1209 : :
1210 : :
1211 : : // Searches for global variable, behavior depends on the fact
1212 : : // if the variable is initialised for the first time
1213 : :
1214 : 4 : void SbiRuntime::StepFIND_G( sal_uInt32 nOp1, sal_uInt32 nOp2 )
1215 : : {
1216 [ + - ]: 4 : if( pMod->pImage->bFirstInit )
1217 : : {
1218 : : // Behave like always during first init
1219 : 4 : StepFIND( nOp1, nOp2 );
1220 : : }
1221 : : else
1222 : : {
1223 : : // Return dummy variable
1224 : 0 : SbxDataType t = (SbxDataType) nOp2;
1225 [ # # ]: 0 : String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) );
1226 : :
1227 [ # # ][ # # ]: 0 : SbxVariable* pDummyVar = new SbxVariable( t );
1228 [ # # ]: 0 : pDummyVar->SetName( aName );
1229 [ # # ][ # # ]: 0 : PushVar( pDummyVar );
1230 : : }
1231 : 4 : }
1232 : :
1233 : :
1234 : 0 : SbxVariable* SbiRuntime::StepSTATIC_Impl( String& aName, SbxDataType& t )
1235 : : {
1236 : 0 : SbxVariable* p = NULL;
1237 [ # # ]: 0 : if ( pMeth )
1238 : : {
1239 : 0 : SbxArray* pStatics = pMeth->GetStatics();
1240 [ # # ][ # # ]: 0 : if( pStatics && ( pStatics->Find( aName, SbxCLASS_DONTCARE ) == NULL ) )
[ # # ][ # # ]
[ # # # # ]
[ # # ]
1241 : : {
1242 [ # # ]: 0 : p = new SbxVariable( t );
1243 [ # # ]: 0 : if( t != SbxVARIANT )
1244 : 0 : p->SetFlag( SBX_FIXED );
1245 : 0 : p->SetName( aName );
1246 : 0 : pStatics->Put( p, pStatics->Count() );
1247 : : }
1248 : : }
1249 : 0 : return p;
1250 : : }
1251 : : // establishing a static variable (+StringID+type)
1252 : 0 : void SbiRuntime::StepSTATIC( sal_uInt32 nOp1, sal_uInt32 nOp2 )
1253 : : {
1254 [ # # ]: 0 : String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
1255 : 0 : SbxDataType t = (SbxDataType) nOp2;
1256 [ # # ][ # # ]: 0 : StepSTATIC_Impl( aName, t );
1257 : 0 : }
1258 : :
1259 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|