xref: /aoo41x/main/basic/source/runtime/step1.cxx (revision e1f63238)
1*e1f63238SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*e1f63238SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*e1f63238SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*e1f63238SAndrew Rist  * distributed with this work for additional information
6*e1f63238SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*e1f63238SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*e1f63238SAndrew Rist  * "License"); you may not use this file except in compliance
9*e1f63238SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*e1f63238SAndrew Rist  *
11*e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*e1f63238SAndrew Rist  *
13*e1f63238SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*e1f63238SAndrew Rist  * software distributed under the License is distributed on an
15*e1f63238SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*e1f63238SAndrew Rist  * KIND, either express or implied.  See the License for the
17*e1f63238SAndrew Rist  * specific language governing permissions and limitations
18*e1f63238SAndrew Rist  * under the License.
19*e1f63238SAndrew Rist  *
20*e1f63238SAndrew Rist  *************************************************************/
21*e1f63238SAndrew Rist 
22*e1f63238SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_basic.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <stdlib.h>
28cdf0e10cSrcweir #include <rtl/math.hxx>
29cdf0e10cSrcweir #include <basic/sbuno.hxx>
30cdf0e10cSrcweir #include "runtime.hxx"
31cdf0e10cSrcweir #include "sbintern.hxx"
32cdf0e10cSrcweir #include "iosys.hxx"
33cdf0e10cSrcweir #include "image.hxx"
34cdf0e10cSrcweir #include "sbunoobj.hxx"
35cdf0e10cSrcweir #include "errobject.hxx"
36cdf0e10cSrcweir 
37cdf0e10cSrcweir bool checkUnoObjectType( SbUnoObject* refVal, const ::rtl::OUString& aClass );
38cdf0e10cSrcweir 
39cdf0e10cSrcweir // Laden einer numerischen Konstanten (+ID)
40cdf0e10cSrcweir 
StepLOADNC(sal_uInt32 nOp1)41cdf0e10cSrcweir void SbiRuntime::StepLOADNC( sal_uInt32 nOp1 )
42cdf0e10cSrcweir {
43cdf0e10cSrcweir 	SbxVariable* p = new SbxVariable( SbxDOUBLE );
44cdf0e10cSrcweir 
45cdf0e10cSrcweir 	// #57844 Lokalisierte Funktion benutzen
46cdf0e10cSrcweir 	String aStr = pImg->GetString( static_cast<short>( nOp1 ) );
47cdf0e10cSrcweir 	// Auch , zulassen !!!
48cdf0e10cSrcweir 	sal_uInt16 iComma = aStr.Search( ',' );
49cdf0e10cSrcweir 	if( iComma != STRING_NOTFOUND )
50cdf0e10cSrcweir 	{
51cdf0e10cSrcweir 		String aStr1 = aStr.Copy( 0, iComma );
52cdf0e10cSrcweir 		String aStr2 = aStr.Copy( iComma + 1 );
53cdf0e10cSrcweir 		aStr = aStr1;
54cdf0e10cSrcweir 		aStr += '.';
55cdf0e10cSrcweir 		aStr += aStr2;
56cdf0e10cSrcweir 	}
57cdf0e10cSrcweir     double n = ::rtl::math::stringToDouble( aStr, '.', ',', NULL, NULL );
58cdf0e10cSrcweir 
59cdf0e10cSrcweir 	p->PutDouble( n );
60cdf0e10cSrcweir 	PushVar( p );
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir // Laden einer Stringkonstanten (+ID)
64cdf0e10cSrcweir 
StepLOADSC(sal_uInt32 nOp1)65cdf0e10cSrcweir void SbiRuntime::StepLOADSC( sal_uInt32 nOp1 )
66cdf0e10cSrcweir {
67cdf0e10cSrcweir 	SbxVariable* p = new SbxVariable;
68cdf0e10cSrcweir 	p->PutString( pImg->GetString( static_cast<short>( nOp1 ) ) );
69cdf0e10cSrcweir 	PushVar( p );
70cdf0e10cSrcweir }
71cdf0e10cSrcweir 
72cdf0e10cSrcweir // Immediate Load (+Wert)
73cdf0e10cSrcweir 
StepLOADI(sal_uInt32 nOp1)74cdf0e10cSrcweir void SbiRuntime::StepLOADI( sal_uInt32 nOp1 )
75cdf0e10cSrcweir {
76cdf0e10cSrcweir 	SbxVariable* p = new SbxVariable;
77cdf0e10cSrcweir 	p->PutInteger( static_cast<sal_Int16>( nOp1 ) );
78cdf0e10cSrcweir 	PushVar( p );
79cdf0e10cSrcweir }
80cdf0e10cSrcweir 
81cdf0e10cSrcweir // Speichern eines named Arguments in Argv (+Arg-Nr ab 1!)
82cdf0e10cSrcweir 
StepARGN(sal_uInt32 nOp1)83cdf0e10cSrcweir void SbiRuntime::StepARGN( sal_uInt32 nOp1 )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir 	if( !refArgv )
86cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
87cdf0e10cSrcweir 	else
88cdf0e10cSrcweir 	{
89cdf0e10cSrcweir 		String aAlias( pImg->GetString( static_cast<short>( nOp1 ) ) );
90cdf0e10cSrcweir 		SbxVariableRef pVal = PopVar();
91cdf0e10cSrcweir 		refArgv->Put( pVal, nArgc );
92cdf0e10cSrcweir 		refArgv->PutAlias( aAlias, nArgc++ );
93cdf0e10cSrcweir 	}
94cdf0e10cSrcweir }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir // Konvertierung des Typs eines Arguments in Argv fuer DECLARE-Fkt. (+Typ)
97cdf0e10cSrcweir 
StepARGTYP(sal_uInt32 nOp1)98cdf0e10cSrcweir void SbiRuntime::StepARGTYP( sal_uInt32 nOp1 )
99cdf0e10cSrcweir {
100cdf0e10cSrcweir 	if( !refArgv )
101cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
102cdf0e10cSrcweir 	else
103cdf0e10cSrcweir 	{
104cdf0e10cSrcweir 		sal_Bool bByVal = (nOp1 & 0x8000) != 0;			// Ist BYVAL verlangt?
105cdf0e10cSrcweir 		SbxDataType t = (SbxDataType) (nOp1 & 0x7FFF);
106cdf0e10cSrcweir 		SbxVariable* pVar = refArgv->Get( refArgv->Count() - 1 );	// letztes Arg
107cdf0e10cSrcweir 
108cdf0e10cSrcweir 		// BYVAL pr�fen
109cdf0e10cSrcweir 		if( pVar->GetRefCount() > 2 )		// 2 ist normal f�r BYVAL
110cdf0e10cSrcweir 		{
111cdf0e10cSrcweir 			// Parameter ist eine Referenz
112cdf0e10cSrcweir 			if( bByVal )
113cdf0e10cSrcweir 			{
114cdf0e10cSrcweir 				// Call by Value ist verlangt -> Kopie anlegen
115cdf0e10cSrcweir 				pVar = new SbxVariable( *pVar );
116cdf0e10cSrcweir 				pVar->SetFlag( SBX_READWRITE );
117cdf0e10cSrcweir 				refExprStk->Put( pVar, refArgv->Count() - 1 );
118cdf0e10cSrcweir 			}
119cdf0e10cSrcweir 			else
120cdf0e10cSrcweir 				pVar->SetFlag( SBX_REFERENCE );		// Ref-Flag f�r DllMgr
121cdf0e10cSrcweir 		}
122cdf0e10cSrcweir 		else
123cdf0e10cSrcweir 		{
124cdf0e10cSrcweir 			// Parameter ist KEINE Referenz
125cdf0e10cSrcweir 			if( bByVal )
126cdf0e10cSrcweir 				pVar->ResetFlag( SBX_REFERENCE );	// Keine Referenz -> OK
127cdf0e10cSrcweir 			else
128cdf0e10cSrcweir 				Error( SbERR_BAD_PARAMETERS );		// Referenz verlangt
129cdf0e10cSrcweir 		}
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 		if( pVar->GetType() != t )
132cdf0e10cSrcweir 		{
133cdf0e10cSrcweir 			// Variant, damit richtige Konvertierung
134cdf0e10cSrcweir 			// Ausserdem Fehler, wenn SbxBYREF
135cdf0e10cSrcweir 			pVar->Convert( SbxVARIANT );
136cdf0e10cSrcweir 			pVar->Convert( t );
137cdf0e10cSrcweir 		}
138cdf0e10cSrcweir 	}
139cdf0e10cSrcweir }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir // String auf feste Laenge bringen (+Laenge)
142cdf0e10cSrcweir 
StepPAD(sal_uInt32 nOp1)143cdf0e10cSrcweir void SbiRuntime::StepPAD( sal_uInt32 nOp1 )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir 	SbxVariable* p = GetTOS();
146cdf0e10cSrcweir 	String& s = (String&)(const String&) *p;
147cdf0e10cSrcweir 	if( s.Len() > nOp1 )
148cdf0e10cSrcweir 		s.Erase( static_cast<xub_StrLen>( nOp1 ) );
149cdf0e10cSrcweir 	else
150cdf0e10cSrcweir 		s.Expand( static_cast<xub_StrLen>( nOp1 ), ' ' );
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir // Sprung (+Target)
154cdf0e10cSrcweir 
StepJUMP(sal_uInt32 nOp1)155cdf0e10cSrcweir void SbiRuntime::StepJUMP( sal_uInt32 nOp1 )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir #ifdef DBG_UTIL
158cdf0e10cSrcweir 	// #QUESTION shouln't this be
159cdf0e10cSrcweir 	// if( (sal_uInt8*)( nOp1+pImagGetCode() ) >= pImg->GetCodeSize() )
160cdf0e10cSrcweir 	if( nOp1 >= pImg->GetCodeSize() )
161cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
162cdf0e10cSrcweir #endif
163cdf0e10cSrcweir 	pCode = (const sal_uInt8*) pImg->GetCode() + nOp1;
164cdf0e10cSrcweir }
165cdf0e10cSrcweir 
166cdf0e10cSrcweir // TOS auswerten, bedingter Sprung (+Target)
167cdf0e10cSrcweir 
StepJUMPT(sal_uInt32 nOp1)168cdf0e10cSrcweir void SbiRuntime::StepJUMPT( sal_uInt32 nOp1 )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir 	SbxVariableRef p = PopVar();
171cdf0e10cSrcweir 	if( p->GetBool() )
172cdf0e10cSrcweir 		StepJUMP( nOp1 );
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir // TOS auswerten, bedingter Sprung (+Target)
176cdf0e10cSrcweir 
StepJUMPF(sal_uInt32 nOp1)177cdf0e10cSrcweir void SbiRuntime::StepJUMPF( sal_uInt32 nOp1 )
178cdf0e10cSrcweir {
179cdf0e10cSrcweir 	SbxVariableRef p = PopVar();
180cdf0e10cSrcweir 	if( !p->GetBool() )
181cdf0e10cSrcweir 		StepJUMP( nOp1 );
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir // TOS auswerten, Sprung in JUMP-Tabelle (+MaxVal)
185cdf0e10cSrcweir // Sieht so aus:
186cdf0e10cSrcweir // ONJUMP 2
187cdf0e10cSrcweir // JUMP target1
188cdf0e10cSrcweir // JUMP target2
189cdf0e10cSrcweir // ...
190cdf0e10cSrcweir //Falls im Operanden 0x8000 gesetzt ist, Returnadresse pushen (ON..GOSUB)
191cdf0e10cSrcweir 
StepONJUMP(sal_uInt32 nOp1)192cdf0e10cSrcweir void SbiRuntime::StepONJUMP( sal_uInt32 nOp1 )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir 	SbxVariableRef p = PopVar();
195cdf0e10cSrcweir 	sal_Int16 n = p->GetInteger();
196cdf0e10cSrcweir 	if( nOp1 & 0x8000 )
197cdf0e10cSrcweir 	{
198cdf0e10cSrcweir 		nOp1 &= 0x7FFF;
199cdf0e10cSrcweir 		//PushGosub( pCode + 3 * nOp1 );
200cdf0e10cSrcweir 		PushGosub( pCode + 5 * nOp1 );
201cdf0e10cSrcweir 	}
202cdf0e10cSrcweir 	if( n < 1 || static_cast<sal_uInt32>(n) > nOp1 )
203cdf0e10cSrcweir 		n = static_cast<sal_Int16>( nOp1 + 1 );
204cdf0e10cSrcweir 	//nOp1 = (sal_uInt32) ( (const char*) pCode - pImg->GetCode() ) + 3 * --n;
205cdf0e10cSrcweir 	nOp1 = (sal_uInt32) ( (const char*) pCode - pImg->GetCode() ) + 5 * --n;
206cdf0e10cSrcweir 	StepJUMP( nOp1 );
207cdf0e10cSrcweir }
208cdf0e10cSrcweir 
209cdf0e10cSrcweir // UP-Aufruf (+Target)
210cdf0e10cSrcweir 
StepGOSUB(sal_uInt32 nOp1)211cdf0e10cSrcweir void SbiRuntime::StepGOSUB( sal_uInt32 nOp1 )
212cdf0e10cSrcweir {
213cdf0e10cSrcweir 	PushGosub( pCode );
214cdf0e10cSrcweir 	if( nOp1 >= pImg->GetCodeSize() )
215cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
216cdf0e10cSrcweir 	pCode = (const sal_uInt8*) pImg->GetCode() + nOp1;
217cdf0e10cSrcweir }
218cdf0e10cSrcweir 
219cdf0e10cSrcweir // UP-Return (+0 oder Target)
220cdf0e10cSrcweir 
StepRETURN(sal_uInt32 nOp1)221cdf0e10cSrcweir void SbiRuntime::StepRETURN( sal_uInt32 nOp1 )
222cdf0e10cSrcweir {
223cdf0e10cSrcweir 	PopGosub();
224cdf0e10cSrcweir 	if( nOp1 )
225cdf0e10cSrcweir 		StepJUMP( nOp1 );
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir // FOR-Variable testen (+Endlabel)
229cdf0e10cSrcweir 
StepTESTFOR(sal_uInt32 nOp1)230cdf0e10cSrcweir void SbiRuntime::StepTESTFOR( sal_uInt32 nOp1 )
231cdf0e10cSrcweir {
232cdf0e10cSrcweir 	if( !pForStk )
233cdf0e10cSrcweir 	{
234cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
235cdf0e10cSrcweir 		return;
236cdf0e10cSrcweir 	}
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 	bool bEndLoop = false;
239cdf0e10cSrcweir 	switch( pForStk->eForType )
240cdf0e10cSrcweir 	{
241cdf0e10cSrcweir 		case FOR_TO:
242cdf0e10cSrcweir 		{
243cdf0e10cSrcweir 			SbxOperator eOp = ( pForStk->refInc->GetDouble() < 0 ) ? SbxLT : SbxGT;
244cdf0e10cSrcweir 			if( pForStk->refVar->Compare( eOp, *pForStk->refEnd ) )
245cdf0e10cSrcweir 				bEndLoop = true;
246cdf0e10cSrcweir 			break;
247cdf0e10cSrcweir 		}
248cdf0e10cSrcweir 		case FOR_EACH_ARRAY:
249cdf0e10cSrcweir 		{
250cdf0e10cSrcweir 			SbiForStack* p = pForStk;
251cdf0e10cSrcweir 			if( p->pArrayCurIndices == NULL )
252cdf0e10cSrcweir 			{
253cdf0e10cSrcweir 				bEndLoop = true;
254cdf0e10cSrcweir 			}
255cdf0e10cSrcweir 			else
256cdf0e10cSrcweir 			{
257cdf0e10cSrcweir 				SbxDimArray* pArray = (SbxDimArray*)(SbxVariable*)p->refEnd;
258cdf0e10cSrcweir 				short nDims = pArray->GetDims();
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 				// Empty array?
261cdf0e10cSrcweir 				if( nDims == 1 && p->pArrayLowerBounds[0] > p->pArrayUpperBounds[0] )
262cdf0e10cSrcweir 				{
263cdf0e10cSrcweir 					bEndLoop = true;
264cdf0e10cSrcweir 					break;
265cdf0e10cSrcweir 				}
266cdf0e10cSrcweir 				SbxVariable* pVal = pArray->Get32( p->pArrayCurIndices );
267cdf0e10cSrcweir 				*(p->refVar) = *pVal;
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 				bool bFoundNext = false;
270cdf0e10cSrcweir 				for( short i = 0 ; i < nDims ; i++ )
271cdf0e10cSrcweir 				{
272cdf0e10cSrcweir 					if( p->pArrayCurIndices[i] < p->pArrayUpperBounds[i] )
273cdf0e10cSrcweir 					{
274cdf0e10cSrcweir 						bFoundNext = true;
275cdf0e10cSrcweir 						p->pArrayCurIndices[i]++;
276cdf0e10cSrcweir 						for( short j = i - 1 ; j >= 0 ; j-- )
277cdf0e10cSrcweir 							p->pArrayCurIndices[j] = p->pArrayLowerBounds[j];
278cdf0e10cSrcweir 						break;
279cdf0e10cSrcweir 					}
280cdf0e10cSrcweir 				}
281cdf0e10cSrcweir 				if( !bFoundNext )
282cdf0e10cSrcweir 				{
283cdf0e10cSrcweir 					delete[] p->pArrayCurIndices;
284cdf0e10cSrcweir 					p->pArrayCurIndices = NULL;
285cdf0e10cSrcweir 				}
286cdf0e10cSrcweir 			}
287cdf0e10cSrcweir 			break;
288cdf0e10cSrcweir 		}
289cdf0e10cSrcweir 		case FOR_EACH_COLLECTION:
290cdf0e10cSrcweir 		{
291cdf0e10cSrcweir 			BasicCollection* pCollection = (BasicCollection*)(SbxVariable*)pForStk->refEnd;
292cdf0e10cSrcweir 			SbxArrayRef xItemArray = pCollection->xItemArray;
293cdf0e10cSrcweir 			sal_Int32 nCount = xItemArray->Count32();
294cdf0e10cSrcweir 			if( pForStk->nCurCollectionIndex < nCount )
295cdf0e10cSrcweir 			{
296cdf0e10cSrcweir 				SbxVariable* pRes = xItemArray->Get32( pForStk->nCurCollectionIndex );
297cdf0e10cSrcweir 				pForStk->nCurCollectionIndex++;
298cdf0e10cSrcweir 				(*pForStk->refVar) = *pRes;
299cdf0e10cSrcweir 			}
300cdf0e10cSrcweir 			else
301cdf0e10cSrcweir 			{
302cdf0e10cSrcweir 				bEndLoop = true;
303cdf0e10cSrcweir 			}
304cdf0e10cSrcweir 			break;
305cdf0e10cSrcweir 		}
306cdf0e10cSrcweir 		case FOR_EACH_XENUMERATION:
307cdf0e10cSrcweir 		{
308cdf0e10cSrcweir 			SbiForStack* p = pForStk;
309cdf0e10cSrcweir 			if( p->xEnumeration->hasMoreElements() )
310cdf0e10cSrcweir 			{
311cdf0e10cSrcweir 				Any aElem = p->xEnumeration->nextElement();
312cdf0e10cSrcweir 				SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
313cdf0e10cSrcweir 				unoToSbxValue( (SbxVariable*)xVar, aElem );
314cdf0e10cSrcweir 				(*pForStk->refVar) = *xVar;
315cdf0e10cSrcweir 			}
316cdf0e10cSrcweir 			else
317cdf0e10cSrcweir 			{
318cdf0e10cSrcweir 				bEndLoop = true;
319cdf0e10cSrcweir 			}
320cdf0e10cSrcweir 			break;
321cdf0e10cSrcweir 		}
322cdf0e10cSrcweir 	}
323cdf0e10cSrcweir 	if( bEndLoop )
324cdf0e10cSrcweir 	{
325cdf0e10cSrcweir 		PopFor();
326cdf0e10cSrcweir 		StepJUMP( nOp1 );
327cdf0e10cSrcweir 	}
328cdf0e10cSrcweir }
329cdf0e10cSrcweir 
330cdf0e10cSrcweir // Tos+1 <= Tos+2 <= Tos, 2xremove (+Target)
331cdf0e10cSrcweir 
StepCASETO(sal_uInt32 nOp1)332cdf0e10cSrcweir void SbiRuntime::StepCASETO( sal_uInt32 nOp1 )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir 	if( !refCaseStk || !refCaseStk->Count() )
335cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
336cdf0e10cSrcweir 	else
337cdf0e10cSrcweir 	{
338cdf0e10cSrcweir 		SbxVariableRef xTo   = PopVar();
339cdf0e10cSrcweir 		SbxVariableRef xFrom = PopVar();
340cdf0e10cSrcweir 		SbxVariableRef xCase = refCaseStk->Get( refCaseStk->Count() - 1 );
341cdf0e10cSrcweir 		if( *xCase >= *xFrom && *xCase <= *xTo )
342cdf0e10cSrcweir 			StepJUMP( nOp1 );
343cdf0e10cSrcweir 	}
344cdf0e10cSrcweir }
345cdf0e10cSrcweir 
346cdf0e10cSrcweir // Fehler-Handler
347cdf0e10cSrcweir 
StepERRHDL(sal_uInt32 nOp1)348cdf0e10cSrcweir void SbiRuntime::StepERRHDL( sal_uInt32 nOp1 )
349cdf0e10cSrcweir {
350cdf0e10cSrcweir 	const sal_uInt8* p = pCode;
351cdf0e10cSrcweir 	StepJUMP( nOp1 );
352cdf0e10cSrcweir 	pError = pCode;
353cdf0e10cSrcweir 	pCode = p;
354cdf0e10cSrcweir 	pInst->aErrorMsg = String();
355cdf0e10cSrcweir 	pInst->nErr = 0;
356cdf0e10cSrcweir 	pInst->nErl = 0;
357cdf0e10cSrcweir 	nError = 0;
358cdf0e10cSrcweir 	SbxErrObject::getUnoErrObject()->Clear();
359cdf0e10cSrcweir }
360cdf0e10cSrcweir 
361cdf0e10cSrcweir // Resume nach Fehlern (+0=statement, 1=next or Label)
362cdf0e10cSrcweir 
StepRESUME(sal_uInt32 nOp1)363cdf0e10cSrcweir void SbiRuntime::StepRESUME( sal_uInt32 nOp1 )
364cdf0e10cSrcweir {
365cdf0e10cSrcweir 	// AB #32714 Resume ohne Error? -> Fehler
366cdf0e10cSrcweir 	if( !bInError )
367cdf0e10cSrcweir 	{
368cdf0e10cSrcweir 		Error( SbERR_BAD_RESUME );
369cdf0e10cSrcweir 		return;
370cdf0e10cSrcweir 	}
371cdf0e10cSrcweir 	if( nOp1 )
372cdf0e10cSrcweir 	{
373cdf0e10cSrcweir 		// Code-Zeiger auf naechstes Statement setzen
374cdf0e10cSrcweir 		sal_uInt16 n1, n2;
375cdf0e10cSrcweir 		pCode = pMod->FindNextStmnt( pErrCode, n1, n2, sal_True, pImg );
376cdf0e10cSrcweir 	}
377cdf0e10cSrcweir 	else
378cdf0e10cSrcweir 		pCode = pErrStmnt;
379cdf0e10cSrcweir 	if ( pError ) // current in error handler ( and got a Resume Next statment )
380cdf0e10cSrcweir 		SbxErrObject::getUnoErrObject()->Clear();
381cdf0e10cSrcweir 
382cdf0e10cSrcweir 	if( nOp1 > 1 )
383cdf0e10cSrcweir 		StepJUMP( nOp1 );
384cdf0e10cSrcweir 	pInst->aErrorMsg = String();
385cdf0e10cSrcweir 	pInst->nErr = 0;
386cdf0e10cSrcweir 	pInst->nErl = 0;
387cdf0e10cSrcweir 	nError = 0;
388cdf0e10cSrcweir 	bInError = sal_False;
389cdf0e10cSrcweir 
390cdf0e10cSrcweir 	// Error-Stack loeschen
391cdf0e10cSrcweir 	SbErrorStack*& rErrStack = GetSbData()->pErrStack;
392cdf0e10cSrcweir 	delete rErrStack;
393cdf0e10cSrcweir 	rErrStack = NULL;
394cdf0e10cSrcweir }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir // Kanal schliessen (+Kanal, 0=Alle)
StepCLOSE(sal_uInt32 nOp1)397cdf0e10cSrcweir void SbiRuntime::StepCLOSE( sal_uInt32 nOp1 )
398cdf0e10cSrcweir {
399cdf0e10cSrcweir 	SbError err;
400cdf0e10cSrcweir 	if( !nOp1 )
401cdf0e10cSrcweir 		pIosys->Shutdown();
402cdf0e10cSrcweir 	else
403cdf0e10cSrcweir 	{
404cdf0e10cSrcweir 		err = pIosys->GetError();
405cdf0e10cSrcweir 		if( !err )
406cdf0e10cSrcweir 		{
407cdf0e10cSrcweir 			pIosys->Close();
408cdf0e10cSrcweir 		}
409cdf0e10cSrcweir 	}
410cdf0e10cSrcweir 	err = pIosys->GetError();
411cdf0e10cSrcweir 	Error( err );
412cdf0e10cSrcweir }
413cdf0e10cSrcweir 
414cdf0e10cSrcweir // Zeichen ausgeben (+char)
415cdf0e10cSrcweir 
StepPRCHAR(sal_uInt32 nOp1)416cdf0e10cSrcweir void SbiRuntime::StepPRCHAR( sal_uInt32 nOp1 )
417cdf0e10cSrcweir {
418cdf0e10cSrcweir 	ByteString s( (char) nOp1 );
419cdf0e10cSrcweir 	pIosys->Write( s );
420cdf0e10cSrcweir 	Error( pIosys->GetError() );
421cdf0e10cSrcweir }
422cdf0e10cSrcweir 
423cdf0e10cSrcweir // Check, ob TOS eine bestimmte Objektklasse ist (+StringID)
424cdf0e10cSrcweir 
implIsClass(SbxObject * pObj,const String & aClass)425cdf0e10cSrcweir bool SbiRuntime::implIsClass( SbxObject* pObj, const String& aClass )
426cdf0e10cSrcweir {
427cdf0e10cSrcweir 	bool bRet = true;
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 	if( aClass.Len() != 0 )
430cdf0e10cSrcweir 	{
431cdf0e10cSrcweir 		bRet = pObj->IsClass( aClass );
432cdf0e10cSrcweir 		if( !bRet )
433cdf0e10cSrcweir 			bRet = aClass.EqualsIgnoreCaseAscii( String( RTL_CONSTASCII_USTRINGPARAM("object") ) );
434cdf0e10cSrcweir 		if( !bRet )
435cdf0e10cSrcweir 		{
436cdf0e10cSrcweir 			String aObjClass = pObj->GetClassName();
437cdf0e10cSrcweir 			SbModule* pClassMod = pCLASSFAC->FindClass( aObjClass );
438cdf0e10cSrcweir 			SbClassData* pClassData;
439cdf0e10cSrcweir 			if( pClassMod && (pClassData=pClassMod->pClassData) != NULL )
440cdf0e10cSrcweir 			{
441cdf0e10cSrcweir 				SbxVariable* pClassVar =
442cdf0e10cSrcweir 					pClassData->mxIfaces->Find( aClass, SbxCLASS_DONTCARE );
443cdf0e10cSrcweir 				bRet = (pClassVar != NULL);
444cdf0e10cSrcweir 			}
445cdf0e10cSrcweir 		}
446cdf0e10cSrcweir 	}
447cdf0e10cSrcweir 	return bRet;
448cdf0e10cSrcweir }
449cdf0e10cSrcweir 
checkClass_Impl(const SbxVariableRef & refVal,const String & aClass,bool bRaiseErrors,bool bDefault)450cdf0e10cSrcweir bool SbiRuntime::checkClass_Impl( const SbxVariableRef& refVal,
451cdf0e10cSrcweir 	const String& aClass, bool bRaiseErrors, bool bDefault )
452cdf0e10cSrcweir {
453cdf0e10cSrcweir 	bool bOk = bDefault;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 	SbxDataType t = refVal->GetType();
456cdf0e10cSrcweir 	if( t == SbxOBJECT )
457cdf0e10cSrcweir 	{
458cdf0e10cSrcweir 		SbxObject* pObj;
459cdf0e10cSrcweir 		SbxVariable* pVal = (SbxVariable*)refVal;
460cdf0e10cSrcweir 		if( pVal->IsA( TYPE(SbxObject) ) )
461cdf0e10cSrcweir 			pObj = (SbxObject*) pVal;
462cdf0e10cSrcweir 		else
463cdf0e10cSrcweir 		{
464cdf0e10cSrcweir 			pObj = (SbxObject*) refVal->GetObject();
465cdf0e10cSrcweir 			if( pObj && !pObj->IsA( TYPE(SbxObject) ) )
466cdf0e10cSrcweir 				pObj = NULL;
467cdf0e10cSrcweir 		}
468cdf0e10cSrcweir 		if( pObj )
469cdf0e10cSrcweir 		{
470cdf0e10cSrcweir 			if( !implIsClass( pObj, aClass ) )
471cdf0e10cSrcweir 			{
472cdf0e10cSrcweir 				if ( bVBAEnabled && pObj->IsA( TYPE(SbUnoObject) ) )
473cdf0e10cSrcweir 				{
474cdf0e10cSrcweir 					SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj);
475cdf0e10cSrcweir 					bOk = checkUnoObjectType( pUnoObj, aClass );
476cdf0e10cSrcweir 				}
477cdf0e10cSrcweir 				else
478cdf0e10cSrcweir 					bOk = false;
479cdf0e10cSrcweir 				if ( !bOk )
480cdf0e10cSrcweir 				{
481cdf0e10cSrcweir 					if( bRaiseErrors )
482cdf0e10cSrcweir 						Error( SbERR_INVALID_USAGE_OBJECT );
483cdf0e10cSrcweir 				}
484cdf0e10cSrcweir 			}
485cdf0e10cSrcweir 			else
486cdf0e10cSrcweir 			{
487cdf0e10cSrcweir 				bOk = true;
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 				SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pObj);
490cdf0e10cSrcweir 				if( pClassModuleObject != NULL )
491cdf0e10cSrcweir 					pClassModuleObject->triggerInitializeEvent();
492cdf0e10cSrcweir 			}
493cdf0e10cSrcweir 		}
494cdf0e10cSrcweir 	}
495cdf0e10cSrcweir 	else
496cdf0e10cSrcweir 	{
497cdf0e10cSrcweir 		if ( !bVBAEnabled )
498cdf0e10cSrcweir 		{
499cdf0e10cSrcweir 			if( bRaiseErrors )
500cdf0e10cSrcweir 				Error( SbERR_NEEDS_OBJECT );
501cdf0e10cSrcweir 			bOk = false;
502cdf0e10cSrcweir 		}
503cdf0e10cSrcweir 	}
504cdf0e10cSrcweir 	return bOk;
505cdf0e10cSrcweir }
506cdf0e10cSrcweir 
StepSETCLASS_impl(sal_uInt32 nOp1,bool bHandleDflt)507cdf0e10cSrcweir void SbiRuntime::StepSETCLASS_impl( sal_uInt32 nOp1, bool bHandleDflt )
508cdf0e10cSrcweir {
509cdf0e10cSrcweir 	SbxVariableRef refVal = PopVar();
510cdf0e10cSrcweir 	SbxVariableRef refVar = PopVar();
511cdf0e10cSrcweir 	String aClass( pImg->GetString( static_cast<short>( nOp1 ) ) );
512cdf0e10cSrcweir 
513cdf0e10cSrcweir 	bool bOk = checkClass_Impl( refVal, aClass, true );
514cdf0e10cSrcweir 	if( bOk )
515cdf0e10cSrcweir 		StepSET_Impl( refVal, refVar, bHandleDflt ); // don't do handle dflt prop for a "proper" set
516cdf0e10cSrcweir }
517cdf0e10cSrcweir 
StepVBASETCLASS(sal_uInt32 nOp1)518cdf0e10cSrcweir void SbiRuntime::StepVBASETCLASS( sal_uInt32 nOp1 )
519cdf0e10cSrcweir {
520cdf0e10cSrcweir 	StepSETCLASS_impl( nOp1, false );
521cdf0e10cSrcweir }
522cdf0e10cSrcweir 
StepSETCLASS(sal_uInt32 nOp1)523cdf0e10cSrcweir void SbiRuntime::StepSETCLASS( sal_uInt32 nOp1 )
524cdf0e10cSrcweir {
525cdf0e10cSrcweir 	StepSETCLASS_impl( nOp1, true );
526cdf0e10cSrcweir }
527cdf0e10cSrcweir 
StepTESTCLASS(sal_uInt32 nOp1)528cdf0e10cSrcweir void SbiRuntime::StepTESTCLASS( sal_uInt32 nOp1 )
529cdf0e10cSrcweir {
530cdf0e10cSrcweir 	SbxVariableRef xObjVal = PopVar();
531cdf0e10cSrcweir 	String aClass( pImg->GetString( static_cast<short>( nOp1 ) ) );
532cdf0e10cSrcweir 	bool bDefault = !bVBAEnabled;
533cdf0e10cSrcweir 	bool bOk = checkClass_Impl( xObjVal, aClass, false, bDefault );
534cdf0e10cSrcweir 
535cdf0e10cSrcweir 	SbxVariable* pRet = new SbxVariable;
536cdf0e10cSrcweir 	pRet->PutBool( bOk );
537cdf0e10cSrcweir 	PushVar( pRet );
538cdf0e10cSrcweir }
539cdf0e10cSrcweir 
540cdf0e10cSrcweir // Library fuer anschliessenden Declare-Call definieren
541cdf0e10cSrcweir 
StepLIB(sal_uInt32 nOp1)542cdf0e10cSrcweir void SbiRuntime::StepLIB( sal_uInt32 nOp1 )
543cdf0e10cSrcweir {
544cdf0e10cSrcweir 	aLibName = pImg->GetString( static_cast<short>( nOp1 ) );
545cdf0e10cSrcweir }
546cdf0e10cSrcweir 
547cdf0e10cSrcweir // TOS wird um BASE erhoeht, BASE davor gepusht (+BASE)
548cdf0e10cSrcweir // Dieser Opcode wird vor DIM/REDIM-Anweisungen gepusht,
549cdf0e10cSrcweir // wenn nur ein Index angegeben wurde.
550cdf0e10cSrcweir 
StepBASED(sal_uInt32 nOp1)551cdf0e10cSrcweir void SbiRuntime::StepBASED( sal_uInt32 nOp1 )
552cdf0e10cSrcweir {
553cdf0e10cSrcweir 	SbxVariable* p1 = new SbxVariable;
554cdf0e10cSrcweir 	SbxVariableRef x2 = PopVar();
555cdf0e10cSrcweir 
556cdf0e10cSrcweir 	// #109275 Check compatiblity mode
557cdf0e10cSrcweir 	bool bCompatible = ((nOp1 & 0x8000) != 0);
558cdf0e10cSrcweir 	sal_uInt16 uBase = static_cast<sal_uInt16>(nOp1 & 1);		// Can only be 0 or 1
559cdf0e10cSrcweir 	p1->PutInteger( uBase );
560cdf0e10cSrcweir 	if( !bCompatible )
561cdf0e10cSrcweir 		x2->Compute( SbxPLUS, *p1 );
562cdf0e10cSrcweir 	PushVar( x2 );	// erst die Expr
563cdf0e10cSrcweir 	PushVar( p1 );	// dann die Base
564cdf0e10cSrcweir }
565cdf0e10cSrcweir 
566cdf0e10cSrcweir 
567cdf0e10cSrcweir 
568cdf0e10cSrcweir 
569cdf0e10cSrcweir 
570