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