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