xref: /aoo42x/main/basic/source/sbx/sbxexec.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_basic.hxx"
30*cdf0e10cSrcweir #include <tools/errcode.hxx>
31*cdf0e10cSrcweir #ifndef _APP_HXX //autogen
32*cdf0e10cSrcweir #include <vcl/svapp.hxx>
33*cdf0e10cSrcweir #endif
34*cdf0e10cSrcweir #include <basic/sbx.hxx>
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir class SbxSimpleCharClass
38*cdf0e10cSrcweir {
39*cdf0e10cSrcweir public:
40*cdf0e10cSrcweir 	sal_Bool isAlpha( sal_Unicode c ) const
41*cdf0e10cSrcweir 	{
42*cdf0e10cSrcweir 		sal_Bool bRet = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
43*cdf0e10cSrcweir 		return bRet;
44*cdf0e10cSrcweir 	}
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir 	sal_Bool isDigit( sal_Unicode c ) const
47*cdf0e10cSrcweir 	{
48*cdf0e10cSrcweir 		sal_Bool bRet = (c >= '0' && c <= '9');
49*cdf0e10cSrcweir 		return bRet;
50*cdf0e10cSrcweir 	}
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir 	sal_Bool isAlphaNumeric( sal_Unicode c ) const
53*cdf0e10cSrcweir 	{
54*cdf0e10cSrcweir 		sal_Bool bRet = isDigit( c ) || isAlpha( c );
55*cdf0e10cSrcweir 		return bRet;
56*cdf0e10cSrcweir 	}
57*cdf0e10cSrcweir };
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir static SbxVariable* Element
61*cdf0e10cSrcweir 	( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf,
62*cdf0e10cSrcweir 	  SbxClassType, const SbxSimpleCharClass& rCharClass );
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir static const xub_Unicode* SkipWhitespace( const xub_Unicode* p )
65*cdf0e10cSrcweir {
66*cdf0e10cSrcweir 	while( *p && ( *p == ' ' || *p == '\t' ) )
67*cdf0e10cSrcweir 		p++;
68*cdf0e10cSrcweir 	return p;
69*cdf0e10cSrcweir }
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir // Scannen eines Symbol. Das Symbol wird in rSym eingetragen, der Returnwert
72*cdf0e10cSrcweir // ist die neue Scanposition. Bei Fehlern ist das Symbol leer.
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir static const xub_Unicode* Symbol( const xub_Unicode* p, XubString& rSym, const SbxSimpleCharClass& rCharClass )
75*cdf0e10cSrcweir {
76*cdf0e10cSrcweir 	sal_uInt16 nLen = 0;
77*cdf0e10cSrcweir 	// Haben wir ein Sondersymbol?
78*cdf0e10cSrcweir 	if( *p == '[' )
79*cdf0e10cSrcweir 	{
80*cdf0e10cSrcweir 		rSym = ++p;
81*cdf0e10cSrcweir 		while( *p && *p != ']' )
82*cdf0e10cSrcweir 			p++, nLen++;
83*cdf0e10cSrcweir 		p++;
84*cdf0e10cSrcweir 	}
85*cdf0e10cSrcweir 	else
86*cdf0e10cSrcweir 	{
87*cdf0e10cSrcweir 		// Ein Symbol muss mit einem Buchstaben oder einem Underline beginnen
88*cdf0e10cSrcweir 		if( !rCharClass.isAlpha( *p ) && *p != '_' )
89*cdf0e10cSrcweir 			SbxBase::SetError( SbxERR_SYNTAX );
90*cdf0e10cSrcweir 		else
91*cdf0e10cSrcweir 		{
92*cdf0e10cSrcweir 			rSym = p;
93*cdf0e10cSrcweir 			// Dann darf es Buchstaben, Zahlen oder Underlines enthalten
94*cdf0e10cSrcweir 			while( *p && (rCharClass.isAlphaNumeric( *p ) || *p == '_') )
95*cdf0e10cSrcweir 				p++, nLen++;
96*cdf0e10cSrcweir 			// BASIC-Standard-Suffixe werden ignoriert
97*cdf0e10cSrcweir 			if( *p && (*p == '%' || *p == '&' || *p == '!' || *p == '#' || *p == '$' ) )
98*cdf0e10cSrcweir 				p++;
99*cdf0e10cSrcweir 		}
100*cdf0e10cSrcweir 	}
101*cdf0e10cSrcweir 	rSym.Erase( nLen );
102*cdf0e10cSrcweir 	return p;
103*cdf0e10cSrcweir }
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir // Qualifizierter Name. Element.Element....
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir static SbxVariable* QualifiedName
108*cdf0e10cSrcweir 	( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf, SbxClassType t )
109*cdf0e10cSrcweir {
110*cdf0e10cSrcweir 	static SbxSimpleCharClass aCharClass;
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir 	SbxVariableRef refVar;
113*cdf0e10cSrcweir 	const xub_Unicode* p = SkipWhitespace( *ppBuf );
114*cdf0e10cSrcweir 	if( aCharClass.isAlpha( *p ) || *p == '_' || *p == '[' )
115*cdf0e10cSrcweir 	{
116*cdf0e10cSrcweir 		// Element einlesen
117*cdf0e10cSrcweir 		refVar = Element( pObj, pGbl, &p, t, aCharClass );
118*cdf0e10cSrcweir 		while( refVar.Is() && (*p == '.' || *p == '!') )
119*cdf0e10cSrcweir 		{
120*cdf0e10cSrcweir 			// Es folgt noch ein Objektelement. Das aktuelle Element
121*cdf0e10cSrcweir 			// muss also ein SBX-Objekt sein oder liefern!
122*cdf0e10cSrcweir 			pObj = PTR_CAST(SbxObject,(SbxVariable*) refVar);
123*cdf0e10cSrcweir 			if( !pObj )
124*cdf0e10cSrcweir 				// Dann muss es ein Objekt liefern
125*cdf0e10cSrcweir 				pObj = PTR_CAST(SbxObject,refVar->GetObject());
126*cdf0e10cSrcweir 			refVar.Clear();
127*cdf0e10cSrcweir 			if( !pObj )
128*cdf0e10cSrcweir 				break;
129*cdf0e10cSrcweir 			p++;
130*cdf0e10cSrcweir 			// Und das naechste Element bitte
131*cdf0e10cSrcweir 			refVar = Element( pObj, pGbl, &p, t, aCharClass );
132*cdf0e10cSrcweir 		}
133*cdf0e10cSrcweir 	}
134*cdf0e10cSrcweir 	else
135*cdf0e10cSrcweir 		SbxBase::SetError( SbxERR_SYNTAX );
136*cdf0e10cSrcweir 	*ppBuf = p;
137*cdf0e10cSrcweir 	if( refVar.Is() )
138*cdf0e10cSrcweir 		refVar->AddRef();
139*cdf0e10cSrcweir 	return refVar;
140*cdf0e10cSrcweir }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir // Einlesen eines Operanden. Dies kann eine Zahl, ein String oder
143*cdf0e10cSrcweir // eine Funktion (mit optionalen Parametern) sein.
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir static SbxVariable* Operand
146*cdf0e10cSrcweir 	( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf, sal_Bool bVar )
147*cdf0e10cSrcweir {
148*cdf0e10cSrcweir 	static SbxSimpleCharClass aCharClass;
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir 	SbxVariableRef refVar( new SbxVariable );
151*cdf0e10cSrcweir 	const xub_Unicode* p = SkipWhitespace( *ppBuf );
152*cdf0e10cSrcweir 	if( !bVar && ( aCharClass.isDigit( *p )
153*cdf0e10cSrcweir 	 || ( *p == '.' && aCharClass.isDigit( *( p+1 ) ) )
154*cdf0e10cSrcweir 	 || *p == '-'
155*cdf0e10cSrcweir 	 || *p == '&' ) )
156*cdf0e10cSrcweir 	{
157*cdf0e10cSrcweir 		// Eine Zahl kann direkt eingescant werden!
158*cdf0e10cSrcweir 		sal_uInt16 nLen;
159*cdf0e10cSrcweir 		if( !refVar->Scan( XubString( p ), &nLen ) )
160*cdf0e10cSrcweir 			refVar.Clear();
161*cdf0e10cSrcweir 		else
162*cdf0e10cSrcweir 			p += nLen;
163*cdf0e10cSrcweir 	}
164*cdf0e10cSrcweir 	else if( !bVar && *p == '"' )
165*cdf0e10cSrcweir 	{
166*cdf0e10cSrcweir 		// Ein String
167*cdf0e10cSrcweir 		XubString aString;
168*cdf0e10cSrcweir 		p++;
169*cdf0e10cSrcweir 		for( ;; )
170*cdf0e10cSrcweir 		{
171*cdf0e10cSrcweir 			// Das ist wohl ein Fehler
172*cdf0e10cSrcweir 			if( !*p )
173*cdf0e10cSrcweir 				return NULL;
174*cdf0e10cSrcweir 			// Doppelte Quotes sind OK
175*cdf0e10cSrcweir 			if( *p == '"' )
176*cdf0e10cSrcweir 				if( *++p != '"' )
177*cdf0e10cSrcweir 					break;
178*cdf0e10cSrcweir 			aString += *p++;
179*cdf0e10cSrcweir 		}
180*cdf0e10cSrcweir 		refVar->PutString( aString );
181*cdf0e10cSrcweir 	}
182*cdf0e10cSrcweir 	else
183*cdf0e10cSrcweir 		refVar = QualifiedName( pObj, pGbl, &p, SbxCLASS_DONTCARE );
184*cdf0e10cSrcweir 	*ppBuf = p;
185*cdf0e10cSrcweir 	if( refVar.Is() )
186*cdf0e10cSrcweir 		refVar->AddRef();
187*cdf0e10cSrcweir 	return refVar;
188*cdf0e10cSrcweir }
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir // Einlesen einer einfachen Term. Die Operatoren +, -, * und /
191*cdf0e10cSrcweir // werden unterstuetzt.
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir static SbxVariable* MulDiv( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf )
194*cdf0e10cSrcweir {
195*cdf0e10cSrcweir 	const xub_Unicode* p = *ppBuf;
196*cdf0e10cSrcweir 	SbxVariableRef refVar( Operand( pObj, pGbl, &p, sal_False ) );
197*cdf0e10cSrcweir 	p = SkipWhitespace( p );
198*cdf0e10cSrcweir 	while( refVar.Is() && ( *p == '*' || *p == '/' ) )
199*cdf0e10cSrcweir 	{
200*cdf0e10cSrcweir 		xub_Unicode cOp = *p++;
201*cdf0e10cSrcweir 		SbxVariableRef refVar2( Operand( pObj, pGbl, &p, sal_False ) );
202*cdf0e10cSrcweir 		if( refVar2.Is() )
203*cdf0e10cSrcweir 		{
204*cdf0e10cSrcweir 			// temporaere Variable!
205*cdf0e10cSrcweir 			SbxVariable* pVar = refVar;
206*cdf0e10cSrcweir 			pVar = new SbxVariable( *pVar );
207*cdf0e10cSrcweir 			refVar = pVar;
208*cdf0e10cSrcweir 			if( cOp == '*' )
209*cdf0e10cSrcweir 				*refVar *= *refVar2;
210*cdf0e10cSrcweir 			else
211*cdf0e10cSrcweir 				*refVar /= *refVar2;
212*cdf0e10cSrcweir 		}
213*cdf0e10cSrcweir 		else
214*cdf0e10cSrcweir 		{
215*cdf0e10cSrcweir 			refVar.Clear();
216*cdf0e10cSrcweir 			break;
217*cdf0e10cSrcweir 		}
218*cdf0e10cSrcweir 	}
219*cdf0e10cSrcweir 	*ppBuf = p;
220*cdf0e10cSrcweir 	if( refVar.Is() )
221*cdf0e10cSrcweir 		refVar->AddRef();
222*cdf0e10cSrcweir 	return refVar;
223*cdf0e10cSrcweir }
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir static SbxVariable* PlusMinus( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf )
226*cdf0e10cSrcweir {
227*cdf0e10cSrcweir 	const xub_Unicode* p = *ppBuf;
228*cdf0e10cSrcweir 	SbxVariableRef refVar( MulDiv( pObj, pGbl, &p ) );
229*cdf0e10cSrcweir 	p = SkipWhitespace( p );
230*cdf0e10cSrcweir 	while( refVar.Is() && ( *p == '+' || *p == '-' ) )
231*cdf0e10cSrcweir 	{
232*cdf0e10cSrcweir 		xub_Unicode cOp = *p++;
233*cdf0e10cSrcweir 		SbxVariableRef refVar2( MulDiv( pObj, pGbl, &p ) );
234*cdf0e10cSrcweir 		if( refVar2.Is() )
235*cdf0e10cSrcweir 		{
236*cdf0e10cSrcweir 			// temporaere Variable!
237*cdf0e10cSrcweir 			SbxVariable* pVar = refVar;
238*cdf0e10cSrcweir 			pVar = new SbxVariable( *pVar );
239*cdf0e10cSrcweir 			refVar = pVar;
240*cdf0e10cSrcweir 			if( cOp == '+' )
241*cdf0e10cSrcweir 				*refVar += *refVar2;
242*cdf0e10cSrcweir 			else
243*cdf0e10cSrcweir 				*refVar -= *refVar2;
244*cdf0e10cSrcweir 		}
245*cdf0e10cSrcweir 		else
246*cdf0e10cSrcweir 		{
247*cdf0e10cSrcweir 			refVar.Clear();
248*cdf0e10cSrcweir 			break;
249*cdf0e10cSrcweir 		}
250*cdf0e10cSrcweir 	}
251*cdf0e10cSrcweir 	*ppBuf = p;
252*cdf0e10cSrcweir 	if( refVar.Is() )
253*cdf0e10cSrcweir 		refVar->AddRef();
254*cdf0e10cSrcweir 	return refVar;
255*cdf0e10cSrcweir }
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir static SbxVariable* Assign( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf )
258*cdf0e10cSrcweir {
259*cdf0e10cSrcweir 	const xub_Unicode* p = *ppBuf;
260*cdf0e10cSrcweir 	SbxVariableRef refVar( Operand( pObj, pGbl, &p, sal_True ) );
261*cdf0e10cSrcweir 	p = SkipWhitespace( p );
262*cdf0e10cSrcweir 	if( refVar.Is() )
263*cdf0e10cSrcweir 	{
264*cdf0e10cSrcweir 		if( *p == '=' )
265*cdf0e10cSrcweir 		{
266*cdf0e10cSrcweir 			// Nur auf Props zuweisen!
267*cdf0e10cSrcweir 			if( refVar->GetClass() != SbxCLASS_PROPERTY )
268*cdf0e10cSrcweir 			{
269*cdf0e10cSrcweir 				SbxBase::SetError( SbxERR_BAD_ACTION );
270*cdf0e10cSrcweir 				refVar.Clear();
271*cdf0e10cSrcweir 			}
272*cdf0e10cSrcweir 			else
273*cdf0e10cSrcweir 			{
274*cdf0e10cSrcweir 				p++;
275*cdf0e10cSrcweir 				SbxVariableRef refVar2( PlusMinus( pObj, pGbl, &p ) );
276*cdf0e10cSrcweir 				if( refVar2.Is() )
277*cdf0e10cSrcweir 				{
278*cdf0e10cSrcweir 					SbxVariable* pVar = refVar;
279*cdf0e10cSrcweir 					SbxVariable* pVar2 = refVar2;
280*cdf0e10cSrcweir 					*pVar = *pVar2;
281*cdf0e10cSrcweir 					pVar->SetParameters( NULL );
282*cdf0e10cSrcweir 				}
283*cdf0e10cSrcweir 			}
284*cdf0e10cSrcweir 		}
285*cdf0e10cSrcweir 		else
286*cdf0e10cSrcweir 			// Einfacher Aufruf: einmal aktivieren
287*cdf0e10cSrcweir 			refVar->Broadcast( SBX_HINT_DATAWANTED );
288*cdf0e10cSrcweir 	}
289*cdf0e10cSrcweir 	*ppBuf = p;
290*cdf0e10cSrcweir 	if( refVar.Is() )
291*cdf0e10cSrcweir 		refVar->AddRef();
292*cdf0e10cSrcweir 	return refVar;
293*cdf0e10cSrcweir }
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir // Einlesen eines Elements. Dies ist ein Symbol, optional gefolgt
296*cdf0e10cSrcweir // von einer Parameterliste. Das Symbol wird im angegebenen Objekt
297*cdf0e10cSrcweir // gesucht und die Parameterliste wird ggf. angefuegt.
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir static SbxVariable* Element
300*cdf0e10cSrcweir 	( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf,
301*cdf0e10cSrcweir 	  SbxClassType t, const SbxSimpleCharClass& rCharClass )
302*cdf0e10cSrcweir {
303*cdf0e10cSrcweir 	XubString aSym;
304*cdf0e10cSrcweir 	const xub_Unicode* p = Symbol( *ppBuf, aSym, rCharClass );
305*cdf0e10cSrcweir 	SbxVariableRef refVar;
306*cdf0e10cSrcweir 	if( aSym.Len() )
307*cdf0e10cSrcweir 	{
308*cdf0e10cSrcweir 		sal_uInt16 nOld = pObj->GetFlags();
309*cdf0e10cSrcweir 		if( pObj == pGbl )
310*cdf0e10cSrcweir 			pObj->SetFlag( SBX_GBLSEARCH );
311*cdf0e10cSrcweir 		refVar = pObj->Find( aSym, t );
312*cdf0e10cSrcweir 		pObj->SetFlags( nOld );
313*cdf0e10cSrcweir 		if( refVar.Is() )
314*cdf0e10cSrcweir 		{
315*cdf0e10cSrcweir 			refVar->SetParameters( NULL );
316*cdf0e10cSrcweir 			// folgen noch Parameter?
317*cdf0e10cSrcweir 			p = SkipWhitespace( p );
318*cdf0e10cSrcweir 			if( *p == '(' )
319*cdf0e10cSrcweir 			{
320*cdf0e10cSrcweir 				p++;
321*cdf0e10cSrcweir 				SbxArrayRef refPar = new SbxArray;
322*cdf0e10cSrcweir 				sal_uInt16 nArg = 0;
323*cdf0e10cSrcweir 				// Wird sind mal relaxed und akzeptieren auch
324*cdf0e10cSrcweir 				// das Zeilen- oder Komandoende als Begrenzer
325*cdf0e10cSrcweir 				// Parameter immer global suchen!
326*cdf0e10cSrcweir 				while( *p && *p != ')' && *p != ']' )
327*cdf0e10cSrcweir 				{
328*cdf0e10cSrcweir 					SbxVariableRef refArg = PlusMinus( pGbl, pGbl, &p );
329*cdf0e10cSrcweir 					if( !refArg )
330*cdf0e10cSrcweir 					{
331*cdf0e10cSrcweir 						// Fehler beim Parsing
332*cdf0e10cSrcweir 						refVar.Clear(); break;
333*cdf0e10cSrcweir 					}
334*cdf0e10cSrcweir 					else
335*cdf0e10cSrcweir 					{
336*cdf0e10cSrcweir 						// Man kopiere den Parameter, damit
337*cdf0e10cSrcweir 						// man den aktuellen Zustand hat (loest auch
338*cdf0e10cSrcweir 						// den Aufruf per Zugriff aus)
339*cdf0e10cSrcweir 						SbxVariable* pArg = refArg;
340*cdf0e10cSrcweir 						refPar->Put( new SbxVariable( *pArg ), ++nArg );
341*cdf0e10cSrcweir 					}
342*cdf0e10cSrcweir 					p = SkipWhitespace( p );
343*cdf0e10cSrcweir 					if( *p == ',' )
344*cdf0e10cSrcweir 						p++;
345*cdf0e10cSrcweir 				}
346*cdf0e10cSrcweir 				if( *p == ')' )
347*cdf0e10cSrcweir 					p++;
348*cdf0e10cSrcweir 				if( refVar.Is() )
349*cdf0e10cSrcweir 					refVar->SetParameters( refPar );
350*cdf0e10cSrcweir 			}
351*cdf0e10cSrcweir 		}
352*cdf0e10cSrcweir 		else
353*cdf0e10cSrcweir 			SbxBase::SetError( SbxERR_NO_METHOD );
354*cdf0e10cSrcweir 	}
355*cdf0e10cSrcweir 	*ppBuf = p;
356*cdf0e10cSrcweir 	if( refVar.Is() )
357*cdf0e10cSrcweir 		refVar->AddRef();
358*cdf0e10cSrcweir 	return refVar;
359*cdf0e10cSrcweir }
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir // Hauptroutine
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir SbxVariable* SbxObject::Execute( const XubString& rTxt )
364*cdf0e10cSrcweir {
365*cdf0e10cSrcweir 	SbxVariable* pVar = NULL;
366*cdf0e10cSrcweir 	const xub_Unicode* p = rTxt.GetBuffer();
367*cdf0e10cSrcweir 	for( ;; )
368*cdf0e10cSrcweir 	{
369*cdf0e10cSrcweir 		p = SkipWhitespace( p );
370*cdf0e10cSrcweir 		if( !*p )
371*cdf0e10cSrcweir 			break;
372*cdf0e10cSrcweir 		if( *p++ != '[' )
373*cdf0e10cSrcweir 		{
374*cdf0e10cSrcweir 			SetError( SbxERR_SYNTAX ); break;
375*cdf0e10cSrcweir 		}
376*cdf0e10cSrcweir 		pVar = Assign( this, this, &p );
377*cdf0e10cSrcweir 		if( !pVar )
378*cdf0e10cSrcweir 			break;
379*cdf0e10cSrcweir 		p = SkipWhitespace( p );
380*cdf0e10cSrcweir 		if( *p++ != ']' )
381*cdf0e10cSrcweir 		{
382*cdf0e10cSrcweir 			SetError( SbxERR_SYNTAX ); break;
383*cdf0e10cSrcweir 		}
384*cdf0e10cSrcweir 	}
385*cdf0e10cSrcweir 	return pVar;
386*cdf0e10cSrcweir }
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir SbxVariable* SbxObject::FindQualified( const XubString& rName, SbxClassType t )
389*cdf0e10cSrcweir {
390*cdf0e10cSrcweir 	SbxVariable* pVar = NULL;
391*cdf0e10cSrcweir 	const xub_Unicode* p = rName.GetBuffer();
392*cdf0e10cSrcweir 	p = SkipWhitespace( p );
393*cdf0e10cSrcweir 	if( !*p )
394*cdf0e10cSrcweir 		return NULL;;
395*cdf0e10cSrcweir 	pVar = QualifiedName( this, this, &p, t );
396*cdf0e10cSrcweir 	p = SkipWhitespace( p );
397*cdf0e10cSrcweir 	if( *p )
398*cdf0e10cSrcweir 		SetError( SbxERR_SYNTAX );
399*cdf0e10cSrcweir 	return pVar;
400*cdf0e10cSrcweir }
401*cdf0e10cSrcweir 
402