blob: 78bdf28eb36873be1f67cfa07e58b4c6ec403955 [file] [log] [blame]
/**************************************************************
*
* 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 );
}