1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_rsc.hxx" 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <string.h> 33 #include <ctype.h> 34 #include <limits.h> 35 36 #ifdef _RSCERROR_H 37 #include <rscerror.h> 38 #endif 39 #include <rschash.hxx> 40 #include <rscdb.hxx> 41 #include <rsctop.hxx> 42 #include <rsckey.hxx> 43 #include <rscpar.hxx> 44 #include <rscdef.hxx> 45 46 #include "rsclex.hxx" 47 #include <yyrscyacc.hxx> 48 49 #include <rtl/textcvt.h> 50 #include <rtl/textenc.h> 51 52 using namespace rtl; 53 54 const char* StringContainer::putString( const char* pString ) 55 { 56 OString aString( static_cast<const sal_Char*>(pString) ); 57 std::pair< 58 std::hash_set< OString, OStringHash >::iterator, 59 bool > aInsert = 60 m_aStrings.insert( aString ); 61 62 return aInsert.first->getStr(); 63 } 64 65 /*************************************************************************/ 66 int c; 67 sal_Bool bLastInclude;// War letztes Symbol INCLUDE 68 RscFileInst* pFI; 69 RscTypCont* pTC; 70 RscExpression * pExp; 71 struct KeyVal { 72 int nKeyWord; 73 YYSTYPE aYYSType; 74 } aKeyVal[ 1 ]; 75 sal_Bool bTargetDefined; 76 77 StringContainer* pStringContainer = NULL; 78 79 80 /****************** C O D E **********************************************/ 81 sal_uInt32 GetNumber(){ 82 sal_uInt32 l = 0; 83 sal_uInt32 nLog = 10; 84 85 if( '0' == c ){ 86 c = pFI->GetFastChar(); 87 if( 'x' == c ){ 88 nLog = 16; 89 c = pFI->GetFastChar(); 90 } 91 }; 92 93 if( nLog == 16 ){ 94 while( isxdigit( c ) ){ 95 if( isdigit( c ) ) 96 l = l * nLog + (c - '0'); 97 else 98 l = l * nLog + (toupper( c ) - 'A' + 10 ); 99 c = pFI->GetFastChar(); 100 } 101 } 102 else{ 103 while( isdigit( c ) || 'x' == c ){ 104 l = l * nLog + (c - '0'); 105 c = pFI->GetFastChar(); 106 } 107 } 108 109 while( c=='U' || c=='u' || c=='l' || c=='L' ) //Wg. Unsigned Longs 110 c = pFI->GetFastChar(); 111 112 if( l > 0x7fffffff ) //Oberstes bit gegebenenfalls abschneiden; 113 l &= 0x7fffffff; 114 115 return( l ); 116 } 117 118 int MakeToken( YYSTYPE * pTokenVal ){ 119 int c1; 120 char * pStr; 121 122 while( sal_True ){ // Kommentare und Leerzeichen ueberlesen 123 while( isspace( c ) ) 124 c = pFI->GetFastChar(); 125 if( '/' == c ){ 126 c1 = c; 127 c = pFI->GetFastChar(); 128 if( '/' == c ){ 129 while( '\n' != c && !pFI->IsEof() ) 130 c = pFI->GetFastChar(); 131 c = pFI->GetFastChar(); 132 } 133 else if( '*' == c ){ 134 c = pFI->GetFastChar(); 135 do { 136 while( '*' != c && !pFI->IsEof() ) 137 c = pFI->GetFastChar(); 138 c = pFI->GetFastChar(); 139 } while( '/' != c && !pFI->IsEof() ); 140 c = pFI->GetFastChar(); 141 } 142 else 143 return( c1 ); 144 } 145 else 146 break; 147 }; 148 149 if( c == pFI->IsEof() ){ 150 return( 0 ); 151 } 152 153 if( bLastInclude ){ 154 bLastInclude = sal_False; //Zuruecksetzten 155 if( '<' == c ){ 156 OStringBuffer aBuf( 256 ); 157 c = pFI->GetFastChar(); 158 while( '>' != c && !pFI->IsEof() ) 159 { 160 aBuf.append( sal_Char(c) ); 161 c = pFI->GetFastChar(); 162 }; 163 c = pFI->GetFastChar(); 164 pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() )); 165 return( INCLUDE_STRING ); 166 }; 167 } 168 169 if( c == '"' ) 170 { 171 OStringBuffer aBuf( 256 ); 172 sal_Bool bDone = sal_False; 173 while( !bDone && !pFI->IsEof() && c ) 174 { 175 c = pFI->GetFastChar(); 176 if( c == '"' ) 177 { 178 do 179 { 180 c = pFI->GetFastChar(); 181 } 182 while( c == ' ' || c == '\t' ); 183 if( c == '"' ) 184 { 185 // this is a continued string 186 // note: multiline string continuations are handled by the parser 187 // see rscyacc.y 188 } 189 else 190 bDone = sal_True; 191 } 192 else if( c == '\\' ) 193 { 194 aBuf.append( '\\' ); 195 c = pFI->GetFastChar(); 196 if( c ) 197 aBuf.append( sal_Char(c) ); 198 } 199 else 200 aBuf.append( sal_Char(c) ); 201 } 202 pStr = pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() )); 203 return( STRING ); 204 } 205 if (isdigit (c)){ 206 pTokenVal->value = GetNumber(); 207 return( NUMBER ); 208 } 209 210 if( isalpha (c) || (c == '_') ){ 211 Atom nHashId; 212 OStringBuffer aBuf( 256 ); 213 214 while( isalnum (c) || (c == '_') || (c == '-') ) 215 { 216 aBuf.append( sal_Char(c) ); 217 c = pFI->GetFastChar(); 218 } 219 220 nHashId = pHS->getID( aBuf.getStr(), true ); 221 if( InvalidAtom != nHashId ) 222 { 223 KEY_STRUCT aKey; 224 225 // Suche nach dem Schluesselwort 226 if( pTC->aNmTb.Get( nHashId, &aKey ) ) 227 { 228 229 // Schluesselwort gefunden 230 switch( aKey.nTyp ) 231 { 232 case CLASSNAME: 233 pTokenVal->pClass = (RscTop *)aKey.yylval; 234 break; 235 case VARNAME: 236 pTokenVal->varid = aKey.nName; 237 break; 238 case CONSTNAME: 239 pTokenVal->constname.hashid = aKey.nName; 240 pTokenVal->constname.nValue = aKey.yylval; 241 break; 242 case BOOLEAN: 243 pTokenVal->svbool = (sal_Bool)aKey.yylval; 244 break; 245 case INCLUDE: 246 bLastInclude = sal_True; 247 default: 248 pTokenVal->value = aKey.yylval; 249 }; 250 251 return( aKey.nTyp ); 252 } 253 else 254 { 255 pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() )); 256 return( SYMBOL ); 257 } 258 } 259 else{ // Symbol 260 RscDefine * pDef; 261 262 pDef = pTC->aFileTab.FindDef( aBuf.getStr() ); 263 if( pDef ){ 264 pTokenVal->defineele = pDef; 265 266 return( RSCDEFINE ); 267 } 268 269 pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() )); 270 return( SYMBOL ); 271 } 272 } 273 274 if( c=='<' ) 275 { 276 c = pFI->GetFastChar(); 277 if( c=='<' ) 278 { 279 c = pFI->GetFastChar(); 280 return LEFTSHIFT; 281 } 282 else 283 return '<'; 284 } 285 286 if( c=='>' ) 287 { 288 c = pFI->GetFastChar(); 289 if( c=='>' ) 290 { 291 c = pFI->GetFastChar(); 292 return RIGHTSHIFT; 293 } 294 else 295 return '>'; 296 } 297 298 c1 = c; 299 c = pFI->GetFastChar(); 300 return( c1 ); 301 } 302 303 #if defined( RS6000 ) || defined( HP9000 ) || defined( SCO ) 304 extern "C" int yylex() 305 #else 306 int yylex() 307 #endif 308 { 309 if( bTargetDefined ) 310 bTargetDefined = sal_False; 311 else 312 aKeyVal[ 0 ].nKeyWord = 313 MakeToken( &aKeyVal[ 0 ].aYYSType ); 314 315 yylval = aKeyVal[ 0 ].aYYSType; 316 return( aKeyVal[ 0 ].nKeyWord ); 317 } 318 319 /****************** yyerror **********************************************/ 320 #ifdef RS6000 321 extern "C" void yyerror( char* pMessage ) 322 #elif defined HP9000 || defined SCO || defined SOLARIS 323 extern "C" void yyerror( const char* pMessage ) 324 #else 325 void yyerror( char* pMessage ) 326 #endif 327 { 328 pTC->pEH->Error( ERR_YACC, NULL, RscId(), pMessage ); 329 } 330 331 /****************** parser start function ********************************/ 332 void InitParser( RscFileInst * pFileInst ) 333 { 334 pTC = pFileInst->pTypCont; // Datenkontainer setzten 335 pFI = pFileInst; 336 pStringContainer = new StringContainer(); 337 pExp = NULL; //fuer MacroParser 338 bTargetDefined = sal_False; 339 340 // Anfangszeichen initialisieren 341 bLastInclude = sal_False; 342 c = pFI->GetFastChar(); 343 } 344 345 void EndParser(){ 346 // Stack abraeumen 347 while( ! S.IsEmpty() ) 348 S.Pop(); 349 350 // free string container 351 delete pStringContainer; 352 pStringContainer = NULL; 353 354 if( pExp ) 355 delete pExp; 356 pTC = NULL; 357 pFI = NULL; 358 pExp = NULL; 359 360 } 361 362 void IncludeParser( RscFileInst * pFileInst ) 363 { 364 int nToken; // Wert des Tokens 365 YYSTYPE aYYSType; // Daten des Tokens 366 RscFile * pFName; // Filestruktur 367 sal_uLong lKey; // Fileschluessel 368 RscTypCont * pTypCon = pFileInst->pTypCont; 369 370 pFName = pTypCon->aFileTab.Get( pFileInst->GetFileIndex() ); 371 InitParser( pFileInst ); 372 373 nToken = MakeToken( &aYYSType ); 374 while( 0 != nToken && CLASSNAME != nToken ){ 375 if( '#' == nToken ){ 376 if( INCLUDE == (nToken = MakeToken( &aYYSType )) ){ 377 if( STRING == (nToken = MakeToken( &aYYSType )) ){ 378 lKey = pTypCon->aFileTab.NewIncFile( aYYSType.string, 379 aYYSType.string ); 380 pFName->InsertDependFile( lKey, LIST_APPEND ); 381 } 382 else if( INCLUDE_STRING == nToken ){ 383 lKey = pTypCon->aFileTab.NewIncFile( aYYSType.string, 384 ByteString() ); 385 pFName->InsertDependFile( lKey, LIST_APPEND ); 386 }; 387 }; 388 }; 389 nToken = MakeToken( &aYYSType ); 390 }; 391 392 EndParser(); 393 } 394 395 ERRTYPE parser( RscFileInst * pFileInst ) 396 { 397 ERRTYPE aError; 398 399 InitParser( pFileInst ); 400 401 aError = yyparse(); 402 403 EndParser(); 404 405 // yyparser gibt 0 zurueck, wenn erfolgreich 406 if( 0 == aError ) 407 aError.Clear(); 408 if( pFileInst->pTypCont->pEH->nErrors ) 409 aError = ERR_ERROR; 410 pFileInst->SetError( aError ); 411 return( aError ); 412 } 413 414 RscExpression * MacroParser( RscFileInst & rFileInst ) 415 { 416 ERRTYPE aError; 417 RscExpression * pExpression; 418 419 InitParser( &rFileInst ); 420 421 //Ziel auf macro_expression setzen 422 aKeyVal[ 0 ].nKeyWord = MACROTARGET; 423 bTargetDefined = sal_True; 424 aError = yyparse(); 425 426 pExpression = pExp; 427 //EndParser() wuerde pExp loeschen 428 if( pExp ) 429 pExp = NULL; 430 431 EndParser(); 432 433 // yyparser gibt 0 zurueck, wenn erfolgreich 434 if( 0 == aError ) 435 aError.Clear(); 436 if( rFileInst.pTypCont->pEH->nErrors ) 437 aError = ERR_ERROR; 438 rFileInst.SetError( aError ); 439 440 //im Fehlerfall pExpression loeschen 441 if( aError.IsError() && pExpression ){ 442 delete pExpression; 443 pExpression = NULL; 444 }; 445 return( pExpression ); 446 } 447 448