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 92880 : const char* StringContainer::putString( const char* pString )
47 : {
48 92880 : OString aString( static_cast<const sal_Char*>(pString) );
49 : std::pair<
50 : boost::unordered_set< OString, OStringHash >::iterator,
51 : bool > aInsert =
52 92880 : m_aStrings.insert( aString );
53 :
54 92880 : 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 189411 : sal_uInt32 GetNumber(){
74 189411 : sal_uInt32 l = 0;
75 189411 : sal_uInt32 nLog = 10;
76 :
77 189411 : if( '0' == c ){
78 6207 : c = pFI->GetFastChar();
79 6207 : if( 'x' == c ){
80 2043 : nLog = 16;
81 2043 : c = pFI->GetFastChar();
82 : }
83 : };
84 :
85 189411 : if( nLog == 16 ){
86 12464 : while( isxdigit( c ) ){
87 8378 : if( isdigit( c ) )
88 4257 : l = l * nLog + (c - '0');
89 : else
90 4121 : l = l * nLog + (toupper( c ) - 'A' + 10 );
91 8378 : c = pFI->GetFastChar();
92 : }
93 : }
94 : else{
95 819467 : while( isdigit( c ) || 'x' == c ){
96 444731 : l = l * nLog + (c - '0');
97 444731 : c = pFI->GetFastChar();
98 : }
99 : }
100 :
101 381184 : while( c=='U' || c=='u' || c=='l' || c=='L' ) //Wg. Unsigned Longs
102 2362 : c = pFI->GetFastChar();
103 :
104 189411 : if( l > 0x7fffffff ) //Oberstes bit gegebenenfalls abschneiden;
105 60 : l &= 0x7fffffff;
106 :
107 189411 : return( l );
108 : }
109 :
110 1482771 : int MakeToken( YYSTYPE * pTokenVal ){
111 : int c1;
112 :
113 0 : while( sal_True ){ // Kommentare und Leerzeichen ueberlesen
114 4396874 : while( isspace( c ) )
115 1431332 : c = pFI->GetFastChar();
116 1482771 : if( '/' == c ){
117 233 : c1 = c;
118 233 : c = pFI->GetFastChar();
119 233 : if( '/' == c ){
120 0 : while( '\n' != c && !pFI->IsEof() )
121 0 : c = pFI->GetFastChar();
122 0 : c = pFI->GetFastChar();
123 : }
124 233 : 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 233 : return( c1 );
135 : }
136 : else
137 1482538 : break;
138 : };
139 :
140 1482538 : if( c == pFI->IsEof() ){
141 0 : return( 0 );
142 : }
143 :
144 1482538 : 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 1482538 : if( c == '"' )
161 : {
162 91574 : OStringBuffer aBuf( 256 );
163 91574 : sal_Bool bDone = sal_False;
164 1821525 : while( !bDone && !pFI->IsEof() && c )
165 : {
166 1638377 : c = pFI->GetFastChar();
167 1638377 : if( c == '"' )
168 : {
169 111333 : do
170 : {
171 111333 : c = pFI->GetFastChar();
172 : }
173 : while( c == ' ' || c == '\t' );
174 91576 : 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 91574 : bDone = sal_True;
182 : }
183 1546801 : else if( c == '\\' )
184 : {
185 2008 : aBuf.append( '\\' );
186 2008 : c = pFI->GetFastChar();
187 2008 : if( c )
188 2008 : aBuf.append( sal_Char(c) );
189 : }
190 : else
191 1544793 : aBuf.append( sal_Char(c) );
192 : }
193 91574 : pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
194 91574 : return( STRING );
195 : }
196 1390964 : if (isdigit (c)){
197 189411 : pTokenVal->value = GetNumber();
198 189411 : return( NUMBER );
199 : }
200 :
201 1201553 : if( isalpha (c) || (c == '_') ){
202 : Atom nHashId;
203 327133 : OStringBuffer aBuf( 256 );
204 :
205 2642531 : while( isalnum (c) || (c == '_') || (c == '-') )
206 : {
207 1988265 : aBuf.append( sal_Char(c) );
208 1988265 : c = pFI->GetFastChar();
209 : }
210 :
211 327133 : nHashId = pHS->getID( aBuf.getStr(), true );
212 327133 : if( InvalidAtom != nHashId )
213 : {
214 : KEY_STRUCT aKey;
215 :
216 : // Suche nach dem Schluesselwort
217 327133 : if( pTC->aNmTb.Get( nHashId, &aKey ) )
218 : {
219 :
220 : // Schluesselwort gefunden
221 327133 : switch( aKey.nTyp )
222 : {
223 : case CLASSNAME:
224 59987 : pTokenVal->pClass = (RscTop *)aKey.yylval;
225 59987 : break;
226 : case VARNAME:
227 129091 : pTokenVal->varid = aKey.nName;
228 129091 : break;
229 : case CONSTNAME:
230 77291 : pTokenVal->constname.hashid = aKey.nName;
231 77291 : pTokenVal->constname.nValue = aKey.yylval;
232 77291 : break;
233 : case BOOLEAN:
234 24953 : pTokenVal->svbool = (sal_Bool)aKey.yylval;
235 24953 : break;
236 : case INCLUDE:
237 0 : bLastInclude = sal_True;
238 : default:
239 35811 : pTokenVal->value = aKey.yylval;
240 : };
241 :
242 327133 : return( aKey.nTyp );
243 : }
244 : else
245 : {
246 0 : pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() ));
247 0 : 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 327133 : }
263 : }
264 :
265 874420 : if( c=='<' )
266 : {
267 6116 : c = pFI->GetFastChar();
268 6116 : if( c=='<' )
269 : {
270 828 : c = pFI->GetFastChar();
271 828 : return LEFTSHIFT;
272 : }
273 : else
274 5288 : return '<';
275 : }
276 :
277 868304 : if( c=='>' )
278 : {
279 5279 : c = pFI->GetFastChar();
280 5279 : if( c=='>' )
281 : {
282 0 : c = pFI->GetFastChar();
283 0 : return RIGHTSHIFT;
284 : }
285 : else
286 5279 : return '>';
287 : }
288 :
289 863025 : c1 = c;
290 863025 : c = pFI->GetFastChar();
291 863025 : return( c1 );
292 : }
293 :
294 : #if defined( RS6000 )
295 : extern "C" int yylex()
296 : #else
297 1482709 : int yylex()
298 : #endif
299 : {
300 1482709 : if( bTargetDefined )
301 0 : bTargetDefined = sal_False;
302 : else
303 : aKeyVal[ 0 ].nKeyWord =
304 1482709 : MakeToken( &aKeyVal[ 0 ].aYYSType );
305 :
306 1482709 : yylval = aKeyVal[ 0 ].aYYSType;
307 1482709 : 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 754 : void InitParser( RscFileInst * pFileInst )
324 : {
325 754 : pTC = pFileInst->pTypCont; // Datenkontainer setzten
326 754 : pFI = pFileInst;
327 754 : pStringContainer = new StringContainer();
328 754 : pExp = NULL; //fuer MacroParser
329 754 : bTargetDefined = sal_False;
330 :
331 : // Anfangszeichen initialisieren
332 754 : bLastInclude = sal_False;
333 754 : c = pFI->GetFastChar();
334 754 : }
335 :
336 754 : void EndParser(){
337 : // Stack abraeumen
338 1508 : while( ! S.IsEmpty() )
339 0 : S.Pop();
340 :
341 : // free string container
342 754 : delete pStringContainer;
343 754 : pStringContainer = NULL;
344 :
345 754 : if( pExp )
346 0 : delete pExp;
347 754 : pTC = NULL;
348 754 : pFI = NULL;
349 754 : pExp = NULL;
350 :
351 754 : }
352 :
353 62 : 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 62 : RscTypCont * pTypCon = pFileInst->pTypCont;
360 :
361 62 : pFName = pTypCon->aFileTab.Get( pFileInst->GetFileIndex() );
362 62 : InitParser( pFileInst );
363 :
364 62 : nToken = MakeToken( &aYYSType );
365 124 : 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 62 : EndParser();
384 62 : }
385 :
386 692 : ERRTYPE parser( RscFileInst * pFileInst )
387 : {
388 692 : ERRTYPE aError;
389 :
390 692 : InitParser( pFileInst );
391 :
392 692 : aError = yyparse();
393 :
394 692 : EndParser();
395 :
396 : // yyparser gibt 0 zurueck, wenn erfolgreich
397 692 : if( 0 == aError )
398 692 : aError.Clear();
399 692 : if( pFileInst->pTypCont->pEH->nErrors )
400 0 : aError = ERR_ERROR;
401 692 : pFileInst->SetError( aError );
402 692 : return( aError );
403 : }
404 :
405 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|