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 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 **********************************************/ 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 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 ) 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 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 ********************************/ 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 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 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 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 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