Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <stdlib.h>
21 : #include <stdio.h>
22 : #include <string.h>
23 : #include <ctype.h>
24 : #include <limits.h>
25 :
26 : #include <rscerror.h>
27 : #include <rschash.hxx>
28 : #include <rscdb.hxx>
29 : #include <rsctop.hxx>
30 : #include <rsckey.hxx>
31 : #include <rscpar.hxx>
32 : #include <rscdef.hxx>
33 :
34 : #include <rsclex.hxx>
35 : #include <rscyacc.hxx>
36 :
37 : #include <rtl/textcvt.h>
38 : #include <rtl/textenc.h>
39 :
40 :
41 65667 : const char* StringContainer::putString( const char* pString )
42 : {
43 65667 : OString aString( static_cast<const sal_Char*>(pString) );
44 : std::pair<
45 : std::unordered_set< OString, OStringHash >::iterator,
46 : bool > aInsert =
47 65667 : m_aStrings.insert( aString );
48 :
49 65667 : return aInsert.first->getStr();
50 : }
51 :
52 : int c;
53 : bool bLastInclude;// War letztes Symbol INCLUDE
54 : RscFileInst* pFI;
55 : RscTypCont* pTC;
56 : RscExpression * pExp;
57 : struct KeyVal
58 : {
59 : int nKeyWord;
60 : YYSTYPE aYYSType;
61 : } aKeyVal[ 1 ];
62 : bool bTargetDefined;
63 :
64 : StringContainer* pStringContainer = NULL;
65 :
66 :
67 85815 : sal_uInt32 GetNumber()
68 : {
69 85815 : sal_uInt32 l = 0;
70 85815 : sal_uInt32 nLog = 10;
71 :
72 85815 : if( '0' == c )
73 : {
74 5116 : c = pFI->GetFastChar();
75 5116 : if( 'x' == c )
76 : {
77 1548 : nLog = 16;
78 1548 : c = pFI->GetFastChar();
79 : }
80 : }
81 :
82 85815 : if( nLog == 16 )
83 : {
84 9496 : while( isxdigit( c ) )
85 : {
86 6400 : if( isdigit( c ) )
87 3502 : l = l * nLog + (c - '0');
88 : else
89 2898 : l = l * nLog + (toupper( c ) - 'A' + 10 );
90 :
91 6400 : c = pFI->GetFastChar();
92 : }
93 : }
94 : else
95 : {
96 410140 : while( isdigit( c ) || 'x' == c )
97 : {
98 241606 : l = l * nLog + (c - '0');
99 241606 : c = pFI->GetFastChar();
100 : }
101 : }
102 :
103 174002 : while( c=='U' || c=='u' || c=='l' || c=='L' ) //Wg. Unsigned Longs
104 2372 : c = pFI->GetFastChar();
105 :
106 85815 : if( l > 0x7fffffff ) //Oberstes bit gegebenenfalls abschneiden;
107 60 : l &= 0x7fffffff;
108 :
109 85815 : return l;
110 : }
111 :
112 781391 : int MakeToken( YYSTYPE * pTokenVal )
113 : {
114 : int c1;
115 :
116 : while( true ) // Kommentare und Leerzeichen ueberlesen
117 : {
118 2306349 : while( isspace( c ) )
119 743567 : c = pFI->GetFastChar();
120 :
121 781391 : if( '/' == c )
122 : {
123 0 : c1 = c;
124 0 : c = pFI->GetFastChar();
125 0 : if( '/' == c )
126 : {
127 0 : while( '\n' != c && !pFI->IsEof() )
128 0 : c = pFI->GetFastChar();
129 :
130 0 : c = pFI->GetFastChar();
131 : }
132 0 : else if( '*' == c )
133 : {
134 0 : c = pFI->GetFastChar();
135 0 : do
136 : {
137 0 : while( '*' != c && !pFI->IsEof() )
138 0 : c = pFI->GetFastChar();
139 :
140 0 : c = pFI->GetFastChar();
141 : }
142 0 : while( '/' != c && !pFI->IsEof() );
143 0 : c = pFI->GetFastChar();
144 : }
145 : else
146 0 : return c1;
147 : }
148 : else
149 781391 : break;
150 : }
151 :
152 : // FIXME: wtf is this supposed to do?
153 781391 : if( (c != 0) == pFI->IsEof() )
154 : {
155 0 : return 0;
156 : }
157 :
158 781391 : if( bLastInclude )
159 : {
160 0 : bLastInclude = false; //Zuruecksetzten
161 0 : if( '<' == c )
162 : {
163 0 : OStringBuffer aBuf( 256 );
164 0 : c = pFI->GetFastChar();
165 0 : while( '>' != c && !pFI->IsEof() )
166 : {
167 0 : aBuf.append( sal_Char(c) );
168 0 : c = pFI->GetFastChar();
169 : }
170 0 : c = pFI->GetFastChar();
171 0 : pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
172 0 : return INCLUDE_STRING;
173 : }
174 : }
175 :
176 781391 : if( c == '"' )
177 : {
178 64606 : OStringBuffer aBuf( 256 );
179 64606 : bool bDone = false;
180 1179446 : while( !bDone && !pFI->IsEof() && c )
181 : {
182 1050234 : c = pFI->GetFastChar();
183 1050234 : if( c == '"' )
184 : {
185 79791 : do
186 : {
187 79791 : c = pFI->GetFastChar();
188 : }
189 144397 : while( c == ' ' || c == '\t' );
190 :
191 64606 : if( c == '"' )
192 : {
193 : // this is a continued string
194 : // note: multiline string continuations are handled by the parser
195 : // see rscyacc.y
196 : }
197 : else
198 64606 : bDone = true;
199 : }
200 985628 : else if( c == '\\' )
201 : {
202 1238 : aBuf.append( '\\' );
203 1238 : c = pFI->GetFastChar();
204 1238 : if( c )
205 1238 : aBuf.append( sal_Char(c) );
206 : }
207 : else
208 984390 : aBuf.append( sal_Char(c) );
209 : }
210 64606 : pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
211 64606 : return STRING;
212 : }
213 716785 : if (isdigit (c))
214 : {
215 85815 : pTokenVal->value = GetNumber();
216 85815 : return NUMBER;
217 : }
218 :
219 630970 : if( isalpha (c) || (c == '_') )
220 : {
221 : Atom nHashId;
222 150363 : OStringBuffer aBuf( 256 );
223 :
224 1125134 : while( isalnum (c) || (c == '_') || (c == '-') )
225 : {
226 824408 : aBuf.append( sal_Char(c) );
227 824408 : c = pFI->GetFastChar();
228 : }
229 :
230 150363 : nHashId = pHS->getID( aBuf.getStr(), true );
231 150363 : if( InvalidAtom != nHashId )
232 : {
233 : KEY_STRUCT aKey;
234 :
235 : // Suche nach dem Schluesselwort
236 150363 : if( pTC->aNmTb.Get( nHashId, &aKey ) )
237 : {
238 :
239 : // Schluesselwort gefunden
240 150363 : switch( aKey.nTyp )
241 : {
242 : case CLASSNAME:
243 42424 : pTokenVal->pClass = reinterpret_cast<RscTop *>(aKey.yylval);
244 42424 : break;
245 : case VARNAME:
246 72767 : pTokenVal->varid = aKey.nName;
247 72767 : break;
248 : case CONSTNAME:
249 31896 : pTokenVal->constname.hashid = aKey.nName;
250 31896 : pTokenVal->constname.nValue = aKey.yylval;
251 31896 : break;
252 : case BOOLEAN:
253 2077 : pTokenVal->svbool = (bool)aKey.yylval;
254 2077 : break;
255 : case INCLUDE:
256 0 : bLastInclude = true;
257 : //fall-through
258 : default:
259 1199 : pTokenVal->value = aKey.yylval;
260 : }
261 :
262 150363 : return aKey.nTyp;
263 : }
264 : else
265 : {
266 0 : pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
267 0 : return SYMBOL;
268 : }
269 : }
270 : else
271 : {
272 : // Symbol
273 : RscDefine * pDef;
274 :
275 0 : pDef = pTC->aFileTab.FindDef( aBuf.getStr() );
276 0 : if( pDef )
277 : {
278 0 : pTokenVal->defineele = pDef;
279 :
280 0 : return RSCDEFINE;
281 : }
282 :
283 0 : pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
284 0 : return SYMBOL;
285 150363 : }
286 : }
287 :
288 480607 : if( c=='<' )
289 : {
290 4269 : c = pFI->GetFastChar();
291 4269 : if( c=='<' )
292 : {
293 831 : c = pFI->GetFastChar();
294 831 : return LEFTSHIFT;
295 : }
296 : else
297 3438 : return '<';
298 : }
299 :
300 476338 : if( c=='>' )
301 : {
302 3438 : c = pFI->GetFastChar();
303 3438 : if( c=='>' )
304 : {
305 0 : c = pFI->GetFastChar();
306 0 : return RIGHTSHIFT;
307 : }
308 : else
309 3438 : return '>';
310 : }
311 :
312 472900 : c1 = c;
313 472900 : c = pFI->GetFastChar();
314 472900 : return c1;
315 : }
316 :
317 781335 : int yylex()
318 : {
319 781335 : if( bTargetDefined )
320 0 : bTargetDefined = false;
321 : else
322 781335 : aKeyVal[ 0 ].nKeyWord = MakeToken( &aKeyVal[ 0 ].aYYSType );
323 :
324 781335 : yylval = aKeyVal[ 0 ].aYYSType;
325 781335 : return aKeyVal[ 0 ].nKeyWord;
326 : }
327 :
328 : #if defined SOLARIS
329 : extern "C" void yyerror( const char* pMessage )
330 : #else
331 0 : void yyerror( char* pMessage )
332 : #endif
333 : {
334 0 : pTC->pEH->Error( ERR_YACC, NULL, RscId(), pMessage );
335 0 : }
336 :
337 473 : void InitParser( RscFileInst * pFileInst )
338 : {
339 473 : pTC = pFileInst->pTypCont; // Datenkontainer setzten
340 473 : pFI = pFileInst;
341 473 : pStringContainer = new StringContainer();
342 473 : pExp = NULL; //fuer MacroParser
343 473 : bTargetDefined = false;
344 :
345 : // Anfangszeichen initialisieren
346 473 : bLastInclude = false;
347 473 : c = pFI->GetFastChar();
348 473 : }
349 :
350 473 : void EndParser()
351 : {
352 : // Stack abraeumen
353 946 : while( ! S.IsEmpty() )
354 0 : S.Pop();
355 :
356 : // free string container
357 473 : delete pStringContainer;
358 473 : pStringContainer = NULL;
359 :
360 473 : if( pExp )
361 0 : delete pExp;
362 473 : pTC = NULL;
363 473 : pFI = NULL;
364 473 : pExp = NULL;
365 :
366 473 : }
367 :
368 56 : void IncludeParser( RscFileInst * pFileInst )
369 : {
370 : int nToken; // Wert des Tokens
371 : YYSTYPE aYYSType; // Daten des Tokens
372 : RscFile * pFName; // Filestruktur
373 : sal_uLong lKey; // Fileschluessel
374 56 : RscTypCont * pTypCon = pFileInst->pTypCont;
375 :
376 56 : pFName = pTypCon->aFileTab.Get( pFileInst->GetFileIndex() );
377 56 : InitParser( pFileInst );
378 :
379 56 : nToken = MakeToken( &aYYSType );
380 112 : while( 0 != nToken && CLASSNAME != nToken )
381 : {
382 0 : if( '#' == nToken )
383 : {
384 0 : if( INCLUDE == (nToken = MakeToken( &aYYSType )) )
385 : {
386 0 : if( STRING == (nToken = MakeToken( &aYYSType )) )
387 : {
388 : lKey = pTypCon->aFileTab.NewIncFile( aYYSType.string,
389 0 : aYYSType.string );
390 0 : pFName->InsertDependFile( lKey, ULONG_MAX );
391 : }
392 0 : else if( INCLUDE_STRING == nToken )
393 : {
394 : lKey = pTypCon->aFileTab.NewIncFile( aYYSType.string,
395 0 : OString() );
396 0 : pFName->InsertDependFile( lKey, ULONG_MAX );
397 : }
398 : }
399 : }
400 0 : nToken = MakeToken( &aYYSType );
401 : }
402 :
403 56 : EndParser();
404 56 : }
405 :
406 417 : ERRTYPE parser( RscFileInst * pFileInst )
407 : {
408 417 : ERRTYPE aError;
409 :
410 417 : InitParser( pFileInst );
411 :
412 417 : aError = yyparse();
413 :
414 417 : EndParser();
415 :
416 : // yyparser gibt 0 zurueck, wenn erfolgreich
417 417 : if( 0 == aError )
418 417 : aError.Clear();
419 417 : if( pFileInst->pTypCont->pEH->nErrors )
420 0 : aError = ERR_ERROR;
421 417 : pFileInst->SetError( aError );
422 417 : return aError;
423 : }
424 :
425 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|