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