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