xref: /AOO41X/main/rsc/source/parser/rsclex.cxx (revision 79aad27f7f29270c03e208e3d687e8e3850af11d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_rsc.hxx"
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <limits.h>
31 
32 #ifdef _RSCERROR_H
33 #include <rscerror.h>
34 #endif
35 #include <rschash.hxx>
36 #include <rscdb.hxx>
37 #include <rsctop.hxx>
38 #include <rsckey.hxx>
39 #include <rscpar.hxx>
40 #include <rscdef.hxx>
41 
42 #include "rsclex.hxx"
43 #include <yyrscyacc.hxx>
44 
45 #include <rtl/textcvt.h>
46 #include <rtl/textenc.h>
47 
48 using namespace rtl;
49 
putString(const char * pString)50 const char* StringContainer::putString( const char* pString )
51 {
52     OString aString( static_cast<const sal_Char*>(pString) );
53     std::pair<
54         std::hash_set< OString, OStringHash >::iterator,
55         bool > aInsert =
56         m_aStrings.insert( aString );
57 
58     return aInsert.first->getStr();
59 }
60 
61 /*************************************************************************/
62 int             c;
63 sal_Bool            bLastInclude;// War letztes Symbol INCLUDE
64 RscFileInst*    pFI;
65 RscTypCont*     pTC;
66 RscExpression * pExp;
67 struct KeyVal {
68     int     nKeyWord;
69     YYSTYPE aYYSType;
70 } aKeyVal[ 1 ];
71 sal_Bool bTargetDefined;
72 
73 StringContainer* pStringContainer = NULL;
74 
75 
76 /****************** C O D E **********************************************/
GetNumber()77 sal_uInt32 GetNumber(){
78     sal_uInt32  l = 0;
79     sal_uInt32  nLog = 10;
80 
81     if( '0' == c ){
82         c = pFI->GetFastChar();
83         if( 'x' == c ){
84             nLog = 16;
85             c = pFI->GetFastChar();
86         }
87     };
88 
89     if( nLog == 16 ){
90         while( isxdigit( c ) ){
91             if( isdigit( c ) )
92                 l = l * nLog + (c - '0');
93             else
94                 l = l * nLog + (toupper( c ) - 'A' + 10 );
95             c = pFI->GetFastChar();
96         }
97     }
98     else{
99         while( isdigit( c ) || 'x' == c ){
100             l = l * nLog + (c - '0');
101             c = pFI->GetFastChar();
102         }
103     }
104 
105     while( c=='U' || c=='u' || c=='l' || c=='L' ) //Wg. Unsigned Longs
106         c = pFI->GetFastChar();
107 
108     if( l > 0x7fffffff ) //Oberstes bit gegebenenfalls abschneiden;
109         l &= 0x7fffffff;
110 
111     return( l );
112 }
113 
MakeToken(YYSTYPE * pTokenVal)114 int MakeToken( YYSTYPE * pTokenVal ){
115     int             c1;
116     char *          pStr;
117 
118     while( sal_True ){  // Kommentare und Leerzeichen ueberlesen
119         while( isspace( c ) )
120             c = pFI->GetFastChar();
121         if( '/' == c ){
122             c1 = c;
123             c = pFI->GetFastChar();
124             if( '/' == c ){
125                 while( '\n' != c && !pFI->IsEof() )
126                     c = pFI->GetFastChar();
127                 c = pFI->GetFastChar();
128             }
129             else if( '*' == c ){
130                 c = pFI->GetFastChar();
131                 do {
132                     while( '*' != c && !pFI->IsEof() )
133                         c = pFI->GetFastChar();
134                     c = pFI->GetFastChar();
135                 } while( '/' != c && !pFI->IsEof() );
136                 c = pFI->GetFastChar();
137             }
138             else
139                 return( c1 );
140         }
141         else
142             break;
143     };
144 
145     if( c == pFI->IsEof() ){
146         return( 0 );
147     }
148 
149     if( bLastInclude ){
150         bLastInclude = sal_False; //Zuruecksetzten
151         if( '<' == c ){
152             OStringBuffer aBuf( 256 );
153             c = pFI->GetFastChar();
154             while( '>' != c && !pFI->IsEof() )
155             {
156                 aBuf.append( sal_Char(c) );
157                 c = pFI->GetFastChar();
158             };
159             c = pFI->GetFastChar();
160             pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
161             return( INCLUDE_STRING );
162         };
163     }
164 
165     if( c == '"' )
166     {
167         OStringBuffer aBuf( 256 );
168         sal_Bool bDone = sal_False;
169         while( !bDone && !pFI->IsEof() && c )
170         {
171             c = pFI->GetFastChar();
172             if( c == '"' )
173             {
174                 do
175                 {
176                     c = pFI->GetFastChar();
177                 }
178                 while(  c == ' ' || c == '\t' );
179                 if( c == '"' )
180                 {
181                     // this is a continued string
182                     // note: multiline string continuations are handled by the parser
183                     // see rscyacc.y
184                 }
185                 else
186                     bDone = sal_True;
187             }
188             else if( c == '\\' )
189             {
190                 aBuf.append( '\\' );
191                 c = pFI->GetFastChar();
192                 if( c )
193                     aBuf.append( sal_Char(c) );
194             }
195             else
196                 aBuf.append( sal_Char(c) );
197         }
198         pStr = pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
199         return( STRING );
200     }
201     if (isdigit (c)){
202         pTokenVal->value = GetNumber();
203         return( NUMBER );
204     }
205 
206     if( isalpha (c) || (c == '_') ){
207         Atom        nHashId;
208         OStringBuffer aBuf( 256 );
209 
210         while( isalnum (c) || (c == '_') || (c == '-') )
211         {
212             aBuf.append( sal_Char(c) );
213             c = pFI->GetFastChar();
214         }
215 
216         nHashId = pHS->getID( aBuf.getStr(), true );
217         if( InvalidAtom != nHashId )
218         {
219             KEY_STRUCT  aKey;
220 
221             // Suche nach dem Schluesselwort
222             if( pTC->aNmTb.Get( nHashId, &aKey ) )
223             {
224 
225                 // Schluesselwort gefunden
226                 switch( aKey.nTyp )
227                 {
228                     case CLASSNAME:
229                         pTokenVal->pClass = (RscTop *)aKey.yylval;
230                         break;
231                     case VARNAME:
232                         pTokenVal->varid = aKey.nName;
233                         break;
234                     case CONSTNAME:
235                         pTokenVal->constname.hashid = aKey.nName;
236                         pTokenVal->constname.nValue = aKey.yylval;
237                         break;
238                     case BOOLEAN:
239                         pTokenVal->svbool = (sal_Bool)aKey.yylval;
240                         break;
241                     case INCLUDE:
242                         bLastInclude = sal_True;
243                     default:
244                         pTokenVal->value = aKey.yylval;
245                 };
246 
247                 return( aKey.nTyp );
248             }
249             else
250             {
251                 pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
252                 return( SYMBOL );
253             }
254         }
255         else{       // Symbol
256             RscDefine  * pDef;
257 
258             pDef = pTC->aFileTab.FindDef( aBuf.getStr() );
259             if( pDef ){
260                 pTokenVal->defineele = pDef;
261 
262                 return( RSCDEFINE );
263             }
264 
265             pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
266             return( SYMBOL );
267         }
268     }
269 
270     if( c=='<' )
271     {
272         c = pFI->GetFastChar();
273         if( c=='<' )
274         {
275             c = pFI->GetFastChar();
276             return LEFTSHIFT;
277         }
278         else
279             return '<';
280     }
281 
282     if( c=='>' )
283     {
284         c = pFI->GetFastChar();
285         if( c=='>' )
286         {
287             c = pFI->GetFastChar();
288             return RIGHTSHIFT;
289         }
290         else
291             return '>';
292     }
293 
294     c1 = c;
295     c = pFI->GetFastChar();
296     return( c1 );
297 }
298 
299 #if defined( RS6000 ) || defined( HP9000 ) || defined( SCO )
yylex()300 extern "C" int yylex()
301 #else
302 int yylex()
303 #endif
304 {
305     if( bTargetDefined )
306         bTargetDefined = sal_False;
307     else
308         aKeyVal[ 0 ].nKeyWord =
309                      MakeToken( &aKeyVal[ 0 ].aYYSType );
310 
311     yylval = aKeyVal[ 0 ].aYYSType;
312     return( aKeyVal[ 0 ].nKeyWord );
313 }
314 
315 /****************** yyerror **********************************************/
316 #ifdef RS6000
yyerror(char * pMessage)317 extern "C" void yyerror( char* pMessage )
318 #elif defined HP9000 || defined SCO || defined SOLARIS
319 extern "C" void yyerror( const char* pMessage )
320 #else
321 void yyerror( char* pMessage )
322 #endif
323 {
324     pTC->pEH->Error( ERR_YACC, NULL, RscId(), pMessage );
325 }
326 
327 /****************** parser start function ********************************/
InitParser(RscFileInst * pFileInst)328 void InitParser( RscFileInst * pFileInst )
329 {
330     pTC = pFileInst->pTypCont;          // Datenkontainer setzten
331     pFI = pFileInst;
332     pStringContainer = new StringContainer();
333     pExp = NULL;                //fuer MacroParser
334     bTargetDefined = sal_False;
335 
336     // Anfangszeichen initialisieren
337     bLastInclude = sal_False;
338     c = pFI->GetFastChar();
339 }
340 
EndParser()341 void EndParser(){
342     // Stack abraeumen
343     while( ! S.IsEmpty() )
344         S.Pop();
345 
346     // free string container
347     delete pStringContainer;
348     pStringContainer = NULL;
349 
350     if( pExp )
351         delete pExp;
352     pTC      = NULL;
353     pFI      = NULL;
354     pExp     = NULL;
355 
356 }
357 
IncludeParser(RscFileInst * pFileInst)358 void IncludeParser( RscFileInst * pFileInst )
359 {
360     int           nToken;   // Wert des Tokens
361     YYSTYPE       aYYSType; // Daten des Tokens
362     RscFile     * pFName;   // Filestruktur
363     sal_uLong         lKey;     // Fileschluessel
364     RscTypCont  * pTypCon  = pFileInst->pTypCont;
365 
366     pFName = pTypCon->aFileTab.Get( pFileInst->GetFileIndex() );
367     InitParser( pFileInst );
368 
369     nToken = MakeToken( &aYYSType );
370     while( 0 != nToken && CLASSNAME != nToken ){
371         if( '#' == nToken ){
372             if( INCLUDE == (nToken = MakeToken( &aYYSType )) ){
373                 if( STRING == (nToken = MakeToken( &aYYSType )) ){
374                     lKey = pTypCon->aFileTab.NewIncFile( aYYSType.string,
375                                                          aYYSType.string );
376                     pFName->InsertDependFile( lKey, LIST_APPEND );
377                 }
378                 else if( INCLUDE_STRING == nToken ){
379                     lKey = pTypCon->aFileTab.NewIncFile( aYYSType.string,
380                                                          ByteString() );
381                     pFName->InsertDependFile( lKey, LIST_APPEND );
382                 };
383             };
384         };
385         nToken = MakeToken( &aYYSType );
386     };
387 
388     EndParser();
389 }
390 
parser(RscFileInst * pFileInst)391 ERRTYPE parser( RscFileInst * pFileInst )
392 {
393     ERRTYPE aError;
394 
395     InitParser( pFileInst );
396 
397     aError = yyparse();
398 
399     EndParser();
400 
401     // yyparser gibt 0 zurueck, wenn erfolgreich
402     if( 0 == aError )
403         aError.Clear();
404     if( pFileInst->pTypCont->pEH->nErrors )
405         aError = ERR_ERROR;
406     pFileInst->SetError( aError );
407     return( aError );
408 }
409 
MacroParser(RscFileInst & rFileInst)410 RscExpression * MacroParser( RscFileInst & rFileInst )
411 {
412     ERRTYPE       aError;
413     RscExpression * pExpression;
414 
415     InitParser( &rFileInst );
416 
417     //Ziel auf macro_expression setzen
418     aKeyVal[ 0 ].nKeyWord = MACROTARGET;
419     bTargetDefined = sal_True;
420     aError = yyparse();
421 
422     pExpression = pExp;
423     //EndParser() wuerde pExp loeschen
424     if( pExp )
425         pExp = NULL;
426 
427     EndParser();
428 
429     // yyparser gibt 0 zurueck, wenn erfolgreich
430     if( 0 == aError )
431         aError.Clear();
432     if( rFileInst.pTypCont->pEH->nErrors )
433         aError = ERR_ERROR;
434     rFileInst.SetError( aError );
435 
436     //im Fehlerfall pExpression loeschen
437     if( aError.IsError() && pExpression ){
438         delete pExpression;
439         pExpression = NULL;
440     };
441     return( pExpression );
442 }
443 
444