xref: /AOO41X/main/basic/source/runtime/step0.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_basic.hxx"
30*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
31*cdf0e10cSrcweir #include <tools/fsys.hxx>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "errobject.hxx"
34*cdf0e10cSrcweir #include "runtime.hxx"
35*cdf0e10cSrcweir #include "sbintern.hxx"
36*cdf0e10cSrcweir #include "iosys.hxx"
37*cdf0e10cSrcweir #include <sb.hrc>
38*cdf0e10cSrcweir #include <basrid.hxx>
39*cdf0e10cSrcweir #include "sbunoobj.hxx"
40*cdf0e10cSrcweir #include "image.hxx"
41*cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx>
42*cdf0e10cSrcweir #include <com/sun/star/util/SearchOptions.hdl>
43*cdf0e10cSrcweir #include <vcl/svapp.hxx>
44*cdf0e10cSrcweir #include <unotools/textsearch.hxx>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::OUString& aVBAType,
47*cdf0e10cSrcweir 										   const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj );
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir #include <algorithm>
50*cdf0e10cSrcweir #include <hash_map>
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir SbxVariable* getDefaultProp( SbxVariable* pRef );
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir void SbiRuntime::StepNOP()
55*cdf0e10cSrcweir {}
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir void SbiRuntime::StepArith( SbxOperator eOp )
58*cdf0e10cSrcweir {
59*cdf0e10cSrcweir 	SbxVariableRef p1 = PopVar();
60*cdf0e10cSrcweir 	TOSMakeTemp();
61*cdf0e10cSrcweir 	SbxVariable* p2 = GetTOS();
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir 	// This could & should be moved to the MakeTempTOS() method in runtime.cxx
65*cdf0e10cSrcweir 	// In the code which this is cut'npaste from there is a check for a ref
66*cdf0e10cSrcweir 	// count != 1 based on which the copy of the SbxVariable is done.
67*cdf0e10cSrcweir 	// see orig code in MakeTempTOS ( and I'm not sure what the significance,
68*cdf0e10cSrcweir 	// of that is )
69*cdf0e10cSrcweir 	// here we alway seem to have a refcount of 1. Also it seems that
70*cdf0e10cSrcweir 	// MakeTempTOS is called for other operation, so I hold off for now
71*cdf0e10cSrcweir 	// until I have a better idea
72*cdf0e10cSrcweir 	if ( bVBAEnabled
73*cdf0e10cSrcweir 		&& ( p2->GetType() == SbxOBJECT || p2->GetType() == SbxVARIANT )
74*cdf0e10cSrcweir 	)
75*cdf0e10cSrcweir 	{
76*cdf0e10cSrcweir 		SbxVariable* pDflt = getDefaultProp( p2 );
77*cdf0e10cSrcweir 		if ( pDflt )
78*cdf0e10cSrcweir 		{
79*cdf0e10cSrcweir 			pDflt->Broadcast( SBX_HINT_DATAWANTED );
80*cdf0e10cSrcweir 			// replacing new p2 on stack causes object pointed by
81*cdf0e10cSrcweir 			// pDft->pParent to be deleted, when p2->Compute() is
82*cdf0e10cSrcweir 			// called below pParent is accessed ( but its deleted )
83*cdf0e10cSrcweir 			// so set it to NULL now
84*cdf0e10cSrcweir 			pDflt->SetParent( NULL );
85*cdf0e10cSrcweir 			p2 = new SbxVariable( *pDflt );
86*cdf0e10cSrcweir 			p2->SetFlag( SBX_READWRITE );
87*cdf0e10cSrcweir 			refExprStk->Put( p2, nExprLvl - 1 );
88*cdf0e10cSrcweir 		}
89*cdf0e10cSrcweir 	}
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir 	p2->ResetFlag( SBX_FIXED );
92*cdf0e10cSrcweir 	p2->Compute( eOp, *p1 );
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir     checkArithmeticOverflow( p2 );
95*cdf0e10cSrcweir }
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir void SbiRuntime::StepUnary( SbxOperator eOp )
98*cdf0e10cSrcweir {
99*cdf0e10cSrcweir 	TOSMakeTemp();
100*cdf0e10cSrcweir 	SbxVariable* p = GetTOS();
101*cdf0e10cSrcweir 	p->Compute( eOp, *p );
102*cdf0e10cSrcweir }
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir void SbiRuntime::StepCompare( SbxOperator eOp )
105*cdf0e10cSrcweir {
106*cdf0e10cSrcweir 	SbxVariableRef p1 = PopVar();
107*cdf0e10cSrcweir 	SbxVariableRef p2 = PopVar();
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir 	// Make sure objects with default params have
110*cdf0e10cSrcweir 	// values ( and type ) set as appropriate
111*cdf0e10cSrcweir 	SbxDataType p1Type = p1->GetType();
112*cdf0e10cSrcweir 	SbxDataType p2Type = p2->GetType();
113*cdf0e10cSrcweir 	if ( p1Type == p2Type )
114*cdf0e10cSrcweir 	{
115*cdf0e10cSrcweir 		if ( p1Type == SbxEMPTY )
116*cdf0e10cSrcweir 		{
117*cdf0e10cSrcweir 			p1->Broadcast( SBX_HINT_DATAWANTED );
118*cdf0e10cSrcweir 			p2->Broadcast( SBX_HINT_DATAWANTED );
119*cdf0e10cSrcweir 		}
120*cdf0e10cSrcweir 		// if both sides are an object and have default props
121*cdf0e10cSrcweir 		// then we need to use the default props
122*cdf0e10cSrcweir 		// we don't need to worry if only one side ( lhs, rhs ) is an
123*cdf0e10cSrcweir 		// object ( object side will get coerced to correct type in
124*cdf0e10cSrcweir 		// Compare )
125*cdf0e10cSrcweir 		else if ( p1Type ==  SbxOBJECT )
126*cdf0e10cSrcweir 		{
127*cdf0e10cSrcweir 			SbxVariable* pDflt = getDefaultProp( p1 );
128*cdf0e10cSrcweir 			if ( pDflt )
129*cdf0e10cSrcweir 			{
130*cdf0e10cSrcweir 				p1 = pDflt;
131*cdf0e10cSrcweir 				p1->Broadcast( SBX_HINT_DATAWANTED );
132*cdf0e10cSrcweir 			}
133*cdf0e10cSrcweir 			pDflt = getDefaultProp( p2 );
134*cdf0e10cSrcweir 			if ( pDflt )
135*cdf0e10cSrcweir 			{
136*cdf0e10cSrcweir 				p2 = pDflt;
137*cdf0e10cSrcweir 				p2->Broadcast( SBX_HINT_DATAWANTED );
138*cdf0e10cSrcweir 			}
139*cdf0e10cSrcweir 		}
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir 	}
142*cdf0e10cSrcweir 	static SbxVariable* pTRUE = NULL;
143*cdf0e10cSrcweir 	static SbxVariable* pFALSE = NULL;
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir 	if( p2->Compare( eOp, *p1 ) )
146*cdf0e10cSrcweir 	{
147*cdf0e10cSrcweir 		if( !pTRUE )
148*cdf0e10cSrcweir 		{
149*cdf0e10cSrcweir 			pTRUE = new SbxVariable;
150*cdf0e10cSrcweir 			pTRUE->PutBool( sal_True );
151*cdf0e10cSrcweir 			pTRUE->AddRef();
152*cdf0e10cSrcweir 		}
153*cdf0e10cSrcweir 		PushVar( pTRUE );
154*cdf0e10cSrcweir 	}
155*cdf0e10cSrcweir 	else
156*cdf0e10cSrcweir 	{
157*cdf0e10cSrcweir 		if( !pFALSE )
158*cdf0e10cSrcweir 		{
159*cdf0e10cSrcweir 			pFALSE = new SbxVariable;
160*cdf0e10cSrcweir 			pFALSE->PutBool( sal_False );
161*cdf0e10cSrcweir 			pFALSE->AddRef();
162*cdf0e10cSrcweir 		}
163*cdf0e10cSrcweir 		PushVar( pFALSE );
164*cdf0e10cSrcweir 	}
165*cdf0e10cSrcweir }
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir void SbiRuntime::StepEXP()		{ StepArith( SbxEXP );		}
168*cdf0e10cSrcweir void SbiRuntime::StepMUL()		{ StepArith( SbxMUL );		}
169*cdf0e10cSrcweir void SbiRuntime::StepDIV()		{ StepArith( SbxDIV );		}
170*cdf0e10cSrcweir void SbiRuntime::StepIDIV()		{ StepArith( SbxIDIV );		}
171*cdf0e10cSrcweir void SbiRuntime::StepMOD()		{ StepArith( SbxMOD );		}
172*cdf0e10cSrcweir void SbiRuntime::StepPLUS()		{ StepArith( SbxPLUS );		}
173*cdf0e10cSrcweir void SbiRuntime::StepMINUS()		{ StepArith( SbxMINUS );	}
174*cdf0e10cSrcweir void SbiRuntime::StepCAT()		{ StepArith( SbxCAT );		}
175*cdf0e10cSrcweir void SbiRuntime::StepAND()		{ StepArith( SbxAND );		}
176*cdf0e10cSrcweir void SbiRuntime::StepOR()		{ StepArith( SbxOR );		}
177*cdf0e10cSrcweir void SbiRuntime::StepXOR()		{ StepArith( SbxXOR );		}
178*cdf0e10cSrcweir void SbiRuntime::StepEQV()		{ StepArith( SbxEQV );		}
179*cdf0e10cSrcweir void SbiRuntime::StepIMP()		{ StepArith( SbxIMP );		}
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir void SbiRuntime::StepNEG()		{ StepUnary( SbxNEG );		}
182*cdf0e10cSrcweir void SbiRuntime::StepNOT()		{ StepUnary( SbxNOT );		}
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir void SbiRuntime::StepEQ()		{ StepCompare( SbxEQ );		}
185*cdf0e10cSrcweir void SbiRuntime::StepNE()		{ StepCompare( SbxNE );		}
186*cdf0e10cSrcweir void SbiRuntime::StepLT()		{ StepCompare( SbxLT );		}
187*cdf0e10cSrcweir void SbiRuntime::StepGT()		{ StepCompare( SbxGT );		}
188*cdf0e10cSrcweir void SbiRuntime::StepLE()		{ StepCompare( SbxLE );		}
189*cdf0e10cSrcweir void SbiRuntime::StepGE()		{ StepCompare( SbxGE );		}
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir namespace
192*cdf0e10cSrcweir {
193*cdf0e10cSrcweir 	bool NeedEsc(sal_Unicode cCode)
194*cdf0e10cSrcweir 	{
195*cdf0e10cSrcweir 		String sEsc(RTL_CONSTASCII_USTRINGPARAM(".^$+\\|{}()"));
196*cdf0e10cSrcweir 		return (STRING_NOTFOUND != sEsc.Search(cCode));
197*cdf0e10cSrcweir 	}
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir 	String VBALikeToRegexp(const String &rIn)
200*cdf0e10cSrcweir 	{
201*cdf0e10cSrcweir 		String sResult;
202*cdf0e10cSrcweir 		const sal_Unicode *start = rIn.GetBuffer();
203*cdf0e10cSrcweir 		const sal_Unicode *end = start + rIn.Len();
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 		int seenright = 0;
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 		sResult.Append('^');
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir 		while (start < end)
210*cdf0e10cSrcweir 		{
211*cdf0e10cSrcweir 			switch (*start)
212*cdf0e10cSrcweir 			{
213*cdf0e10cSrcweir 				case '?':
214*cdf0e10cSrcweir 					sResult.Append('.');
215*cdf0e10cSrcweir 					start++;
216*cdf0e10cSrcweir 					break;
217*cdf0e10cSrcweir 				case '*':
218*cdf0e10cSrcweir 					sResult.Append(String(RTL_CONSTASCII_USTRINGPARAM(".*")));
219*cdf0e10cSrcweir 					start++;
220*cdf0e10cSrcweir 					break;
221*cdf0e10cSrcweir 				case '#':
222*cdf0e10cSrcweir 					sResult.Append(String(RTL_CONSTASCII_USTRINGPARAM("[0-9]")));
223*cdf0e10cSrcweir 					start++;
224*cdf0e10cSrcweir 					break;
225*cdf0e10cSrcweir 				case ']':
226*cdf0e10cSrcweir 					sResult.Append('\\');
227*cdf0e10cSrcweir 					sResult.Append(*start++);
228*cdf0e10cSrcweir 					break;
229*cdf0e10cSrcweir 				case '[':
230*cdf0e10cSrcweir 					sResult.Append(*start++);
231*cdf0e10cSrcweir 					seenright = 0;
232*cdf0e10cSrcweir 					while (start < end && !seenright)
233*cdf0e10cSrcweir 					{
234*cdf0e10cSrcweir 						switch (*start)
235*cdf0e10cSrcweir 						{
236*cdf0e10cSrcweir 							case '[':
237*cdf0e10cSrcweir 							case '?':
238*cdf0e10cSrcweir 							case '*':
239*cdf0e10cSrcweir 							sResult.Append('\\');
240*cdf0e10cSrcweir 							sResult.Append(*start);
241*cdf0e10cSrcweir 								break;
242*cdf0e10cSrcweir 							case ']':
243*cdf0e10cSrcweir 							sResult.Append(*start);
244*cdf0e10cSrcweir 								seenright = 1;
245*cdf0e10cSrcweir 								break;
246*cdf0e10cSrcweir 							case '!':
247*cdf0e10cSrcweir 								sResult.Append('^');
248*cdf0e10cSrcweir 								break;
249*cdf0e10cSrcweir 							default:
250*cdf0e10cSrcweir 							if (NeedEsc(*start))
251*cdf0e10cSrcweir 									sResult.Append('\\');
252*cdf0e10cSrcweir 							sResult.Append(*start);
253*cdf0e10cSrcweir 								break;
254*cdf0e10cSrcweir 						}
255*cdf0e10cSrcweir 						start++;
256*cdf0e10cSrcweir 					}
257*cdf0e10cSrcweir 					break;
258*cdf0e10cSrcweir 				default:
259*cdf0e10cSrcweir 					if (NeedEsc(*start))
260*cdf0e10cSrcweir 						sResult.Append('\\');
261*cdf0e10cSrcweir 					sResult.Append(*start++);
262*cdf0e10cSrcweir 			}
263*cdf0e10cSrcweir 		}
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir 		sResult.Append('$');
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 		return sResult;
268*cdf0e10cSrcweir 	}
269*cdf0e10cSrcweir }
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir void SbiRuntime::StepLIKE()
272*cdf0e10cSrcweir {
273*cdf0e10cSrcweir     SbxVariableRef refVar1 = PopVar();
274*cdf0e10cSrcweir     SbxVariableRef refVar2 = PopVar();
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir     String pattern = VBALikeToRegexp(refVar1->GetString());
277*cdf0e10cSrcweir     String value = refVar2->GetString();
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir     com::sun::star::util::SearchOptions aSearchOpt;
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir     aSearchOpt.algorithmType = com::sun::star::util::SearchAlgorithms_REGEXP;
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir     aSearchOpt.Locale = Application::GetSettings().GetLocale();
284*cdf0e10cSrcweir     aSearchOpt.searchString = pattern;
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir     int bTextMode(1);
287*cdf0e10cSrcweir     bool bCompatibility = ( pINST && pINST->IsCompatibility() );
288*cdf0e10cSrcweir     if( bCompatibility )
289*cdf0e10cSrcweir         bTextMode = GetImageFlag( SBIMG_COMPARETEXT );
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir     if( bTextMode )
292*cdf0e10cSrcweir         aSearchOpt.transliterateFlags |= com::sun::star::i18n::TransliterationModules_IGNORE_CASE;
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir     SbxVariable* pRes = new SbxVariable;
295*cdf0e10cSrcweir     utl::TextSearch aSearch(aSearchOpt);
296*cdf0e10cSrcweir     xub_StrLen nStart=0, nEnd=value.Len();
297*cdf0e10cSrcweir     int bRes = aSearch.SearchFrwrd(value, &nStart, &nEnd);
298*cdf0e10cSrcweir     pRes->PutBool( bRes != 0 );
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir     PushVar( pRes );
301*cdf0e10cSrcweir }
302*cdf0e10cSrcweir 
303*cdf0e10cSrcweir // TOS und TOS-1 sind beides Objektvariable und enthalten den selben Pointer
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir void SbiRuntime::StepIS()
306*cdf0e10cSrcweir {
307*cdf0e10cSrcweir 	SbxVariableRef refVar1 = PopVar();
308*cdf0e10cSrcweir 	SbxVariableRef refVar2 = PopVar();
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir 	SbxDataType eType1 = refVar1->GetType();
311*cdf0e10cSrcweir 	SbxDataType eType2 = refVar2->GetType();
312*cdf0e10cSrcweir 	if ( eType1 == SbxEMPTY )
313*cdf0e10cSrcweir 	{
314*cdf0e10cSrcweir 		refVar1->Broadcast( SBX_HINT_DATAWANTED );
315*cdf0e10cSrcweir 		eType1 = refVar1->GetType();
316*cdf0e10cSrcweir 	}
317*cdf0e10cSrcweir 	if ( eType2 == SbxEMPTY )
318*cdf0e10cSrcweir 	{
319*cdf0e10cSrcweir 		refVar2->Broadcast( SBX_HINT_DATAWANTED );
320*cdf0e10cSrcweir 		eType2 = refVar2->GetType();
321*cdf0e10cSrcweir 	}
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir 	sal_Bool bRes = sal_Bool( eType1 == SbxOBJECT && eType2 == SbxOBJECT );
324*cdf0e10cSrcweir 	if ( bVBAEnabled  && !bRes )
325*cdf0e10cSrcweir 		Error( SbERR_INVALID_USAGE_OBJECT );
326*cdf0e10cSrcweir 	bRes = ( bRes && refVar1->GetObject() == refVar2->GetObject() );
327*cdf0e10cSrcweir 	SbxVariable* pRes = new SbxVariable;
328*cdf0e10cSrcweir 	pRes->PutBool( bRes );
329*cdf0e10cSrcweir 	PushVar( pRes );
330*cdf0e10cSrcweir }
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir // Aktualisieren des Wertes von TOS
333*cdf0e10cSrcweir 
334*cdf0e10cSrcweir void SbiRuntime::StepGET()
335*cdf0e10cSrcweir {
336*cdf0e10cSrcweir 	SbxVariable* p = GetTOS();
337*cdf0e10cSrcweir 	p->Broadcast( SBX_HINT_DATAWANTED );
338*cdf0e10cSrcweir }
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir // #67607 Uno-Structs kopieren
341*cdf0e10cSrcweir inline void checkUnoStructCopy( SbxVariableRef& refVal, SbxVariableRef& refVar )
342*cdf0e10cSrcweir {
343*cdf0e10cSrcweir 	SbxDataType eVarType = refVar->GetType();
344*cdf0e10cSrcweir 	if( eVarType != SbxOBJECT )
345*cdf0e10cSrcweir         return;
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir 	SbxObjectRef xValObj = (SbxObject*)refVal->GetObject();
348*cdf0e10cSrcweir 	if( !xValObj.Is() || xValObj->ISA(SbUnoAnyObject) )
349*cdf0e10cSrcweir         return;
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir 	// #115826: Exclude ProcedureProperties to avoid call to Property Get procedure
352*cdf0e10cSrcweir 	if( refVar->ISA(SbProcedureProperty) )
353*cdf0e10cSrcweir 		return;
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir 	SbxObjectRef xVarObj = (SbxObject*)refVar->GetObject();
356*cdf0e10cSrcweir 	SbxDataType eValType = refVal->GetType();
357*cdf0e10cSrcweir 	if( eValType == SbxOBJECT && xVarObj == xValObj )
358*cdf0e10cSrcweir 	{
359*cdf0e10cSrcweir 		SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)xVarObj);
360*cdf0e10cSrcweir 		if( pUnoObj )
361*cdf0e10cSrcweir 		{
362*cdf0e10cSrcweir 			Any aAny = pUnoObj->getUnoAny();
363*cdf0e10cSrcweir 			if( aAny.getValueType().getTypeClass() == TypeClass_STRUCT )
364*cdf0e10cSrcweir 			{
365*cdf0e10cSrcweir 				SbUnoObject* pNewUnoObj = new SbUnoObject( pUnoObj->GetName(), aAny );
366*cdf0e10cSrcweir 				// #70324: ClassName uebernehmen
367*cdf0e10cSrcweir 				pNewUnoObj->SetClassName( pUnoObj->GetClassName() );
368*cdf0e10cSrcweir 				refVar->PutObject( pNewUnoObj );
369*cdf0e10cSrcweir 			}
370*cdf0e10cSrcweir 		}
371*cdf0e10cSrcweir 	}
372*cdf0e10cSrcweir }
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir // Ablage von TOS in TOS-1
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir void SbiRuntime::StepPUT()
378*cdf0e10cSrcweir {
379*cdf0e10cSrcweir 	SbxVariableRef refVal = PopVar();
380*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
381*cdf0e10cSrcweir 	// Store auf die eigene Methode (innerhalb einer Function)?
382*cdf0e10cSrcweir 	sal_Bool bFlagsChanged = sal_False;
383*cdf0e10cSrcweir 	sal_uInt16 n = 0;
384*cdf0e10cSrcweir 	if( (SbxVariable*) refVar == (SbxVariable*) pMeth )
385*cdf0e10cSrcweir 	{
386*cdf0e10cSrcweir 		bFlagsChanged = sal_True;
387*cdf0e10cSrcweir 		n = refVar->GetFlags();
388*cdf0e10cSrcweir 		refVar->SetFlag( SBX_WRITE );
389*cdf0e10cSrcweir 	}
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir 	// if left side arg is an object or variant and right handside isn't
392*cdf0e10cSrcweir 	// either an object or a variant then try and see if a default
393*cdf0e10cSrcweir 	// property exists.
394*cdf0e10cSrcweir 	// to use e.g. Range{"A1") = 34
395*cdf0e10cSrcweir 	// could equate to Range("A1").Value = 34
396*cdf0e10cSrcweir 	if ( bVBAEnabled )
397*cdf0e10cSrcweir 	{
398*cdf0e10cSrcweir 		if ( refVar->GetType() == SbxOBJECT  )
399*cdf0e10cSrcweir 		{
400*cdf0e10cSrcweir 			SbxVariable* pDflt = getDefaultProp( refVar );
401*cdf0e10cSrcweir 			if ( pDflt )
402*cdf0e10cSrcweir 				refVar = pDflt;
403*cdf0e10cSrcweir 		}
404*cdf0e10cSrcweir 		if (  refVal->GetType() == SbxOBJECT  )
405*cdf0e10cSrcweir 		{
406*cdf0e10cSrcweir 			SbxVariable* pDflt = getDefaultProp( refVal );
407*cdf0e10cSrcweir 			if ( pDflt )
408*cdf0e10cSrcweir 				refVal = pDflt;
409*cdf0e10cSrcweir 		}
410*cdf0e10cSrcweir 	}
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir 	*refVar = *refVal;
413*cdf0e10cSrcweir 	// lhs is a property who's value is currently null
414*cdf0e10cSrcweir 	if ( !bVBAEnabled || ( bVBAEnabled && refVar->GetType() != SbxEMPTY ) )
415*cdf0e10cSrcweir 	// #67607 Uno-Structs kopieren
416*cdf0e10cSrcweir 		checkUnoStructCopy( refVal, refVar );
417*cdf0e10cSrcweir 	if( bFlagsChanged )
418*cdf0e10cSrcweir 		refVar->SetFlags( n );
419*cdf0e10cSrcweir }
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir // VBA Dim As New behavior handling, save init object information
423*cdf0e10cSrcweir struct DimAsNewRecoverItem
424*cdf0e10cSrcweir {
425*cdf0e10cSrcweir 	String			m_aObjClass;
426*cdf0e10cSrcweir 	String			m_aObjName;
427*cdf0e10cSrcweir 	SbxObject*		m_pObjParent;
428*cdf0e10cSrcweir 	SbModule*		m_pClassModule;
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir 	DimAsNewRecoverItem( void )
431*cdf0e10cSrcweir 		: m_pObjParent( NULL )
432*cdf0e10cSrcweir 		, m_pClassModule( NULL )
433*cdf0e10cSrcweir 	{}
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir 	DimAsNewRecoverItem( const String& rObjClass, const String& rObjName,
436*cdf0e10cSrcweir 		SbxObject* pObjParent, SbModule* pClassModule )
437*cdf0e10cSrcweir 			: m_aObjClass( rObjClass )
438*cdf0e10cSrcweir 			, m_aObjName( rObjName )
439*cdf0e10cSrcweir 			, m_pObjParent( pObjParent )
440*cdf0e10cSrcweir 			, m_pClassModule( pClassModule )
441*cdf0e10cSrcweir 	{}
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir };
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir struct SbxVariablePtrHash
447*cdf0e10cSrcweir {
448*cdf0e10cSrcweir     size_t operator()( SbxVariable* pVar ) const
449*cdf0e10cSrcweir         { return (size_t)pVar; }
450*cdf0e10cSrcweir };
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir typedef std::hash_map< SbxVariable*, DimAsNewRecoverItem, SbxVariablePtrHash >	DimAsNewRecoverHash;
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir static DimAsNewRecoverHash		GaDimAsNewRecoverHash;
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir void removeDimAsNewRecoverItem( SbxVariable* pVar )
457*cdf0e10cSrcweir {
458*cdf0e10cSrcweir 	DimAsNewRecoverHash::iterator it = GaDimAsNewRecoverHash.find( pVar );
459*cdf0e10cSrcweir 	if( it != GaDimAsNewRecoverHash.end() )
460*cdf0e10cSrcweir 		GaDimAsNewRecoverHash.erase( it );
461*cdf0e10cSrcweir }
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir // Speichern Objektvariable
465*cdf0e10cSrcweir // Nicht-Objekt-Variable fuehren zu Fehlern
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir static const char pCollectionStr[] = "Collection";
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, bool bHandleDefaultProp )
470*cdf0e10cSrcweir {
471*cdf0e10cSrcweir 	// #67733 Typen mit Array-Flag sind auch ok
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir 	// Check var, !object is no error for sure if, only if type is fixed
474*cdf0e10cSrcweir 	SbxDataType eVarType = refVar->GetType();
475*cdf0e10cSrcweir 	if( !bHandleDefaultProp && eVarType != SbxOBJECT && !(eVarType & SbxARRAY) && refVar->IsFixed() )
476*cdf0e10cSrcweir 	{
477*cdf0e10cSrcweir 		Error( SbERR_INVALID_USAGE_OBJECT );
478*cdf0e10cSrcweir 		return;
479*cdf0e10cSrcweir 	}
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir 	// Check value, !object is no error for sure if, only if type is fixed
482*cdf0e10cSrcweir 	SbxDataType eValType = refVal->GetType();
483*cdf0e10cSrcweir //	bool bGetValObject = false;
484*cdf0e10cSrcweir 	if( !bHandleDefaultProp && eValType != SbxOBJECT && !(eValType & SbxARRAY) && refVal->IsFixed() )
485*cdf0e10cSrcweir 	{
486*cdf0e10cSrcweir 		Error( SbERR_INVALID_USAGE_OBJECT );
487*cdf0e10cSrcweir 		return;
488*cdf0e10cSrcweir 	}
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir 	// Getting in here causes problems with objects with default properties
491*cdf0e10cSrcweir 	// if they are SbxEMPTY I guess
492*cdf0e10cSrcweir 	if ( !bHandleDefaultProp || ( bHandleDefaultProp && eValType == SbxOBJECT ) )
493*cdf0e10cSrcweir 	{
494*cdf0e10cSrcweir 	// Auf refVal GetObject fuer Collections ausloesen
495*cdf0e10cSrcweir 		SbxBase* pObjVarObj = refVal->GetObject();
496*cdf0e10cSrcweir 		if( pObjVarObj )
497*cdf0e10cSrcweir 		{
498*cdf0e10cSrcweir 			SbxVariableRef refObjVal = PTR_CAST(SbxObject,pObjVarObj);
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir 			// #67733 Typen mit Array-Flag sind auch ok
501*cdf0e10cSrcweir 			if( refObjVal )
502*cdf0e10cSrcweir 				refVal = refObjVal;
503*cdf0e10cSrcweir 			else if( !(eValType & SbxARRAY) )
504*cdf0e10cSrcweir 				refVal = NULL;
505*cdf0e10cSrcweir 		}
506*cdf0e10cSrcweir 	}
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir 	// #52896 Wenn Uno-Sequences bzw. allgemein Arrays einer als
509*cdf0e10cSrcweir 	// Object deklarierten Variable zugewiesen werden, kann hier
510*cdf0e10cSrcweir 	// refVal ungueltig sein!
511*cdf0e10cSrcweir 	if( !refVal )
512*cdf0e10cSrcweir 	{
513*cdf0e10cSrcweir 		Error( SbERR_INVALID_USAGE_OBJECT );
514*cdf0e10cSrcweir 	}
515*cdf0e10cSrcweir 	else
516*cdf0e10cSrcweir 	{
517*cdf0e10cSrcweir 		// Store auf die eigene Methode (innerhalb einer Function)?
518*cdf0e10cSrcweir 		sal_Bool bFlagsChanged = sal_False;
519*cdf0e10cSrcweir 		sal_uInt16 n = 0;
520*cdf0e10cSrcweir 		if( (SbxVariable*) refVar == (SbxVariable*) pMeth )
521*cdf0e10cSrcweir 		{
522*cdf0e10cSrcweir 			bFlagsChanged = sal_True;
523*cdf0e10cSrcweir 			n = refVar->GetFlags();
524*cdf0e10cSrcweir 			refVar->SetFlag( SBX_WRITE );
525*cdf0e10cSrcweir 		}
526*cdf0e10cSrcweir 		SbProcedureProperty* pProcProperty = PTR_CAST(SbProcedureProperty,(SbxVariable*)refVar);
527*cdf0e10cSrcweir 		if( pProcProperty )
528*cdf0e10cSrcweir 			pProcProperty->setSet( true );
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir 		if ( bHandleDefaultProp )
531*cdf0e10cSrcweir 		{
532*cdf0e10cSrcweir 			// get default properties for lhs & rhs where necessary
533*cdf0e10cSrcweir 			// SbxVariable* defaultProp = NULL; unused variable
534*cdf0e10cSrcweir 			bool bLHSHasDefaultProp = false;
535*cdf0e10cSrcweir 			// LHS try determine if a default prop exists
536*cdf0e10cSrcweir 			if ( refVar->GetType() == SbxOBJECT )
537*cdf0e10cSrcweir 			{
538*cdf0e10cSrcweir 				SbxVariable* pDflt = getDefaultProp( refVar );
539*cdf0e10cSrcweir 				if ( pDflt )
540*cdf0e10cSrcweir 				{
541*cdf0e10cSrcweir 					refVar = pDflt;
542*cdf0e10cSrcweir 					bLHSHasDefaultProp = true;
543*cdf0e10cSrcweir 				}
544*cdf0e10cSrcweir 			}
545*cdf0e10cSrcweir 			// RHS only get a default prop is the rhs has one
546*cdf0e10cSrcweir 			if (  refVal->GetType() == SbxOBJECT )
547*cdf0e10cSrcweir 			{
548*cdf0e10cSrcweir 				// check if lhs is a null object
549*cdf0e10cSrcweir 				// if it is then use the object not the default property
550*cdf0e10cSrcweir 				SbxObject* pObj = NULL;
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir 				pObj = PTR_CAST(SbxObject,(SbxVariable*)refVar);
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir 				// calling GetObject on a SbxEMPTY variable raises
556*cdf0e10cSrcweir 				// object not set errors, make sure its an Object
557*cdf0e10cSrcweir 				if ( !pObj && refVar->GetType() == SbxOBJECT )
558*cdf0e10cSrcweir 				{
559*cdf0e10cSrcweir 					SbxBase* pObjVarObj = refVar->GetObject();
560*cdf0e10cSrcweir 					pObj = PTR_CAST(SbxObject,pObjVarObj);
561*cdf0e10cSrcweir 				}
562*cdf0e10cSrcweir 				SbxVariable* pDflt = NULL;
563*cdf0e10cSrcweir 				if ( pObj || bLHSHasDefaultProp )
564*cdf0e10cSrcweir 					// lhs is either a valid object || or has a defaultProp
565*cdf0e10cSrcweir 					pDflt = getDefaultProp( refVal );
566*cdf0e10cSrcweir 				if ( pDflt )
567*cdf0e10cSrcweir 					refVal = pDflt;
568*cdf0e10cSrcweir 			}
569*cdf0e10cSrcweir 		}
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir 		// Handle Dim As New
572*cdf0e10cSrcweir 		sal_Bool bDimAsNew = bVBAEnabled && refVar->IsSet( SBX_DIM_AS_NEW );
573*cdf0e10cSrcweir 		SbxBaseRef xPrevVarObj;
574*cdf0e10cSrcweir 		if( bDimAsNew )
575*cdf0e10cSrcweir 			xPrevVarObj = refVar->GetObject();
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir 		// Handle withevents
578*cdf0e10cSrcweir 		sal_Bool bWithEvents = refVar->IsSet( SBX_WITH_EVENTS );
579*cdf0e10cSrcweir         if ( bWithEvents )
580*cdf0e10cSrcweir         {
581*cdf0e10cSrcweir             Reference< XInterface > xComListener;
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir             SbxBase* pObj = refVal->GetObject();
584*cdf0e10cSrcweir             SbUnoObject* pUnoObj = (pObj != NULL) ? PTR_CAST(SbUnoObject,pObj) : NULL;
585*cdf0e10cSrcweir             if( pUnoObj != NULL )
586*cdf0e10cSrcweir             {
587*cdf0e10cSrcweir                 Any aControlAny = pUnoObj->getUnoAny();
588*cdf0e10cSrcweir                 String aDeclareClassName = refVar->GetDeclareClassName();
589*cdf0e10cSrcweir                 ::rtl::OUString aVBAType = aDeclareClassName;
590*cdf0e10cSrcweir                 ::rtl::OUString aPrefix = refVar->GetName();
591*cdf0e10cSrcweir                 SbxObjectRef xScopeObj = refVar->GetParent();
592*cdf0e10cSrcweir                 xComListener = createComListener( aControlAny, aVBAType, aPrefix, xScopeObj );
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir                 refVal->SetDeclareClassName( aDeclareClassName );
595*cdf0e10cSrcweir                 refVal->SetComListener( xComListener, &rBasic );		// Hold reference
596*cdf0e10cSrcweir             }
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir             *refVar = *refVal;
599*cdf0e10cSrcweir         }
600*cdf0e10cSrcweir         else
601*cdf0e10cSrcweir         {
602*cdf0e10cSrcweir             *refVar = *refVal;
603*cdf0e10cSrcweir         }
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir         if ( bDimAsNew )
606*cdf0e10cSrcweir         {
607*cdf0e10cSrcweir 			if( !refVar->ISA(SbxObject) )
608*cdf0e10cSrcweir 			{
609*cdf0e10cSrcweir 	            SbxBase* pValObjBase = refVal->GetObject();
610*cdf0e10cSrcweir 				if( pValObjBase == NULL )
611*cdf0e10cSrcweir 				{
612*cdf0e10cSrcweir 					if( xPrevVarObj.Is() )
613*cdf0e10cSrcweir 					{
614*cdf0e10cSrcweir 						// Object is overwritten with NULL, instantiate init object
615*cdf0e10cSrcweir 						DimAsNewRecoverHash::iterator it = GaDimAsNewRecoverHash.find( refVar );
616*cdf0e10cSrcweir 						if( it != GaDimAsNewRecoverHash.end() )
617*cdf0e10cSrcweir 						{
618*cdf0e10cSrcweir 							const DimAsNewRecoverItem& rItem = it->second;
619*cdf0e10cSrcweir 							if( rItem.m_pClassModule != NULL )
620*cdf0e10cSrcweir 							{
621*cdf0e10cSrcweir 								SbClassModuleObject* pNewObj = new SbClassModuleObject( rItem.m_pClassModule );
622*cdf0e10cSrcweir 								pNewObj->SetName( rItem.m_aObjName );
623*cdf0e10cSrcweir 								pNewObj->SetParent( rItem.m_pObjParent );
624*cdf0e10cSrcweir 								refVar->PutObject( pNewObj );
625*cdf0e10cSrcweir 							}
626*cdf0e10cSrcweir 							else if( rItem.m_aObjClass.EqualsIgnoreCaseAscii( pCollectionStr ) )
627*cdf0e10cSrcweir 							{
628*cdf0e10cSrcweir 								BasicCollection* pNewCollection = new BasicCollection( String( RTL_CONSTASCII_USTRINGPARAM(pCollectionStr) ) );
629*cdf0e10cSrcweir 								pNewCollection->SetName( rItem.m_aObjName );
630*cdf0e10cSrcweir 								pNewCollection->SetParent( rItem.m_pObjParent );
631*cdf0e10cSrcweir 								refVar->PutObject( pNewCollection );
632*cdf0e10cSrcweir 							}
633*cdf0e10cSrcweir 						}
634*cdf0e10cSrcweir 					}
635*cdf0e10cSrcweir 				}
636*cdf0e10cSrcweir 				else
637*cdf0e10cSrcweir 				{
638*cdf0e10cSrcweir 					// Does old value exist?
639*cdf0e10cSrcweir 					bool bFirstInit = !xPrevVarObj.Is();
640*cdf0e10cSrcweir 					if( bFirstInit )
641*cdf0e10cSrcweir 					{
642*cdf0e10cSrcweir 						// Store information to instantiate object later
643*cdf0e10cSrcweir 						SbxObject* pValObj = PTR_CAST(SbxObject,pValObjBase);
644*cdf0e10cSrcweir 						if( pValObj != NULL )
645*cdf0e10cSrcweir 						{
646*cdf0e10cSrcweir 							String aObjClass = pValObj->GetClassName();
647*cdf0e10cSrcweir 
648*cdf0e10cSrcweir 							SbClassModuleObject* pClassModuleObj = PTR_CAST(SbClassModuleObject,pValObjBase);
649*cdf0e10cSrcweir 							if( pClassModuleObj != NULL )
650*cdf0e10cSrcweir 							{
651*cdf0e10cSrcweir 								SbModule* pClassModule = pClassModuleObj->getClassModule();
652*cdf0e10cSrcweir 								GaDimAsNewRecoverHash[refVar] =
653*cdf0e10cSrcweir 									DimAsNewRecoverItem( aObjClass, pValObj->GetName(), pValObj->GetParent(), pClassModule );
654*cdf0e10cSrcweir 							}
655*cdf0e10cSrcweir 							else if( aObjClass.EqualsIgnoreCaseAscii( "Collection" ) )
656*cdf0e10cSrcweir 							{
657*cdf0e10cSrcweir 								GaDimAsNewRecoverHash[refVar] =
658*cdf0e10cSrcweir 									DimAsNewRecoverItem( aObjClass, pValObj->GetName(), pValObj->GetParent(), NULL );
659*cdf0e10cSrcweir 							}
660*cdf0e10cSrcweir 						}
661*cdf0e10cSrcweir 					}
662*cdf0e10cSrcweir 				}
663*cdf0e10cSrcweir 			}
664*cdf0e10cSrcweir 		}
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir 		// lhs is a property who's value is currently (Empty e.g. no broadcast yet)
668*cdf0e10cSrcweir 		// in this case if there is a default prop involved the value of the
669*cdf0e10cSrcweir 		// default property may infact be void so the type will also be SbxEMPTY
670*cdf0e10cSrcweir 		// in this case we do not want to call checkUnoStructCopy 'cause that will
671*cdf0e10cSrcweir 		// cause an error also
672*cdf0e10cSrcweir 		if ( !bHandleDefaultProp || ( bHandleDefaultProp && ( refVar->GetType() != SbxEMPTY ) ) )
673*cdf0e10cSrcweir 		// #67607 Uno-Structs kopieren
674*cdf0e10cSrcweir 			checkUnoStructCopy( refVal, refVar );
675*cdf0e10cSrcweir 		if( bFlagsChanged )
676*cdf0e10cSrcweir 			refVar->SetFlags( n );
677*cdf0e10cSrcweir 	}
678*cdf0e10cSrcweir }
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir void SbiRuntime::StepSET()
681*cdf0e10cSrcweir {
682*cdf0e10cSrcweir 	SbxVariableRef refVal = PopVar();
683*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
684*cdf0e10cSrcweir 	StepSET_Impl( refVal, refVar, bVBAEnabled ); // this is really assigment
685*cdf0e10cSrcweir }
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir void SbiRuntime::StepVBASET()
688*cdf0e10cSrcweir {
689*cdf0e10cSrcweir 	SbxVariableRef refVal = PopVar();
690*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
691*cdf0e10cSrcweir 	// don't handle default property
692*cdf0e10cSrcweir 	StepSET_Impl( refVal, refVar, false ); // set obj = something
693*cdf0e10cSrcweir }
694*cdf0e10cSrcweir 
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir // JSM 07.10.95
697*cdf0e10cSrcweir void SbiRuntime::StepLSET()
698*cdf0e10cSrcweir {
699*cdf0e10cSrcweir 	SbxVariableRef refVal = PopVar();
700*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
701*cdf0e10cSrcweir 	if( refVar->GetType() != SbxSTRING
702*cdf0e10cSrcweir 	 || refVal->GetType() != SbxSTRING )
703*cdf0e10cSrcweir 		Error( SbERR_INVALID_USAGE_OBJECT );
704*cdf0e10cSrcweir 	else
705*cdf0e10cSrcweir 	{
706*cdf0e10cSrcweir 		// Store auf die eigene Methode (innerhalb einer Function)?
707*cdf0e10cSrcweir 		sal_uInt16 n = refVar->GetFlags();
708*cdf0e10cSrcweir 		if( (SbxVariable*) refVar == (SbxVariable*) pMeth )
709*cdf0e10cSrcweir 			refVar->SetFlag( SBX_WRITE );
710*cdf0e10cSrcweir 		String aRefVarString = refVar->GetString();
711*cdf0e10cSrcweir 		String aRefValString = refVal->GetString();
712*cdf0e10cSrcweir 
713*cdf0e10cSrcweir         sal_uInt16 nVarStrLen = aRefVarString.Len();
714*cdf0e10cSrcweir         sal_uInt16 nValStrLen = aRefValString.Len();
715*cdf0e10cSrcweir         String aNewStr;
716*cdf0e10cSrcweir 		if( nVarStrLen > nValStrLen )
717*cdf0e10cSrcweir         {
718*cdf0e10cSrcweir 			aRefVarString.Fill(nVarStrLen,' ');
719*cdf0e10cSrcweir 		    aNewStr  = aRefValString.Copy( 0, nValStrLen );
720*cdf0e10cSrcweir 		    aNewStr += aRefVarString.Copy( nValStrLen, nVarStrLen - nValStrLen );
721*cdf0e10cSrcweir         }
722*cdf0e10cSrcweir         else
723*cdf0e10cSrcweir         {
724*cdf0e10cSrcweir 		    aNewStr = aRefValString.Copy( 0, nVarStrLen );
725*cdf0e10cSrcweir         }
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir 	    refVar->PutString( aNewStr );
728*cdf0e10cSrcweir 		refVar->SetFlags( n );
729*cdf0e10cSrcweir 	}
730*cdf0e10cSrcweir }
731*cdf0e10cSrcweir 
732*cdf0e10cSrcweir // JSM 07.10.95
733*cdf0e10cSrcweir void SbiRuntime::StepRSET()
734*cdf0e10cSrcweir {
735*cdf0e10cSrcweir 	SbxVariableRef refVal = PopVar();
736*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
737*cdf0e10cSrcweir 	if( refVar->GetType() != SbxSTRING
738*cdf0e10cSrcweir 	 || refVal->GetType() != SbxSTRING )
739*cdf0e10cSrcweir 		Error( SbERR_INVALID_USAGE_OBJECT );
740*cdf0e10cSrcweir 	else
741*cdf0e10cSrcweir 	{
742*cdf0e10cSrcweir 		// Store auf die eigene Methode (innerhalb einer Function)?
743*cdf0e10cSrcweir 		sal_uInt16 n = refVar->GetFlags();
744*cdf0e10cSrcweir 		if( (SbxVariable*) refVar == (SbxVariable*) pMeth )
745*cdf0e10cSrcweir 			refVar->SetFlag( SBX_WRITE );
746*cdf0e10cSrcweir 		String aRefVarString = refVar->GetString();
747*cdf0e10cSrcweir 		String aRefValString = refVal->GetString();
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir 		sal_uInt16 nPos = 0;
750*cdf0e10cSrcweir         sal_uInt16 nVarStrLen = aRefVarString.Len();
751*cdf0e10cSrcweir 		if( nVarStrLen > aRefValString.Len() )
752*cdf0e10cSrcweir 		{
753*cdf0e10cSrcweir 			aRefVarString.Fill(nVarStrLen,' ');
754*cdf0e10cSrcweir 			nPos = nVarStrLen - aRefValString.Len();
755*cdf0e10cSrcweir 		}
756*cdf0e10cSrcweir 		aRefVarString  = aRefVarString.Copy( 0, nPos );
757*cdf0e10cSrcweir 		aRefVarString += aRefValString.Copy( 0, nVarStrLen - nPos );
758*cdf0e10cSrcweir 		refVar->PutString(aRefVarString);
759*cdf0e10cSrcweir 
760*cdf0e10cSrcweir 		refVar->SetFlags( n );
761*cdf0e10cSrcweir 	}
762*cdf0e10cSrcweir }
763*cdf0e10cSrcweir 
764*cdf0e10cSrcweir // Ablage von TOS in TOS-1, dann ReadOnly-Bit setzen
765*cdf0e10cSrcweir 
766*cdf0e10cSrcweir void SbiRuntime::StepPUTC()
767*cdf0e10cSrcweir {
768*cdf0e10cSrcweir 	SbxVariableRef refVal = PopVar();
769*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
770*cdf0e10cSrcweir 	refVar->SetFlag( SBX_WRITE );
771*cdf0e10cSrcweir 	*refVar = *refVal;
772*cdf0e10cSrcweir 	refVar->ResetFlag( SBX_WRITE );
773*cdf0e10cSrcweir 	refVar->SetFlag( SBX_CONST );
774*cdf0e10cSrcweir }
775*cdf0e10cSrcweir 
776*cdf0e10cSrcweir // DIM
777*cdf0e10cSrcweir // TOS = Variable fuer das Array mit Dimensionsangaben als Parameter
778*cdf0e10cSrcweir 
779*cdf0e10cSrcweir void SbiRuntime::StepDIM()
780*cdf0e10cSrcweir {
781*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
782*cdf0e10cSrcweir 	DimImpl( refVar );
783*cdf0e10cSrcweir }
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir // #56204 DIM-Funktionalitaet in Hilfsmethode auslagern (step0.cxx)
786*cdf0e10cSrcweir void SbiRuntime::DimImpl( SbxVariableRef refVar )
787*cdf0e10cSrcweir {
788*cdf0e10cSrcweir 	SbxArray* pDims = refVar->GetParameters();
789*cdf0e10cSrcweir 	// Muss eine gerade Anzahl Argumente haben
790*cdf0e10cSrcweir 	// Man denke daran, dass Arg[0] nicht zaehlt!
791*cdf0e10cSrcweir 	if( pDims && !( pDims->Count() & 1 ) )
792*cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
793*cdf0e10cSrcweir 	else
794*cdf0e10cSrcweir 	{
795*cdf0e10cSrcweir 		SbxDataType eType = refVar->IsFixed() ? refVar->GetType() : SbxVARIANT;
796*cdf0e10cSrcweir 		SbxDimArray* pArray = new SbxDimArray( eType );
797*cdf0e10cSrcweir 		// AB 2.4.1996, auch Arrays ohne Dimensionsangaben zulassen (VB-komp.)
798*cdf0e10cSrcweir 		if( pDims )
799*cdf0e10cSrcweir 		{
800*cdf0e10cSrcweir 			refVar->ResetFlag( SBX_VAR_TO_DIM );
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir 			for( sal_uInt16 i = 1; i < pDims->Count(); )
803*cdf0e10cSrcweir 			{
804*cdf0e10cSrcweir 				sal_Int32 lb = pDims->Get( i++ )->GetLong();
805*cdf0e10cSrcweir 				sal_Int32 ub = pDims->Get( i++ )->GetLong();
806*cdf0e10cSrcweir 				if( ub < lb )
807*cdf0e10cSrcweir 					Error( SbERR_OUT_OF_RANGE ), ub = lb;
808*cdf0e10cSrcweir 				pArray->AddDim32( lb, ub );
809*cdf0e10cSrcweir 				if ( lb != ub )
810*cdf0e10cSrcweir 					pArray->setHasFixedSize( true );
811*cdf0e10cSrcweir 			}
812*cdf0e10cSrcweir 		}
813*cdf0e10cSrcweir 		else
814*cdf0e10cSrcweir 		{
815*cdf0e10cSrcweir 			// #62867 Beim Anlegen eines Arrays der Laenge 0 wie bei
816*cdf0e10cSrcweir 			// Uno-Sequences der Laenge 0 eine Dimension anlegen
817*cdf0e10cSrcweir 			pArray->unoAddDim( 0, -1 );
818*cdf0e10cSrcweir 		}
819*cdf0e10cSrcweir 		sal_uInt16 nSavFlags = refVar->GetFlags();
820*cdf0e10cSrcweir 		refVar->ResetFlag( SBX_FIXED );
821*cdf0e10cSrcweir 		refVar->PutObject( pArray );
822*cdf0e10cSrcweir 		refVar->SetFlags( nSavFlags );
823*cdf0e10cSrcweir 		refVar->SetParameters( NULL );
824*cdf0e10cSrcweir 	}
825*cdf0e10cSrcweir }
826*cdf0e10cSrcweir 
827*cdf0e10cSrcweir // REDIM
828*cdf0e10cSrcweir // TOS  = Variable fuer das Array
829*cdf0e10cSrcweir // argv = Dimensionsangaben
830*cdf0e10cSrcweir 
831*cdf0e10cSrcweir void SbiRuntime::StepREDIM()
832*cdf0e10cSrcweir {
833*cdf0e10cSrcweir 	// Im Moment ist es nichts anderes als Dim, da doppeltes Dim
834*cdf0e10cSrcweir 	// bereits vom Compiler erkannt wird.
835*cdf0e10cSrcweir 	StepDIM();
836*cdf0e10cSrcweir }
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir 
839*cdf0e10cSrcweir // Helper function for StepREDIMP
840*cdf0e10cSrcweir void implCopyDimArray( SbxDimArray* pNewArray, SbxDimArray* pOldArray, short nMaxDimIndex,
841*cdf0e10cSrcweir 	short nActualDim, sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
842*cdf0e10cSrcweir {
843*cdf0e10cSrcweir 	sal_Int32& ri = pActualIndices[nActualDim];
844*cdf0e10cSrcweir 	for( ri = pLowerBounds[nActualDim] ; ri <= pUpperBounds[nActualDim] ; ri++ )
845*cdf0e10cSrcweir 	{
846*cdf0e10cSrcweir 		if( nActualDim < nMaxDimIndex )
847*cdf0e10cSrcweir 		{
848*cdf0e10cSrcweir 			implCopyDimArray( pNewArray, pOldArray, nMaxDimIndex, nActualDim + 1,
849*cdf0e10cSrcweir 				pActualIndices, pLowerBounds, pUpperBounds );
850*cdf0e10cSrcweir 		}
851*cdf0e10cSrcweir 		else
852*cdf0e10cSrcweir 		{
853*cdf0e10cSrcweir 			SbxVariable* pSource = pOldArray->Get32( pActualIndices );
854*cdf0e10cSrcweir 			SbxVariable* pDest   = pNewArray->Get32( pActualIndices );
855*cdf0e10cSrcweir 			if( pSource && pDest )
856*cdf0e10cSrcweir 				*pDest = *pSource;
857*cdf0e10cSrcweir 		}
858*cdf0e10cSrcweir 	}
859*cdf0e10cSrcweir }
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir // REDIM PRESERVE
862*cdf0e10cSrcweir // TOS  = Variable fuer das Array
863*cdf0e10cSrcweir // argv = Dimensionsangaben
864*cdf0e10cSrcweir 
865*cdf0e10cSrcweir void SbiRuntime::StepREDIMP()
866*cdf0e10cSrcweir {
867*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
868*cdf0e10cSrcweir 	DimImpl( refVar );
869*cdf0e10cSrcweir 
870*cdf0e10cSrcweir 	// Now check, if we can copy from the old array
871*cdf0e10cSrcweir 	if( refRedimpArray.Is() )
872*cdf0e10cSrcweir 	{
873*cdf0e10cSrcweir 		SbxBase* pElemObj = refVar->GetObject();
874*cdf0e10cSrcweir 		SbxDimArray* pNewArray = PTR_CAST(SbxDimArray,pElemObj);
875*cdf0e10cSrcweir 		SbxDimArray* pOldArray = (SbxDimArray*)(SbxArray*)refRedimpArray;
876*cdf0e10cSrcweir 		if( pNewArray )
877*cdf0e10cSrcweir 		{
878*cdf0e10cSrcweir 			short nDimsNew = pNewArray->GetDims();
879*cdf0e10cSrcweir 			short nDimsOld = pOldArray->GetDims();
880*cdf0e10cSrcweir 			short nDims = nDimsNew;
881*cdf0e10cSrcweir 			sal_Bool bRangeError = sal_False;
882*cdf0e10cSrcweir 
883*cdf0e10cSrcweir 			// Store dims to use them for copying later
884*cdf0e10cSrcweir 			sal_Int32* pLowerBounds = new sal_Int32[nDims];
885*cdf0e10cSrcweir 			sal_Int32* pUpperBounds = new sal_Int32[nDims];
886*cdf0e10cSrcweir 			sal_Int32* pActualIndices = new sal_Int32[nDims];
887*cdf0e10cSrcweir 
888*cdf0e10cSrcweir 			if( nDimsOld != nDimsNew )
889*cdf0e10cSrcweir 			{
890*cdf0e10cSrcweir 				bRangeError = sal_True;
891*cdf0e10cSrcweir 			}
892*cdf0e10cSrcweir 			else
893*cdf0e10cSrcweir 			{
894*cdf0e10cSrcweir 				// Compare bounds
895*cdf0e10cSrcweir 				for( short i = 1 ; i <= nDims ; i++ )
896*cdf0e10cSrcweir 				{
897*cdf0e10cSrcweir 					sal_Int32 lBoundNew, uBoundNew;
898*cdf0e10cSrcweir 					sal_Int32 lBoundOld, uBoundOld;
899*cdf0e10cSrcweir 					pNewArray->GetDim32( i, lBoundNew, uBoundNew );
900*cdf0e10cSrcweir 					pOldArray->GetDim32( i, lBoundOld, uBoundOld );
901*cdf0e10cSrcweir 
902*cdf0e10cSrcweir                     /* #69094 Allow all dimensions to be changed
903*cdf0e10cSrcweir                        although Visual Basic is not able to do so.
904*cdf0e10cSrcweir 					// All bounds but the last have to be the same
905*cdf0e10cSrcweir 					if( i < nDims && ( lBoundNew != lBoundOld || uBoundNew != uBoundOld ) )
906*cdf0e10cSrcweir 					{
907*cdf0e10cSrcweir 						bRangeError = sal_True;
908*cdf0e10cSrcweir 						break;
909*cdf0e10cSrcweir 					}
910*cdf0e10cSrcweir 					else
911*cdf0e10cSrcweir                     */
912*cdf0e10cSrcweir 					{
913*cdf0e10cSrcweir 						// #69094: if( i == nDims )
914*cdf0e10cSrcweir 						{
915*cdf0e10cSrcweir 							lBoundNew = std::max( lBoundNew, lBoundOld );
916*cdf0e10cSrcweir 							uBoundNew = std::min( uBoundNew, uBoundOld );
917*cdf0e10cSrcweir 						}
918*cdf0e10cSrcweir 						short j = i - 1;
919*cdf0e10cSrcweir 						pActualIndices[j] = pLowerBounds[j] = lBoundNew;
920*cdf0e10cSrcweir 						pUpperBounds[j] = uBoundNew;
921*cdf0e10cSrcweir 					}
922*cdf0e10cSrcweir 				}
923*cdf0e10cSrcweir 			}
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir 			if( bRangeError )
926*cdf0e10cSrcweir 			{
927*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_OUT_OF_RANGE );
928*cdf0e10cSrcweir 			}
929*cdf0e10cSrcweir 			else
930*cdf0e10cSrcweir 			{
931*cdf0e10cSrcweir 				// Copy data from old array by going recursively through all dimensions
932*cdf0e10cSrcweir 				// (It would be faster to work on the flat internal data array of an
933*cdf0e10cSrcweir 				// SbyArray but this solution is clearer and easier)
934*cdf0e10cSrcweir 				implCopyDimArray( pNewArray, pOldArray, nDims - 1,
935*cdf0e10cSrcweir 					0, pActualIndices, pLowerBounds, pUpperBounds );
936*cdf0e10cSrcweir 			}
937*cdf0e10cSrcweir 
938*cdf0e10cSrcweir 			delete[] pUpperBounds;
939*cdf0e10cSrcweir 			delete[] pLowerBounds;
940*cdf0e10cSrcweir 			delete[] pActualIndices;
941*cdf0e10cSrcweir 			refRedimpArray = NULL;
942*cdf0e10cSrcweir 		}
943*cdf0e10cSrcweir 	}
944*cdf0e10cSrcweir 
945*cdf0e10cSrcweir 	//StarBASIC::FatalError( SbERR_NOT_IMPLEMENTED );
946*cdf0e10cSrcweir }
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir // REDIM_COPY
949*cdf0e10cSrcweir // TOS  = Array-Variable, Reference to array is copied
950*cdf0e10cSrcweir //		  Variable is cleared as in ERASE
951*cdf0e10cSrcweir 
952*cdf0e10cSrcweir void SbiRuntime::StepREDIMP_ERASE()
953*cdf0e10cSrcweir {
954*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
955*cdf0e10cSrcweir 	SbxDataType eType = refVar->GetType();
956*cdf0e10cSrcweir 	if( eType & SbxARRAY )
957*cdf0e10cSrcweir 	{
958*cdf0e10cSrcweir 		SbxBase* pElemObj = refVar->GetObject();
959*cdf0e10cSrcweir 		SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
960*cdf0e10cSrcweir 		if( pDimArray )
961*cdf0e10cSrcweir 		{
962*cdf0e10cSrcweir 			refRedimpArray = pDimArray;
963*cdf0e10cSrcweir 		}
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir 		// As in ERASE
966*cdf0e10cSrcweir 		sal_uInt16 nSavFlags = refVar->GetFlags();
967*cdf0e10cSrcweir 		refVar->ResetFlag( SBX_FIXED );
968*cdf0e10cSrcweir 		refVar->SetType( SbxDataType(eType & 0x0FFF) );
969*cdf0e10cSrcweir 		refVar->SetFlags( nSavFlags );
970*cdf0e10cSrcweir 		refVar->Clear();
971*cdf0e10cSrcweir 	}
972*cdf0e10cSrcweir 	else
973*cdf0e10cSrcweir 	if( refVar->IsFixed() )
974*cdf0e10cSrcweir 		refVar->Clear();
975*cdf0e10cSrcweir 	else
976*cdf0e10cSrcweir 		refVar->SetType( SbxEMPTY );
977*cdf0e10cSrcweir }
978*cdf0e10cSrcweir 
979*cdf0e10cSrcweir void lcl_clearImpl( SbxVariableRef& refVar, SbxDataType& eType )
980*cdf0e10cSrcweir {
981*cdf0e10cSrcweir 	sal_uInt16 nSavFlags = refVar->GetFlags();
982*cdf0e10cSrcweir 	refVar->ResetFlag( SBX_FIXED );
983*cdf0e10cSrcweir 	refVar->SetType( SbxDataType(eType & 0x0FFF) );
984*cdf0e10cSrcweir 	refVar->SetFlags( nSavFlags );
985*cdf0e10cSrcweir 	refVar->Clear();
986*cdf0e10cSrcweir }
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir void lcl_eraseImpl( SbxVariableRef& refVar, bool bVBAEnabled )
989*cdf0e10cSrcweir {
990*cdf0e10cSrcweir 	SbxDataType eType = refVar->GetType();
991*cdf0e10cSrcweir 	if( eType & SbxARRAY )
992*cdf0e10cSrcweir 	{
993*cdf0e10cSrcweir 		if ( bVBAEnabled )
994*cdf0e10cSrcweir 		{
995*cdf0e10cSrcweir 			SbxBase* pElemObj = refVar->GetObject();
996*cdf0e10cSrcweir 			SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
997*cdf0e10cSrcweir 			bool bClearValues = true;
998*cdf0e10cSrcweir 			if( pDimArray )
999*cdf0e10cSrcweir 			{
1000*cdf0e10cSrcweir 				if ( pDimArray->hasFixedSize() )
1001*cdf0e10cSrcweir 				{
1002*cdf0e10cSrcweir 					// Clear all Value(s)
1003*cdf0e10cSrcweir 					pDimArray->SbxArray::Clear();
1004*cdf0e10cSrcweir 					bClearValues = false;
1005*cdf0e10cSrcweir 				}
1006*cdf0e10cSrcweir 				else
1007*cdf0e10cSrcweir 					pDimArray->Clear(); // clear Dims
1008*cdf0e10cSrcweir 			}
1009*cdf0e10cSrcweir 			if ( bClearValues )
1010*cdf0e10cSrcweir 			{
1011*cdf0e10cSrcweir 				SbxArray* pArray = PTR_CAST(SbxArray,pElemObj);
1012*cdf0e10cSrcweir 				if ( pArray )
1013*cdf0e10cSrcweir 					pArray->Clear();
1014*cdf0e10cSrcweir 			}
1015*cdf0e10cSrcweir 		}
1016*cdf0e10cSrcweir 		else
1017*cdf0e10cSrcweir 		// AB 2.4.1996
1018*cdf0e10cSrcweir 		// Arrays haben bei Erase nach VB ein recht komplexes Verhalten. Hier
1019*cdf0e10cSrcweir 		// werden zunaechst nur die Typ-Probleme bei REDIM (#26295) beseitigt:
1020*cdf0e10cSrcweir 		// Typ hart auf den Array-Typ setzen, da eine Variable mit Array
1021*cdf0e10cSrcweir 		// SbxOBJECT ist. Bei REDIM entsteht dann ein SbxOBJECT-Array und
1022*cdf0e10cSrcweir 		// der ursruengliche Typ geht verloren -> Laufzeitfehler
1023*cdf0e10cSrcweir 			lcl_clearImpl( refVar, eType );
1024*cdf0e10cSrcweir 	}
1025*cdf0e10cSrcweir 	else
1026*cdf0e10cSrcweir 	if( refVar->IsFixed() )
1027*cdf0e10cSrcweir 		refVar->Clear();
1028*cdf0e10cSrcweir 	else
1029*cdf0e10cSrcweir 		refVar->SetType( SbxEMPTY );
1030*cdf0e10cSrcweir }
1031*cdf0e10cSrcweir 
1032*cdf0e10cSrcweir // Variable loeschen
1033*cdf0e10cSrcweir // TOS = Variable
1034*cdf0e10cSrcweir 
1035*cdf0e10cSrcweir void SbiRuntime::StepERASE()
1036*cdf0e10cSrcweir {
1037*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
1038*cdf0e10cSrcweir 	lcl_eraseImpl( refVar, bVBAEnabled );
1039*cdf0e10cSrcweir }
1040*cdf0e10cSrcweir 
1041*cdf0e10cSrcweir void SbiRuntime::StepERASE_CLEAR()
1042*cdf0e10cSrcweir {
1043*cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
1044*cdf0e10cSrcweir 	lcl_eraseImpl( refVar, bVBAEnabled );
1045*cdf0e10cSrcweir 	SbxDataType eType = refVar->GetType();
1046*cdf0e10cSrcweir 	lcl_clearImpl( refVar, eType );
1047*cdf0e10cSrcweir }
1048*cdf0e10cSrcweir 
1049*cdf0e10cSrcweir void SbiRuntime::StepARRAYACCESS()
1050*cdf0e10cSrcweir {
1051*cdf0e10cSrcweir 	if( !refArgv )
1052*cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
1053*cdf0e10cSrcweir     SbxVariableRef refVar = PopVar();
1054*cdf0e10cSrcweir 	refVar->SetParameters( refArgv );
1055*cdf0e10cSrcweir 	PopArgv();
1056*cdf0e10cSrcweir 	PushVar( CheckArray( refVar ) );
1057*cdf0e10cSrcweir }
1058*cdf0e10cSrcweir 
1059*cdf0e10cSrcweir void SbiRuntime::StepBYVAL()
1060*cdf0e10cSrcweir {
1061*cdf0e10cSrcweir 	// Copy variable on stack to break call by reference
1062*cdf0e10cSrcweir 	SbxVariableRef pVar = PopVar();
1063*cdf0e10cSrcweir 	SbxDataType t = pVar->GetType();
1064*cdf0e10cSrcweir 
1065*cdf0e10cSrcweir 	SbxVariable* pCopyVar = new SbxVariable( t );
1066*cdf0e10cSrcweir 	pCopyVar->SetFlag( SBX_READWRITE );
1067*cdf0e10cSrcweir 	*pCopyVar = *pVar;
1068*cdf0e10cSrcweir 
1069*cdf0e10cSrcweir 	PushVar( pCopyVar );
1070*cdf0e10cSrcweir }
1071*cdf0e10cSrcweir 
1072*cdf0e10cSrcweir // Einrichten eines Argvs
1073*cdf0e10cSrcweir // nOp1 bleibt so -> 1. Element ist Returnwert
1074*cdf0e10cSrcweir 
1075*cdf0e10cSrcweir void SbiRuntime::StepARGC()
1076*cdf0e10cSrcweir {
1077*cdf0e10cSrcweir 	PushArgv();
1078*cdf0e10cSrcweir 	refArgv = new SbxArray;
1079*cdf0e10cSrcweir 	nArgc = 1;
1080*cdf0e10cSrcweir }
1081*cdf0e10cSrcweir 
1082*cdf0e10cSrcweir // Speichern eines Arguments in Argv
1083*cdf0e10cSrcweir 
1084*cdf0e10cSrcweir void SbiRuntime::StepARGV()
1085*cdf0e10cSrcweir {
1086*cdf0e10cSrcweir 	if( !refArgv )
1087*cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
1088*cdf0e10cSrcweir 	else
1089*cdf0e10cSrcweir 	{
1090*cdf0e10cSrcweir 		SbxVariableRef pVal = PopVar();
1091*cdf0e10cSrcweir 
1092*cdf0e10cSrcweir 		// Before fix of #94916:
1093*cdf0e10cSrcweir 		// if( pVal->ISA(SbxMethod) || pVal->ISA(SbxProperty) )
1094*cdf0e10cSrcweir 		if( pVal->ISA(SbxMethod) || pVal->ISA(SbUnoProperty) || pVal->ISA(SbProcedureProperty) )
1095*cdf0e10cSrcweir 		{
1096*cdf0e10cSrcweir 			// Methoden und Properties evaluieren!
1097*cdf0e10cSrcweir 			SbxVariable* pRes = new SbxVariable( *pVal );
1098*cdf0e10cSrcweir 			pVal = pRes;
1099*cdf0e10cSrcweir 		}
1100*cdf0e10cSrcweir 		refArgv->Put( pVal, nArgc++ );
1101*cdf0e10cSrcweir 	}
1102*cdf0e10cSrcweir }
1103*cdf0e10cSrcweir 
1104*cdf0e10cSrcweir // Input to Variable. Die Variable ist auf TOS und wird
1105*cdf0e10cSrcweir // anschliessend entfernt.
1106*cdf0e10cSrcweir 
1107*cdf0e10cSrcweir void SbiRuntime::StepINPUT()
1108*cdf0e10cSrcweir {
1109*cdf0e10cSrcweir 	String s;
1110*cdf0e10cSrcweir 	char ch = 0;
1111*cdf0e10cSrcweir 	SbError err;
1112*cdf0e10cSrcweir 	// Skip whitespace
1113*cdf0e10cSrcweir 	while( ( err = pIosys->GetError() ) == 0 )
1114*cdf0e10cSrcweir 	{
1115*cdf0e10cSrcweir 		ch = pIosys->Read();
1116*cdf0e10cSrcweir 		if( ch != ' ' && ch != '\t' && ch != '\n' )
1117*cdf0e10cSrcweir 			break;
1118*cdf0e10cSrcweir 	}
1119*cdf0e10cSrcweir 	if( !err )
1120*cdf0e10cSrcweir 	{
1121*cdf0e10cSrcweir 		// Scan until comma or whitespace
1122*cdf0e10cSrcweir 		char sep = ( ch == '"' ) ? ch : 0;
1123*cdf0e10cSrcweir 		if( sep ) ch = pIosys->Read();
1124*cdf0e10cSrcweir 		while( ( err = pIosys->GetError() ) == 0 )
1125*cdf0e10cSrcweir 		{
1126*cdf0e10cSrcweir 			if( ch == sep )
1127*cdf0e10cSrcweir 			{
1128*cdf0e10cSrcweir 				ch = pIosys->Read();
1129*cdf0e10cSrcweir 				if( ch != sep )
1130*cdf0e10cSrcweir 					break;
1131*cdf0e10cSrcweir 			}
1132*cdf0e10cSrcweir 			else if( !sep && (ch == ',' || ch == '\n') )
1133*cdf0e10cSrcweir 				break;
1134*cdf0e10cSrcweir 			s += ch;
1135*cdf0e10cSrcweir 			ch = pIosys->Read();
1136*cdf0e10cSrcweir 		}
1137*cdf0e10cSrcweir 		// skip whitespace
1138*cdf0e10cSrcweir 		if( ch == ' ' || ch == '\t' )
1139*cdf0e10cSrcweir 		  while( ( err = pIosys->GetError() ) == 0 )
1140*cdf0e10cSrcweir 		{
1141*cdf0e10cSrcweir 			if( ch != ' ' && ch != '\t' && ch != '\n' )
1142*cdf0e10cSrcweir 				break;
1143*cdf0e10cSrcweir 			ch = pIosys->Read();
1144*cdf0e10cSrcweir 		}
1145*cdf0e10cSrcweir 	}
1146*cdf0e10cSrcweir 	if( !err )
1147*cdf0e10cSrcweir 	{
1148*cdf0e10cSrcweir 		SbxVariableRef pVar = GetTOS();
1149*cdf0e10cSrcweir 		// Zuerst versuchen, die Variable mit einem numerischen Wert
1150*cdf0e10cSrcweir 		// zu fuellen, dann mit einem Stringwert
1151*cdf0e10cSrcweir 		if( !pVar->IsFixed() || pVar->IsNumeric() )
1152*cdf0e10cSrcweir 		{
1153*cdf0e10cSrcweir 			sal_uInt16 nLen = 0;
1154*cdf0e10cSrcweir 			if( !pVar->Scan( s, &nLen ) )
1155*cdf0e10cSrcweir 			{
1156*cdf0e10cSrcweir 				err = SbxBase::GetError();
1157*cdf0e10cSrcweir 				SbxBase::ResetError();
1158*cdf0e10cSrcweir 			}
1159*cdf0e10cSrcweir 			// Der Wert muss komplett eingescant werden
1160*cdf0e10cSrcweir 			else if( nLen != s.Len() && !pVar->PutString( s ) )
1161*cdf0e10cSrcweir 			{
1162*cdf0e10cSrcweir 				err = SbxBase::GetError();
1163*cdf0e10cSrcweir 				SbxBase::ResetError();
1164*cdf0e10cSrcweir 			}
1165*cdf0e10cSrcweir 			else if( nLen != s.Len() && pVar->IsNumeric() )
1166*cdf0e10cSrcweir 			{
1167*cdf0e10cSrcweir 				err = SbxBase::GetError();
1168*cdf0e10cSrcweir 				SbxBase::ResetError();
1169*cdf0e10cSrcweir 				if( !err )
1170*cdf0e10cSrcweir 					err = SbERR_CONVERSION;
1171*cdf0e10cSrcweir 			}
1172*cdf0e10cSrcweir 		}
1173*cdf0e10cSrcweir 		else
1174*cdf0e10cSrcweir 		{
1175*cdf0e10cSrcweir 			pVar->PutString( s );
1176*cdf0e10cSrcweir 			err = SbxBase::GetError();
1177*cdf0e10cSrcweir 			SbxBase::ResetError();
1178*cdf0e10cSrcweir 		}
1179*cdf0e10cSrcweir 	}
1180*cdf0e10cSrcweir 	if( err == SbERR_USER_ABORT )
1181*cdf0e10cSrcweir 		Error( err );
1182*cdf0e10cSrcweir 	else if( err )
1183*cdf0e10cSrcweir 	{
1184*cdf0e10cSrcweir 		if( pRestart && !pIosys->GetChannel() )
1185*cdf0e10cSrcweir 		{
1186*cdf0e10cSrcweir 			BasResId aId( IDS_SBERR_START + 4 );
1187*cdf0e10cSrcweir 			String aMsg( aId );
1188*cdf0e10cSrcweir 
1189*cdf0e10cSrcweir             //****** DONT CHECK IN, TEST ONLY *******
1190*cdf0e10cSrcweir             //****** DONT CHECK IN, TEST ONLY *******
1191*cdf0e10cSrcweir 			// ErrorBox( NULL, WB_OK, aMsg ).Execute();
1192*cdf0e10cSrcweir             //****** DONT CHECK IN, TEST ONLY *******
1193*cdf0e10cSrcweir             //****** DONT CHECK IN, TEST ONLY *******
1194*cdf0e10cSrcweir 
1195*cdf0e10cSrcweir 			pCode = pRestart;
1196*cdf0e10cSrcweir 		}
1197*cdf0e10cSrcweir 		else
1198*cdf0e10cSrcweir 			Error( err );
1199*cdf0e10cSrcweir 	}
1200*cdf0e10cSrcweir 	else
1201*cdf0e10cSrcweir 	{
1202*cdf0e10cSrcweir 		// pIosys->ResetChannel();
1203*cdf0e10cSrcweir 		PopVar();
1204*cdf0e10cSrcweir 	}
1205*cdf0e10cSrcweir }
1206*cdf0e10cSrcweir 
1207*cdf0e10cSrcweir // Line Input to Variable. Die Variable ist auf TOS und wird
1208*cdf0e10cSrcweir // anschliessend entfernt.
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir void SbiRuntime::StepLINPUT()
1211*cdf0e10cSrcweir {
1212*cdf0e10cSrcweir 	ByteString aInput;
1213*cdf0e10cSrcweir 	pIosys->Read( aInput );
1214*cdf0e10cSrcweir 	Error( pIosys->GetError() );
1215*cdf0e10cSrcweir 	SbxVariableRef p = PopVar();
1216*cdf0e10cSrcweir 	p->PutString( String( aInput, gsl_getSystemTextEncoding() ) );
1217*cdf0e10cSrcweir 	// pIosys->ResetChannel();
1218*cdf0e10cSrcweir }
1219*cdf0e10cSrcweir 
1220*cdf0e10cSrcweir // Programmende
1221*cdf0e10cSrcweir 
1222*cdf0e10cSrcweir void SbiRuntime::StepSTOP()
1223*cdf0e10cSrcweir {
1224*cdf0e10cSrcweir 	pInst->Stop();
1225*cdf0e10cSrcweir }
1226*cdf0e10cSrcweir 
1227*cdf0e10cSrcweir // FOR-Variable initialisieren
1228*cdf0e10cSrcweir 
1229*cdf0e10cSrcweir void SbiRuntime::StepINITFOR()
1230*cdf0e10cSrcweir {
1231*cdf0e10cSrcweir 	PushFor();
1232*cdf0e10cSrcweir }
1233*cdf0e10cSrcweir 
1234*cdf0e10cSrcweir void SbiRuntime::StepINITFOREACH()
1235*cdf0e10cSrcweir {
1236*cdf0e10cSrcweir 	PushForEach();
1237*cdf0e10cSrcweir }
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir // FOR-Variable inkrementieren
1240*cdf0e10cSrcweir 
1241*cdf0e10cSrcweir void SbiRuntime::StepNEXT()
1242*cdf0e10cSrcweir {
1243*cdf0e10cSrcweir 	if( !pForStk )
1244*cdf0e10cSrcweir 	{
1245*cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
1246*cdf0e10cSrcweir 		return;
1247*cdf0e10cSrcweir 	}
1248*cdf0e10cSrcweir 	if( pForStk->eForType == FOR_TO )
1249*cdf0e10cSrcweir 		pForStk->refVar->Compute( SbxPLUS, *pForStk->refInc );
1250*cdf0e10cSrcweir }
1251*cdf0e10cSrcweir 
1252*cdf0e10cSrcweir // Anfang CASE: TOS in CASE-Stack
1253*cdf0e10cSrcweir 
1254*cdf0e10cSrcweir void SbiRuntime::StepCASE()
1255*cdf0e10cSrcweir {
1256*cdf0e10cSrcweir 	if( !refCaseStk.Is() )
1257*cdf0e10cSrcweir 		refCaseStk = new SbxArray;
1258*cdf0e10cSrcweir 	SbxVariableRef xVar = PopVar();
1259*cdf0e10cSrcweir 	refCaseStk->Put( xVar, refCaseStk->Count() );
1260*cdf0e10cSrcweir }
1261*cdf0e10cSrcweir 
1262*cdf0e10cSrcweir // Ende CASE: Variable freigeben
1263*cdf0e10cSrcweir 
1264*cdf0e10cSrcweir void SbiRuntime::StepENDCASE()
1265*cdf0e10cSrcweir {
1266*cdf0e10cSrcweir 	if( !refCaseStk || !refCaseStk->Count() )
1267*cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
1268*cdf0e10cSrcweir 	else
1269*cdf0e10cSrcweir 		refCaseStk->Remove( refCaseStk->Count() - 1 );
1270*cdf0e10cSrcweir }
1271*cdf0e10cSrcweir 
1272*cdf0e10cSrcweir // Standard-Fehlerbehandlung
1273*cdf0e10cSrcweir 
1274*cdf0e10cSrcweir void SbiRuntime::StepSTDERROR()
1275*cdf0e10cSrcweir {
1276*cdf0e10cSrcweir 	pError = NULL; bError = sal_True;
1277*cdf0e10cSrcweir 	pInst->aErrorMsg = String();
1278*cdf0e10cSrcweir 	pInst->nErr = 0L;
1279*cdf0e10cSrcweir 	pInst->nErl = 0;
1280*cdf0e10cSrcweir 	nError = 0L;
1281*cdf0e10cSrcweir 	SbxErrObject::getUnoErrObject()->Clear();
1282*cdf0e10cSrcweir }
1283*cdf0e10cSrcweir 
1284*cdf0e10cSrcweir void SbiRuntime::StepNOERROR()
1285*cdf0e10cSrcweir {
1286*cdf0e10cSrcweir 	pInst->aErrorMsg = String();
1287*cdf0e10cSrcweir 	pInst->nErr = 0L;
1288*cdf0e10cSrcweir 	pInst->nErl = 0;
1289*cdf0e10cSrcweir 	nError = 0L;
1290*cdf0e10cSrcweir 	SbxErrObject::getUnoErrObject()->Clear();
1291*cdf0e10cSrcweir 	bError = sal_False;
1292*cdf0e10cSrcweir }
1293*cdf0e10cSrcweir 
1294*cdf0e10cSrcweir // UP verlassen
1295*cdf0e10cSrcweir 
1296*cdf0e10cSrcweir void SbiRuntime::StepLEAVE()
1297*cdf0e10cSrcweir {
1298*cdf0e10cSrcweir 	bRun = sal_False;
1299*cdf0e10cSrcweir         // If VBA and we are leaving an ErrorHandler then clear the error ( it's been processed )
1300*cdf0e10cSrcweir 	if ( bInError && pError )
1301*cdf0e10cSrcweir 	    SbxErrObject::getUnoErrObject()->Clear();
1302*cdf0e10cSrcweir }
1303*cdf0e10cSrcweir 
1304*cdf0e10cSrcweir void SbiRuntime::StepCHANNEL()	  	// TOS = Kanalnummer
1305*cdf0e10cSrcweir {
1306*cdf0e10cSrcweir 	SbxVariableRef pChan = PopVar();
1307*cdf0e10cSrcweir 	short nChan = pChan->GetInteger();
1308*cdf0e10cSrcweir 	pIosys->SetChannel( nChan );
1309*cdf0e10cSrcweir 	Error( pIosys->GetError() );
1310*cdf0e10cSrcweir }
1311*cdf0e10cSrcweir 
1312*cdf0e10cSrcweir void SbiRuntime::StepCHANNEL0()
1313*cdf0e10cSrcweir {
1314*cdf0e10cSrcweir 	pIosys->ResetChannel();
1315*cdf0e10cSrcweir }
1316*cdf0e10cSrcweir 
1317*cdf0e10cSrcweir void SbiRuntime::StepPRINT()	  	// print TOS
1318*cdf0e10cSrcweir {
1319*cdf0e10cSrcweir 	SbxVariableRef p = PopVar();
1320*cdf0e10cSrcweir 	String s1 = p->GetString();
1321*cdf0e10cSrcweir 	String s;
1322*cdf0e10cSrcweir 	if( p->GetType() >= SbxINTEGER && p->GetType() <= SbxDOUBLE )
1323*cdf0e10cSrcweir 		s = ' ';	// ein Blank davor
1324*cdf0e10cSrcweir 	s += s1;
1325*cdf0e10cSrcweir 	ByteString aByteStr( s, gsl_getSystemTextEncoding() );
1326*cdf0e10cSrcweir 	pIosys->Write( aByteStr );
1327*cdf0e10cSrcweir 	Error( pIosys->GetError() );
1328*cdf0e10cSrcweir }
1329*cdf0e10cSrcweir 
1330*cdf0e10cSrcweir void SbiRuntime::StepPRINTF()	  	// print TOS in field
1331*cdf0e10cSrcweir {
1332*cdf0e10cSrcweir 	SbxVariableRef p = PopVar();
1333*cdf0e10cSrcweir 	String s1 = p->GetString();
1334*cdf0e10cSrcweir 	String s;
1335*cdf0e10cSrcweir 	if( p->GetType() >= SbxINTEGER && p->GetType() <= SbxDOUBLE )
1336*cdf0e10cSrcweir 		s = ' ';	// ein Blank davor
1337*cdf0e10cSrcweir 	s += s1;
1338*cdf0e10cSrcweir 	s.Expand( 14, ' ' );
1339*cdf0e10cSrcweir 	ByteString aByteStr( s, gsl_getSystemTextEncoding() );
1340*cdf0e10cSrcweir 	pIosys->Write( aByteStr );
1341*cdf0e10cSrcweir 	Error( pIosys->GetError() );
1342*cdf0e10cSrcweir }
1343*cdf0e10cSrcweir 
1344*cdf0e10cSrcweir void SbiRuntime::StepWRITE()	  	// write TOS
1345*cdf0e10cSrcweir {
1346*cdf0e10cSrcweir 	SbxVariableRef p = PopVar();
1347*cdf0e10cSrcweir 	// Muss der String gekapselt werden?
1348*cdf0e10cSrcweir 	char ch = 0;
1349*cdf0e10cSrcweir 	switch (p->GetType() )
1350*cdf0e10cSrcweir 	{
1351*cdf0e10cSrcweir 		case SbxSTRING: ch = '"'; break;
1352*cdf0e10cSrcweir 		case SbxCURRENCY:
1353*cdf0e10cSrcweir 		case SbxBOOL:
1354*cdf0e10cSrcweir 		case SbxDATE: ch = '#'; break;
1355*cdf0e10cSrcweir 		default: break;
1356*cdf0e10cSrcweir 	}
1357*cdf0e10cSrcweir 	String s;
1358*cdf0e10cSrcweir 	if( ch )
1359*cdf0e10cSrcweir 		s += ch;
1360*cdf0e10cSrcweir 	s += p->GetString();
1361*cdf0e10cSrcweir 	if( ch )
1362*cdf0e10cSrcweir 		s += ch;
1363*cdf0e10cSrcweir 	ByteString aByteStr( s, gsl_getSystemTextEncoding() );
1364*cdf0e10cSrcweir 	pIosys->Write( aByteStr );
1365*cdf0e10cSrcweir 	Error( pIosys->GetError() );
1366*cdf0e10cSrcweir }
1367*cdf0e10cSrcweir 
1368*cdf0e10cSrcweir void SbiRuntime::StepRENAME()	  	// Rename Tos+1 to Tos
1369*cdf0e10cSrcweir {
1370*cdf0e10cSrcweir 	SbxVariableRef pTos1 = PopVar();
1371*cdf0e10cSrcweir 	SbxVariableRef pTos  = PopVar();
1372*cdf0e10cSrcweir 	String aDest = pTos1->GetString();
1373*cdf0e10cSrcweir 	String aSource = pTos->GetString();
1374*cdf0e10cSrcweir 
1375*cdf0e10cSrcweir 	// <-- UCB
1376*cdf0e10cSrcweir 	if( hasUno() )
1377*cdf0e10cSrcweir 	{
1378*cdf0e10cSrcweir 		implStepRenameUCB( aSource, aDest );
1379*cdf0e10cSrcweir 	}
1380*cdf0e10cSrcweir 	else
1381*cdf0e10cSrcweir 	// --> UCB
1382*cdf0e10cSrcweir 	{
1383*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
1384*cdf0e10cSrcweir 		DirEntry aSourceDirEntry( aSource );
1385*cdf0e10cSrcweir 		if( aSourceDirEntry.Exists() )
1386*cdf0e10cSrcweir 		{
1387*cdf0e10cSrcweir 			if( aSourceDirEntry.MoveTo( DirEntry(aDest) ) != FSYS_ERR_OK )
1388*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
1389*cdf0e10cSrcweir 		}
1390*cdf0e10cSrcweir 		else
1391*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
1392*cdf0e10cSrcweir #else
1393*cdf0e10cSrcweir 		implStepRenameOSL( aSource, aDest );
1394*cdf0e10cSrcweir #endif
1395*cdf0e10cSrcweir 	}
1396*cdf0e10cSrcweir }
1397*cdf0e10cSrcweir 
1398*cdf0e10cSrcweir // TOS = Prompt
1399*cdf0e10cSrcweir 
1400*cdf0e10cSrcweir void SbiRuntime::StepPROMPT()
1401*cdf0e10cSrcweir {
1402*cdf0e10cSrcweir 	SbxVariableRef p = PopVar();
1403*cdf0e10cSrcweir 	ByteString aStr( p->GetString(), gsl_getSystemTextEncoding() );
1404*cdf0e10cSrcweir 	pIosys->SetPrompt( aStr );
1405*cdf0e10cSrcweir }
1406*cdf0e10cSrcweir 
1407*cdf0e10cSrcweir // Set Restart point
1408*cdf0e10cSrcweir 
1409*cdf0e10cSrcweir void SbiRuntime::StepRESTART()
1410*cdf0e10cSrcweir {
1411*cdf0e10cSrcweir 	pRestart = pCode;
1412*cdf0e10cSrcweir }
1413*cdf0e10cSrcweir 
1414*cdf0e10cSrcweir // Leerer Ausdruck auf Stack fuer fehlenden Parameter
1415*cdf0e10cSrcweir 
1416*cdf0e10cSrcweir void SbiRuntime::StepEMPTY()
1417*cdf0e10cSrcweir {
1418*cdf0e10cSrcweir 	// #57915 Die Semantik von StepEMPTY() ist die Repraesentation eines fehlenden
1419*cdf0e10cSrcweir 	// Arguments. Dies wird in VB durch ein durch den Wert 448 (SbERR_NAMED_NOT_FOUND)
1420*cdf0e10cSrcweir 	// vom Typ Error repraesentiert. StepEmpty jetzt muesste besser StepMISSING()
1421*cdf0e10cSrcweir 	// heissen, aber der Name wird der Einfachkeit halber beibehalten.
1422*cdf0e10cSrcweir 	SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
1423*cdf0e10cSrcweir 	xVar->PutErr( 448 );
1424*cdf0e10cSrcweir 	PushVar( xVar );
1425*cdf0e10cSrcweir 	// ALT: PushVar( new SbxVariable( SbxEMPTY ) );
1426*cdf0e10cSrcweir }
1427*cdf0e10cSrcweir 
1428*cdf0e10cSrcweir // TOS = Fehlercode
1429*cdf0e10cSrcweir 
1430*cdf0e10cSrcweir void SbiRuntime::StepERROR()
1431*cdf0e10cSrcweir {
1432*cdf0e10cSrcweir 	SbxVariableRef refCode = PopVar();
1433*cdf0e10cSrcweir 	sal_uInt16 n = refCode->GetUShort();
1434*cdf0e10cSrcweir 	SbError error = StarBASIC::GetSfxFromVBError( n );
1435*cdf0e10cSrcweir 	if ( bVBAEnabled )
1436*cdf0e10cSrcweir 		pInst->Error( error );
1437*cdf0e10cSrcweir 	else
1438*cdf0e10cSrcweir 		Error( error );
1439*cdf0e10cSrcweir }
1440*cdf0e10cSrcweir 
1441