xref: /aoo41x/main/idl/source/cmptools/lex.cxx (revision cdf0e10c)
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