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