| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_rsc.hxx" |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <ctype.h> |
| #include <limits.h> |
| |
| #ifdef _RSCERROR_H |
| #include <rscerror.h> |
| #endif |
| #include <rschash.hxx> |
| #include <rscdb.hxx> |
| #include <rsctop.hxx> |
| #include <rsckey.hxx> |
| #include <rscpar.hxx> |
| #include <rscdef.hxx> |
| |
| #include "rsclex.hxx" |
| #include <yyrscyacc.hxx> |
| |
| #include <rtl/textcvt.h> |
| #include <rtl/textenc.h> |
| |
| using namespace rtl; |
| |
| const char* StringContainer::putString( const char* pString ) |
| { |
| OString aString( static_cast<const sal_Char*>(pString) ); |
| std::pair< |
| std::hash_set< OString, OStringHash >::iterator, |
| bool > aInsert = |
| m_aStrings.insert( aString ); |
| |
| return aInsert.first->getStr(); |
| } |
| |
| /*************************************************************************/ |
| int c; |
| sal_Bool bLastInclude;// War letztes Symbol INCLUDE |
| RscFileInst* pFI; |
| RscTypCont* pTC; |
| RscExpression * pExp; |
| struct KeyVal { |
| int nKeyWord; |
| YYSTYPE aYYSType; |
| } aKeyVal[ 1 ]; |
| sal_Bool bTargetDefined; |
| |
| StringContainer* pStringContainer = NULL; |
| |
| |
| /****************** C O D E **********************************************/ |
| sal_uInt32 GetNumber(){ |
| sal_uInt32 l = 0; |
| sal_uInt32 nLog = 10; |
| |
| if( '0' == c ){ |
| c = pFI->GetFastChar(); |
| if( 'x' == c ){ |
| nLog = 16; |
| c = pFI->GetFastChar(); |
| } |
| }; |
| |
| if( nLog == 16 ){ |
| while( isxdigit( c ) ){ |
| if( isdigit( c ) ) |
| l = l * nLog + (c - '0'); |
| else |
| l = l * nLog + (toupper( c ) - 'A' + 10 ); |
| c = pFI->GetFastChar(); |
| } |
| } |
| else{ |
| while( isdigit( c ) || 'x' == c ){ |
| l = l * nLog + (c - '0'); |
| c = pFI->GetFastChar(); |
| } |
| } |
| |
| while( c=='U' || c=='u' || c=='l' || c=='L' ) //Wg. Unsigned Longs |
| c = pFI->GetFastChar(); |
| |
| if( l > 0x7fffffff ) //Oberstes bit gegebenenfalls abschneiden; |
| l &= 0x7fffffff; |
| |
| return( l ); |
| } |
| |
| int MakeToken( YYSTYPE * pTokenVal ){ |
| int c1; |
| char * pStr; |
| |
| while( sal_True ){ // Kommentare und Leerzeichen ueberlesen |
| while( isspace( c ) ) |
| c = pFI->GetFastChar(); |
| if( '/' == c ){ |
| c1 = c; |
| c = pFI->GetFastChar(); |
| if( '/' == c ){ |
| while( '\n' != c && !pFI->IsEof() ) |
| c = pFI->GetFastChar(); |
| c = pFI->GetFastChar(); |
| } |
| else if( '*' == c ){ |
| c = pFI->GetFastChar(); |
| do { |
| while( '*' != c && !pFI->IsEof() ) |
| c = pFI->GetFastChar(); |
| c = pFI->GetFastChar(); |
| } while( '/' != c && !pFI->IsEof() ); |
| c = pFI->GetFastChar(); |
| } |
| else |
| return( c1 ); |
| } |
| else |
| break; |
| }; |
| |
| if( c == pFI->IsEof() ){ |
| return( 0 ); |
| } |
| |
| if( bLastInclude ){ |
| bLastInclude = sal_False; //Zuruecksetzten |
| if( '<' == c ){ |
| OStringBuffer aBuf( 256 ); |
| c = pFI->GetFastChar(); |
| while( '>' != c && !pFI->IsEof() ) |
| { |
| aBuf.append( sal_Char(c) ); |
| c = pFI->GetFastChar(); |
| }; |
| c = pFI->GetFastChar(); |
| pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() )); |
| return( INCLUDE_STRING ); |
| }; |
| } |
| |
| if( c == '"' ) |
| { |
| OStringBuffer aBuf( 256 ); |
| sal_Bool bDone = sal_False; |
| while( !bDone && !pFI->IsEof() && c ) |
| { |
| c = pFI->GetFastChar(); |
| if( c == '"' ) |
| { |
| do |
| { |
| c = pFI->GetFastChar(); |
| } |
| while( c == ' ' || c == '\t' ); |
| if( c == '"' ) |
| { |
| // this is a continued string |
| // note: multiline string continuations are handled by the parser |
| // see rscyacc.y |
| } |
| else |
| bDone = sal_True; |
| } |
| else if( c == '\\' ) |
| { |
| aBuf.append( '\\' ); |
| c = pFI->GetFastChar(); |
| if( c ) |
| aBuf.append( sal_Char(c) ); |
| } |
| else |
| aBuf.append( sal_Char(c) ); |
| } |
| pStr = pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() )); |
| return( STRING ); |
| } |
| if (isdigit (c)){ |
| pTokenVal->value = GetNumber(); |
| return( NUMBER ); |
| } |
| |
| if( isalpha (c) || (c == '_') ){ |
| Atom nHashId; |
| OStringBuffer aBuf( 256 ); |
| |
| while( isalnum (c) || (c == '_') || (c == '-') ) |
| { |
| aBuf.append( sal_Char(c) ); |
| c = pFI->GetFastChar(); |
| } |
| |
| nHashId = pHS->getID( aBuf.getStr(), true ); |
| if( InvalidAtom != nHashId ) |
| { |
| KEY_STRUCT aKey; |
| |
| // Suche nach dem Schluesselwort |
| if( pTC->aNmTb.Get( nHashId, &aKey ) ) |
| { |
| |
| // Schluesselwort gefunden |
| switch( aKey.nTyp ) |
| { |
| case CLASSNAME: |
| pTokenVal->pClass = (RscTop *)aKey.yylval; |
| break; |
| case VARNAME: |
| pTokenVal->varid = aKey.nName; |
| break; |
| case CONSTNAME: |
| pTokenVal->constname.hashid = aKey.nName; |
| pTokenVal->constname.nValue = aKey.yylval; |
| break; |
| case BOOLEAN: |
| pTokenVal->svbool = (sal_Bool)aKey.yylval; |
| break; |
| case INCLUDE: |
| bLastInclude = sal_True; |
| default: |
| pTokenVal->value = aKey.yylval; |
| }; |
| |
| return( aKey.nTyp ); |
| } |
| else |
| { |
| pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() )); |
| return( SYMBOL ); |
| } |
| } |
| else{ // Symbol |
| RscDefine * pDef; |
| |
| pDef = pTC->aFileTab.FindDef( aBuf.getStr() ); |
| if( pDef ){ |
| pTokenVal->defineele = pDef; |
| |
| return( RSCDEFINE ); |
| } |
| |
| pTokenVal->string = const_cast<char*>(pStringContainer->putString( aBuf.getStr() )); |
| return( SYMBOL ); |
| } |
| } |
| |
| if( c=='<' ) |
| { |
| c = pFI->GetFastChar(); |
| if( c=='<' ) |
| { |
| c = pFI->GetFastChar(); |
| return LEFTSHIFT; |
| } |
| else |
| return '<'; |
| } |
| |
| if( c=='>' ) |
| { |
| c = pFI->GetFastChar(); |
| if( c=='>' ) |
| { |
| c = pFI->GetFastChar(); |
| return RIGHTSHIFT; |
| } |
| else |
| return '>'; |
| } |
| |
| c1 = c; |
| c = pFI->GetFastChar(); |
| return( c1 ); |
| } |
| |
| #if defined( RS6000 ) || defined( HP9000 ) || defined( SCO ) |
| extern "C" int yylex() |
| #else |
| int yylex() |
| #endif |
| { |
| if( bTargetDefined ) |
| bTargetDefined = sal_False; |
| else |
| aKeyVal[ 0 ].nKeyWord = |
| MakeToken( &aKeyVal[ 0 ].aYYSType ); |
| |
| yylval = aKeyVal[ 0 ].aYYSType; |
| return( aKeyVal[ 0 ].nKeyWord ); |
| } |
| |
| /****************** yyerror **********************************************/ |
| #ifdef RS6000 |
| extern "C" void yyerror( char* pMessage ) |
| #elif defined HP9000 || defined SCO || defined SOLARIS |
| extern "C" void yyerror( const char* pMessage ) |
| #else |
| void yyerror( char* pMessage ) |
| #endif |
| { |
| pTC->pEH->Error( ERR_YACC, NULL, RscId(), pMessage ); |
| } |
| |
| /****************** parser start function ********************************/ |
| void InitParser( RscFileInst * pFileInst ) |
| { |
| pTC = pFileInst->pTypCont; // Datenkontainer setzten |
| pFI = pFileInst; |
| pStringContainer = new StringContainer(); |
| pExp = NULL; //fuer MacroParser |
| bTargetDefined = sal_False; |
| |
| // Anfangszeichen initialisieren |
| bLastInclude = sal_False; |
| c = pFI->GetFastChar(); |
| } |
| |
| void EndParser(){ |
| // Stack abraeumen |
| while( ! S.IsEmpty() ) |
| S.Pop(); |
| |
| // free string container |
| delete pStringContainer; |
| pStringContainer = NULL; |
| |
| if( pExp ) |
| delete pExp; |
| pTC = NULL; |
| pFI = NULL; |
| pExp = NULL; |
| |
| } |
| |
| void IncludeParser( RscFileInst * pFileInst ) |
| { |
| int nToken; // Wert des Tokens |
| YYSTYPE aYYSType; // Daten des Tokens |
| RscFile * pFName; // Filestruktur |
| sal_uLong lKey; // Fileschluessel |
| RscTypCont * pTypCon = pFileInst->pTypCont; |
| |
| pFName = pTypCon->aFileTab.Get( pFileInst->GetFileIndex() ); |
| InitParser( pFileInst ); |
| |
| nToken = MakeToken( &aYYSType ); |
| while( 0 != nToken && CLASSNAME != nToken ){ |
| if( '#' == nToken ){ |
| if( INCLUDE == (nToken = MakeToken( &aYYSType )) ){ |
| if( STRING == (nToken = MakeToken( &aYYSType )) ){ |
| lKey = pTypCon->aFileTab.NewIncFile( aYYSType.string, |
| aYYSType.string ); |
| pFName->InsertDependFile( lKey, LIST_APPEND ); |
| } |
| else if( INCLUDE_STRING == nToken ){ |
| lKey = pTypCon->aFileTab.NewIncFile( aYYSType.string, |
| ByteString() ); |
| pFName->InsertDependFile( lKey, LIST_APPEND ); |
| }; |
| }; |
| }; |
| nToken = MakeToken( &aYYSType ); |
| }; |
| |
| EndParser(); |
| } |
| |
| ERRTYPE parser( RscFileInst * pFileInst ) |
| { |
| ERRTYPE aError; |
| |
| InitParser( pFileInst ); |
| |
| aError = yyparse(); |
| |
| EndParser(); |
| |
| // yyparser gibt 0 zurueck, wenn erfolgreich |
| if( 0 == aError ) |
| aError.Clear(); |
| if( pFileInst->pTypCont->pEH->nErrors ) |
| aError = ERR_ERROR; |
| pFileInst->SetError( aError ); |
| return( aError ); |
| } |
| |
| RscExpression * MacroParser( RscFileInst & rFileInst ) |
| { |
| ERRTYPE aError; |
| RscExpression * pExpression; |
| |
| InitParser( &rFileInst ); |
| |
| //Ziel auf macro_expression setzen |
| aKeyVal[ 0 ].nKeyWord = MACROTARGET; |
| bTargetDefined = sal_True; |
| aError = yyparse(); |
| |
| pExpression = pExp; |
| //EndParser() wuerde pExp loeschen |
| if( pExp ) |
| pExp = NULL; |
| |
| EndParser(); |
| |
| // yyparser gibt 0 zurueck, wenn erfolgreich |
| if( 0 == aError ) |
| aError.Clear(); |
| if( rFileInst.pTypCont->pEH->nErrors ) |
| aError = ERR_ERROR; |
| rFileInst.SetError( aError ); |
| |
| //im Fehlerfall pExpression loeschen |
| if( aError.IsError() && pExpression ){ |
| delete pExpression; |
| pExpression = NULL; |
| }; |
| return( pExpression ); |
| } |
| |