xref: /trunk/main/basic/source/sbx/sbxexec.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1e1f63238SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3e1f63238SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4e1f63238SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5e1f63238SAndrew Rist  * distributed with this work for additional information
6e1f63238SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7e1f63238SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8e1f63238SAndrew Rist  * "License"); you may not use this file except in compliance
9e1f63238SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13e1f63238SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14e1f63238SAndrew Rist  * software distributed under the License is distributed on an
15e1f63238SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16e1f63238SAndrew Rist  * KIND, either express or implied.  See the License for the
17e1f63238SAndrew Rist  * specific language governing permissions and limitations
18e1f63238SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20e1f63238SAndrew Rist  *************************************************************/
21e1f63238SAndrew Rist 
22e1f63238SAndrew 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 )
390*be099857Smseidel         return NULL;
391cdf0e10cSrcweir     pVar = QualifiedName( this, this, &p, t );
392cdf0e10cSrcweir     p = SkipWhitespace( p );
393cdf0e10cSrcweir     if( *p )
394cdf0e10cSrcweir         SetError( SbxERR_SYNTAX );
395cdf0e10cSrcweir     return pVar;
396cdf0e10cSrcweir }
397