xref: /trunk/main/idl/source/cmptools/lex.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_idl.hxx"
30 
31 
32 #include <ctype.h>
33 #include <stdio.h>
34 
35 #include <char.hxx>
36 #include <hash.hxx>
37 #include <lex.hxx>
38 #include <globals.hxx>
39 #include <tools/bigint.hxx>
40 
41 /****************** SvToken **********************************************/
42 /*************************************************************************
43 |*
44 |*    SvToken::Print()
45 |*
46 |*    Beschreibung
47 |*
48 *************************************************************************/
49 ByteString SvToken::GetTokenAsString() const
50 {
51     ByteString aStr;
52     switch( nType )
53     {
54         case SVTOKEN_EMPTY:
55             break;
56         case SVTOKEN_COMMENT:
57             aStr = aString;
58             break;
59         case SVTOKEN_INTEGER:
60             aStr = ByteString::CreateFromInt64(nLong);
61             break;
62         case SVTOKEN_STRING:
63             aStr = aString;
64             break;
65         case SVTOKEN_BOOL:
66             aStr = bBool ? "TRUE" : "FALSE";
67             break;
68         case SVTOKEN_IDENTIFIER:
69             aStr = aString;
70             break;
71         case SVTOKEN_CHAR:
72             aStr = cChar;
73             break;
74         case SVTOKEN_RTTIBASE:
75             aStr = "RTTIBASE";//(ULONG)pComplexObj;
76             break;
77         case SVTOKEN_EOF:
78         case SVTOKEN_HASHID:
79             break;
80     }
81 
82     return aStr;
83 }
84 
85 /*************************************************************************
86 |*
87 |*    SvToken::SvToken()
88 |*
89 |*    Beschreibung
90 |*
91 *************************************************************************/
92 SvToken::SvToken( const SvToken & rObj )
93 {
94     nLine = rObj.nLine;
95     nColumn = rObj.nColumn;
96     nType = rObj.nType;
97     aString = rObj.aString;
98 /*
99     if( SVTOKEN_RTTIBASE = nType )
100     {
101         pComplexObj = rObj.pComplexObj;
102         pComplexObj->AddRef();
103     }
104     else
105 */
106         nLong = rObj.nLong;
107 }
108 
109 /*************************************************************************
110 |*
111 |*    SvToken::operator = ()
112 |*
113 |*    Beschreibung
114 |*
115 *************************************************************************/
116 SvToken & SvToken::operator = ( const SvToken & rObj )
117 {
118     if( this != &rObj )
119     {
120 /*
121         if( SVTOKEN_RTTIBASE = nType )
122             pComplexObj->ReleaseRef();
123 */
124         nLine = rObj.nLine;
125         nColumn = rObj.nColumn;
126         nType = rObj.nType;
127         aString = rObj.aString;
128 /*
129         if( SVTOKEN_RTTIBASE = nType )
130         {
131             pComplexObj = rObj.pComplexObj;
132             pComplexObj->AddRef();
133         }
134         else
135 */
136             nLong = rObj.nLong;
137     }
138     return *this;
139 }
140 
141 /****************** SvTokenStream ****************************************/
142 /*************************************************************************
143 |*    SvTokenStream::InitCtor()
144 |*
145 |*    Beschreibung
146 *************************************************************************/
147 void SvTokenStream::InitCtor()
148 {
149     SetCharSet( gsl_getSystemTextEncoding() );
150     aStrTrue    = "TRUE";
151     aStrFalse   = "FALSE";
152     nLine       = nColumn = 0;
153     nBufPos     = 0;
154     nTabSize    = 4;
155     pCurToken   = NULL;
156     nMaxPos     = 0;
157     c           = GetNextChar();
158     FillTokenList();
159 }
160 
161 /*************************************************************************
162 |*    SvTokenStream::SvTokenStream()
163 |*
164 |*    Beschreibung
165 *************************************************************************/
166 SvTokenStream::SvTokenStream( const String & rFileName )
167     : pInStream( new SvFileStream( rFileName, STREAM_STD_READ | STREAM_NOCREATE ) )
168     , rInStream( *pInStream )
169     , aFileName( rFileName )
170     , aTokList( 0x8000, 0x8000 )
171 {
172     InitCtor();
173 }
174 
175 /*************************************************************************
176 |*    SvTokenStream::SvTokenStream()
177 |*
178 |*    Beschreibung
179 *************************************************************************/
180 SvTokenStream::SvTokenStream( SvStream & rStream, const String & rFileName )
181     : pInStream( NULL )
182     , rInStream( rStream )
183     , aFileName( rFileName )
184     , aTokList( 0x8000, 0x8000 )
185 {
186     InitCtor();
187 }
188 
189 /*************************************************************************
190 |*    SvTokenStream::~SvTokenStream()
191 |*
192 |*    Beschreibung
193 *************************************************************************/
194 SvTokenStream::~SvTokenStream()
195 {
196     delete pInStream;
197     SvToken * pTok = aTokList.Last();
198     while( pTok )
199     {
200         delete pTok;
201         pTok = aTokList.Prev();
202     }
203 }
204 
205 /*************************************************************************
206 |*    SvTokenStream::FillTokenList()
207 |*
208 |*    Beschreibung
209 *************************************************************************/
210 void SvTokenStream::FillTokenList()
211 {
212     SvToken * pToken = new SvToken();
213     aTokList.Insert( pToken, LIST_APPEND );
214     do
215     {
216         if( !MakeToken( *pToken ) )
217         {
218             SvToken * p = aTokList.Prev();
219             *pToken = SvToken();
220             if( p )
221             {
222                 pToken->SetLine( p->GetLine() );
223                 pToken->SetColumn( p->GetColumn() );
224             }
225             break;
226         }
227         else if( pToken->IsComment() )
228             *pToken = SvToken();
229         else if( pToken->IsEof() )
230             break;
231         else
232         {
233             pToken = new SvToken();
234             aTokList.Insert( pToken, LIST_APPEND );
235         }
236     }
237     while( !pToken->IsEof() );
238     pCurToken = aTokList.First();
239 }
240 
241 /*************************************************************************
242 |*    SvTokenStrem::SetCharSet()
243 |*
244 |*    Beschreibung
245 *************************************************************************/
246 void SvTokenStream::SetCharSet( CharSet nSet )
247 {
248     nCharSet = nSet;
249 
250     pCharTab = SvChar::GetTable( nSet, gsl_getSystemTextEncoding() );
251 }
252 
253 /*************************************************************************
254 |*    SvTokeStream::GetNextChar()
255 |*
256 |*    Beschreibung
257 *************************************************************************/
258 int SvTokenStream::GetNextChar()
259 {
260     int nChar;
261     if( (int)aBufStr.Len() < nBufPos )
262     {
263         if( rInStream.ReadLine( aBufStr ) )
264         {
265             nLine++;
266             nColumn = 0;
267             nBufPos = 0;
268         }
269         else
270         {
271             aBufStr.Erase();
272             nColumn = 0;
273             nBufPos = 0;
274             return '\0';
275         }
276     }
277     nChar = aBufStr.GetChar( (sal_uInt16)nBufPos++ );
278     nColumn += nChar == '\t' ? nTabSize : 1;
279     return nChar;
280 }
281 
282 /*************************************************************************
283 |*    SvTokenStrem::GetNumber()
284 |*
285 |*    Beschreibung
286 *************************************************************************/
287 sal_uLong SvTokenStream::GetNumber()
288 {
289     sal_uLong   l = 0;
290     short   nLog = 10;
291 
292     if( '0' == c )
293     {
294         c = GetFastNextChar();
295         if( 'x' == c )
296         {
297             nLog = 16;
298             c = GetFastNextChar();
299         }
300     };
301 
302     if( nLog == 16 )
303     {
304         while( isxdigit( c ) )
305         {
306             if( isdigit( c ) )
307                 l = l * nLog + (c - '0');
308             else
309                 l = l * nLog + (toupper( c ) - 'A' + 10 );
310             c = GetFastNextChar();
311         }
312     }
313     else
314     {
315         while( isdigit( c ) || 'x' == c )
316         {
317             l = l * nLog + (c - '0');
318             c = GetFastNextChar();
319         }
320     }
321 
322     return( l );
323 }
324 
325 /*************************************************************************
326 |*    SvTokenStream::MakeToken()
327 |*
328 |*    Beschreibung
329 *************************************************************************/
330 sal_Bool SvTokenStream::MakeToken( SvToken & rToken )
331 {
332     int             c1;
333     sal_uInt16          i;
334 
335     do
336     {
337         if( 0 == c )
338             c = GetNextChar();
339         // Leerzeichen ueberlesen
340         while( isspace( c ) || 26 == c )
341         {
342             c = GetFastNextChar();
343             nColumn += c == '\t' ? nTabSize : 1;
344         }
345     }
346     while( 0 == c && !IsEof() && ( SVSTREAM_OK == rInStream.GetError() ) );
347 
348     sal_uLong nLastLine     = nLine;
349     sal_uLong nLastColumn   = nColumn;
350     // Kommentar
351     if( '/' == c )
352     {
353         // Zeit Optimierung, keine Kommentare
354         //ByteString aComment( (char)c );
355         c1 = c;
356         c = GetFastNextChar();
357         if( '/' == c )
358         {
359             while( '\0' != c )
360             {
361                 //aComment += (char)c;
362                 c = GetFastNextChar();
363             }
364             c = GetNextChar();
365             rToken.nType    = SVTOKEN_COMMENT;
366             //rToken.aString    = aComment;
367         }
368         else if( '*' == c )
369         {
370             //aComment += (char)c;
371             c = GetFastNextChar();
372             do
373             {
374                 //aComment += (char)c;
375                 while( '*' != c )
376                 {
377                     if( '\0' == c )
378                     {
379                         c = GetNextChar();
380                         if( IsEof() )
381                             return sal_False;
382                     }
383                     else
384                         c = GetFastNextChar();
385                     //aComment += (char)c;
386                 }
387                 c = GetFastNextChar();
388             }
389             while( '/' != c && !IsEof() && ( SVSTREAM_OK == rInStream.GetError() ) );
390             if( IsEof() || ( SVSTREAM_OK != rInStream.GetError() ) )
391                 return sal_False;
392             //aComment += (char)c;
393             c = GetNextChar();
394             rToken.nType = SVTOKEN_COMMENT;
395             //rToken.aString = aComment;
396             CalcColumn();
397         }
398         else
399         {
400             rToken.nType = SVTOKEN_CHAR;
401             rToken.cChar = (char)c1;
402         }
403     }
404     else if( c == '"' )
405     {
406         ByteString          aStr;
407         i = 0;
408         sal_Bool bDone = sal_False;
409         while( !bDone && !IsEof() && c )
410         {
411             c = GetFastNextChar();
412             if( '\0' == c )
413             {
414                 // Strings auch "uber das Zeilenende hinauslesen
415                 aStr += '\n';
416                 c = GetNextChar();
417                 if( IsEof() )
418                     return sal_False;
419             }
420             if( c == '"' )
421             {
422                 c = GetFastNextChar();
423                 if( c == '"' )
424                 {
425                     aStr += '"';
426                     aStr += '"';
427                 }
428                 else
429                     bDone = sal_True;
430             }
431             else if( c == '\\' )
432             {
433                 aStr += '\\';
434                 c = GetFastNextChar();
435                 if( c )
436                     aStr += (char)c;
437             }
438             else
439                 aStr += (char)c;
440         }
441         if( IsEof() || ( SVSTREAM_OK != rInStream.GetError() ) )
442             return sal_False;
443         char * pStr = (char *)aStr.GetBuffer();
444         while( *pStr )
445         {
446             *pStr = pCharTab[ (unsigned char)*pStr ];
447             pStr++;
448         };
449         rToken.nType   = SVTOKEN_STRING;
450         rToken.aString = aStr;
451     }
452     else if( isdigit( c ) )
453     {
454         rToken.nType = SVTOKEN_INTEGER;
455         rToken.nLong = GetNumber();
456 
457     }
458     else if( isalpha (c) || (c == '_') )
459     {
460         ByteString aStr;
461 
462         while( isalnum( c ) || c == '_' )
463         {
464             aStr += (char)c;
465             c = GetFastNextChar();
466         }
467         if( aStr.EqualsIgnoreCaseAscii( aStrTrue ) )
468         {
469             rToken.nType = SVTOKEN_BOOL;
470             rToken.bBool = sal_True;
471         }
472         else if( aStr.EqualsIgnoreCaseAscii( aStrFalse ) )
473         {
474             rToken.nType = SVTOKEN_BOOL;
475             rToken.bBool = sal_False;
476         }
477         else
478         {
479             sal_uInt32 nHashId;
480             if( IDLAPP->pHashTable->Test( aStr, &nHashId ) )
481                 rToken.SetHash( IDLAPP->pHashTable->Get( nHashId ) );
482             else
483             {
484                 rToken.nType   = SVTOKEN_IDENTIFIER;
485                 rToken.aString = aStr;
486             }
487         }
488     }
489     else if( IsEof() )
490     {
491         rToken.nType = SVTOKEN_EOF;
492     }
493     else
494     {
495         rToken.nType = SVTOKEN_CHAR;
496         rToken.cChar = (char)c;
497         c = GetFastNextChar();
498     }
499     rToken.SetLine( nLastLine );
500     rToken.SetColumn( nLastColumn );
501     return rInStream.GetError() == SVSTREAM_OK;
502 }
503 
504