diff options
Diffstat (limited to 'rsc/source/parser/rsclex.cxx')
-rw-r--r-- | rsc/source/parser/rsclex.cxx | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/rsc/source/parser/rsclex.cxx b/rsc/source/parser/rsclex.cxx new file mode 100644 index 000000000000..8c34637fa304 --- /dev/null +++ b/rsc/source/parser/rsclex.cxx @@ -0,0 +1,445 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: rsclex.cxx,v $ + * $Revision: 1.13 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 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; +BOOL bLastInclude;// War letztes Symbol INCLUDE +RscFileInst* pFI; +RscTypCont* pTC; +RscExpression * pExp; +struct KeyVal { + int nKeyWord; + YYSTYPE aYYSType; +} aKeyVal[ 1 ]; +BOOL bTargetDefined; + +StringContainer* pStringContainer = NULL; + + +/****************** C O D E **********************************************/ +UINT32 GetNumber(){ + UINT32 l = 0; + 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( 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 = 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 ); + BOOL bDone = FALSE; + while( !bDone && !pFI->IsEof() && c ) + { + c = pFI->GetFastChar(); + if( c == '"' ) + { + c = pFI->GetFastChar(); + if( c == '"' ) + { + aBuf.append( '"' ); + aBuf.append( '"' ); + } + else + bDone = 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 = (BOOL)aKey.yylval; + break; + case INCLUDE: + bLastInclude = 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 = 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 = FALSE; + + // Anfangszeichen initialisieren + bLastInclude = 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 + 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 = 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 ); +} + |