f8087b516a
Change-Id: I22adb7f3750f1e1b9910f37046c5da98ac7ab5be Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159697 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
590 lines
17 KiB
C++
590 lines
17 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* 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 .
|
|
*/
|
|
|
|
#include <sal/config.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <parser.hxx>
|
|
#include <database.hxx>
|
|
#include <globals.hxx>
|
|
#include <slot.hxx>
|
|
#include <osl/file.hxx>
|
|
|
|
void SvIdlParser::ReadSvIdl( const OUString & rPath )
|
|
{
|
|
rBase.SetPath(rPath); // only valid for this iteration
|
|
SvToken& rTok = rInStm.GetToken();
|
|
|
|
while( true )
|
|
{
|
|
rTok = rInStm.GetToken();
|
|
if( rTok.IsEof() )
|
|
return;
|
|
|
|
Read( SvHash_module() );
|
|
tools::SvRef<SvMetaModule> aModule = new SvMetaModule;
|
|
ReadModuleHeader(*aModule);
|
|
rBase.GetModuleList().push_back( aModule.get() );
|
|
}
|
|
}
|
|
|
|
void SvIdlParser::ReadModuleHeader(SvMetaModule& rModule)
|
|
{
|
|
OString aName = ReadIdentifier();
|
|
rModule.SetName( aName );
|
|
rBase.Push( &rModule ); // onto the context stack
|
|
ReadModuleBody(rModule);
|
|
rBase.GetStack().pop_back(); // remove from stack
|
|
}
|
|
|
|
void SvIdlParser::ReadModuleBody(SvMetaModule& rModule)
|
|
{
|
|
if( ReadIf( '[' ) )
|
|
{
|
|
while( true )
|
|
{
|
|
OString aSlotIdFile;
|
|
if( !ReadStringSvIdl( SvHash_SlotIdFile(), rInStm, aSlotIdFile ) )
|
|
break;
|
|
if( !rBase.ReadIdFile( aSlotIdFile ) )
|
|
{
|
|
throw SvParseException( rInStm, "cannot read file: " + aSlotIdFile );
|
|
}
|
|
ReadIfDelimiter();
|
|
}
|
|
Read( ']' );
|
|
}
|
|
|
|
if( !ReadIf( '{' ) )
|
|
return;
|
|
|
|
sal_uInt32 nBeginPos = 0;
|
|
while( nBeginPos != rInStm.Tell() )
|
|
{
|
|
nBeginPos = rInStm.Tell();
|
|
ReadModuleElement( rModule );
|
|
ReadIfDelimiter();
|
|
}
|
|
Read( '}' );
|
|
}
|
|
|
|
void SvIdlParser::ReadModuleElement( SvMetaModule& rModule )
|
|
{
|
|
if( ReadIf( SvHash_interface() ) )
|
|
{
|
|
ReadInterfaceOrShell(rModule, MetaTypeType::Interface);
|
|
}
|
|
else if( ReadIf( SvHash_shell() ) )
|
|
{
|
|
ReadInterfaceOrShell(rModule, MetaTypeType::Shell);
|
|
}
|
|
else if( ReadIf( SvHash_enum() ) )
|
|
{
|
|
ReadEnum();
|
|
}
|
|
else if( ReadIf( SvHash_item() ) )
|
|
{
|
|
ReadItem();
|
|
}
|
|
else if( ReadIf( SvHash_struct() ) )
|
|
{
|
|
ReadStruct();
|
|
}
|
|
else if( ReadIf( SvHash_include() ) )
|
|
{
|
|
ReadInclude(rModule);
|
|
}
|
|
else
|
|
{
|
|
tools::SvRef<SvMetaSlot> xSlot( new SvMetaSlot() );
|
|
|
|
if (ReadSlot(*xSlot))
|
|
{
|
|
if( xSlot->Test( rInStm ) )
|
|
{
|
|
// announce globally
|
|
rBase.AppendSlot( xSlot.get() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SvIdlParser::ReadInclude( SvMetaModule& rModule )
|
|
{
|
|
sal_uInt32 nTokPos = rInStm.Tell();
|
|
bool bOk = false;
|
|
OUString aFullName(OStringToOUString(ReadString(), RTL_TEXTENCODING_ASCII_US));
|
|
rBase.StartNewFile( aFullName );
|
|
osl::FileBase::RC searchError = osl::File::searchFileURL(aFullName, rBase.GetPath(), aFullName);
|
|
if( osl::FileBase::E_None != searchError )
|
|
{
|
|
OString aStr = "cannot find file:" +
|
|
OUStringToOString(aFullName, RTL_TEXTENCODING_UTF8);
|
|
throw SvParseException(aStr, rInStm.GetToken());
|
|
}
|
|
osl::FileBase::getSystemPathFromFileURL( aFullName, aFullName );
|
|
rBase.AddDepFile( aFullName );
|
|
SvTokenStream aTokStm( aFullName );
|
|
if( ERRCODE_NONE != aTokStm.GetStream().GetError() )
|
|
{
|
|
OString aStr = "cannot open file: " +
|
|
OUStringToOString(aFullName, RTL_TEXTENCODING_UTF8);
|
|
throw SvParseException(aStr, rInStm.GetToken());
|
|
}
|
|
// rescue error from old file
|
|
SvIdlError aOldErr = rBase.GetError();
|
|
// reset error
|
|
rBase.SetError( SvIdlError() );
|
|
|
|
try {
|
|
SvIdlParser aIncludeParser( rBase, aTokStm );
|
|
sal_uInt32 nBeginPos = 0xFFFFFFFF; // can not happen with Tell
|
|
while( nBeginPos != aTokStm.Tell() )
|
|
{
|
|
nBeginPos = aTokStm.Tell();
|
|
aIncludeParser.ReadModuleElement(rModule);
|
|
aTokStm.ReadIfDelimiter();
|
|
}
|
|
} catch (const SvParseException& ex) {
|
|
rBase.SetError(ex.aError);
|
|
rBase.WriteError(aTokStm);
|
|
}
|
|
bOk = aTokStm.GetToken().IsEof();
|
|
if( !bOk )
|
|
{
|
|
rBase.WriteError( aTokStm );
|
|
}
|
|
// recover error from old file
|
|
rBase.SetError( aOldErr );
|
|
if( !bOk )
|
|
rInStm.Seek( nTokPos );
|
|
}
|
|
|
|
void SvIdlParser::ReadStruct()
|
|
{
|
|
tools::SvRef<SvMetaType> xStruct(new SvMetaType() );
|
|
xStruct->SetType( MetaTypeType::Struct );
|
|
xStruct->SetName( ReadIdentifier() );
|
|
Read( '{' );
|
|
while( true )
|
|
{
|
|
tools::SvRef<SvMetaAttribute> xAttr( new SvMetaAttribute() );
|
|
xAttr->aType = ReadKnownType();
|
|
xAttr->SetName(ReadIdentifier());
|
|
xAttr->aSlotId.setString(ReadIdentifier());
|
|
sal_uInt32 n;
|
|
if( !rBase.FindId( xAttr->aSlotId.getString(), &n ) )
|
|
throw SvParseException( rInStm, "no value for identifier <" + xAttr->aSlotId.getString() + "> " );
|
|
xAttr->aSlotId.SetValue(n);
|
|
xStruct->GetAttrList().push_back( xAttr.get() );
|
|
if( !ReadIfDelimiter() )
|
|
break;
|
|
if( rInStm.GetToken().IsChar() && rInStm.GetToken().GetChar() == '}')
|
|
break;
|
|
}
|
|
Read( '}' );
|
|
ReadDelimiter();
|
|
// announce globally
|
|
rBase.GetTypeList().push_back( xStruct.get() );
|
|
}
|
|
|
|
void SvIdlParser::ReadItem()
|
|
{
|
|
tools::SvRef<SvMetaType> xItem(new SvMetaType() );
|
|
xItem->SetItem(true);
|
|
xItem->SetRef( ReadKnownType() );
|
|
xItem->SetName( ReadIdentifier() );
|
|
// announce globally
|
|
rBase.GetTypeList().push_back( xItem.get() );
|
|
}
|
|
|
|
void SvIdlParser::ReadEnum()
|
|
{
|
|
tools::SvRef<SvMetaTypeEnum> xEnum( new SvMetaTypeEnum() );
|
|
xEnum->SetType( MetaTypeType::Enum );
|
|
xEnum->SetName( ReadIdentifier() );
|
|
|
|
Read('{');
|
|
while( true )
|
|
{
|
|
ReadEnumValue( *xEnum );
|
|
if( !ReadIfDelimiter() )
|
|
break;
|
|
}
|
|
Read( '}' );
|
|
// announce globally
|
|
rBase.GetTypeList().push_back( xEnum.get() );
|
|
}
|
|
|
|
static std::string_view getCommonSubPrefix(std::string_view rA, std::string_view rB)
|
|
{
|
|
sal_Int32 nMax = std::min(rA.size(), rB.size());
|
|
sal_Int32 nI = 0;
|
|
while (nI < nMax)
|
|
{
|
|
if (rA[nI] != rB[nI])
|
|
break;
|
|
++nI;
|
|
}
|
|
return rA.substr(0, nI);
|
|
}
|
|
|
|
void SvIdlParser::ReadEnumValue( SvMetaTypeEnum& rEnum )
|
|
{
|
|
tools::SvRef<SvMetaEnumValue> aEnumVal = new SvMetaEnumValue();
|
|
aEnumVal->SetName( ReadIdentifier() );
|
|
if( rEnum.aEnumValueList.empty() )
|
|
{
|
|
// the first
|
|
rEnum.aPrefix = aEnumVal->GetName();
|
|
}
|
|
else
|
|
{
|
|
rEnum.aPrefix = OString(getCommonSubPrefix(rEnum.aPrefix, aEnumVal->GetName()));
|
|
}
|
|
rEnum.aEnumValueList.push_back( aEnumVal.get() );
|
|
}
|
|
|
|
void SvIdlParser::ReadInterfaceOrShell( SvMetaModule& rModule, MetaTypeType aMetaTypeType )
|
|
{
|
|
tools::SvRef<SvMetaClass> aClass( new SvMetaClass() );
|
|
|
|
aClass->SetType( aMetaTypeType );
|
|
|
|
aClass->SetName( ReadIdentifier() );
|
|
|
|
if( ReadIf( ':' ) )
|
|
{
|
|
aClass->aSuperClass = ReadKnownClass();
|
|
}
|
|
if( ReadIf( '{' ) )
|
|
{
|
|
sal_uInt32 nBeginPos = 0; // can not happen with Tell
|
|
while( nBeginPos != rInStm.Tell() )
|
|
{
|
|
nBeginPos = rInStm.Tell();
|
|
ReadInterfaceOrShellEntry(*aClass);
|
|
ReadIfDelimiter();
|
|
}
|
|
Read( '}' );
|
|
}
|
|
rModule.aClassList.push_back( aClass.get() );
|
|
// announce globally
|
|
rBase.GetClassList().push_back( aClass.get() );
|
|
}
|
|
|
|
void SvIdlParser::ReadInterfaceOrShellEntry(SvMetaClass& rClass)
|
|
{
|
|
if( ReadIf( SvHash_import() ) )
|
|
{
|
|
SvMetaClass * pClass = ReadKnownClass();
|
|
SvClassElement aEle(pClass);
|
|
SvToken& rTok = rInStm.GetToken();
|
|
if( rTok.IsString() )
|
|
{
|
|
aEle.SetPrefix( rTok.GetString() );
|
|
rInStm.GetToken_Next();
|
|
}
|
|
rClass.aClassElementList.push_back( aEle );
|
|
}
|
|
else
|
|
{
|
|
SvMetaType * pType = rBase.ReadKnownType( rInStm );
|
|
tools::SvRef<SvMetaAttribute> xAttr;
|
|
bool bOk = false;
|
|
if( !pType || pType->IsItem() )
|
|
{
|
|
xAttr = new SvMetaSlot( pType );
|
|
bOk = ReadSlot(static_cast<SvMetaSlot&>(*xAttr));
|
|
}
|
|
else
|
|
{
|
|
xAttr = new SvMetaAttribute( pType );
|
|
ReadInterfaceOrShellMethod(*xAttr);
|
|
bOk = true;
|
|
}
|
|
if( bOk )
|
|
bOk = xAttr->Test( rInStm );
|
|
if( bOk )
|
|
bOk = rClass.TestAttribute( rBase, rInStm, *xAttr );
|
|
if( bOk )
|
|
{
|
|
if( !xAttr->GetSlotId().IsSet() )
|
|
xAttr->SetSlotId( SvIdentifier(rBase.GetUniqueId()) );
|
|
rClass.aAttrList.push_back( xAttr.get() );
|
|
}
|
|
}
|
|
}
|
|
|
|
bool SvIdlParser::ReadSlot(SvMetaSlot& rSlot)
|
|
{
|
|
sal_uInt32 nTokPos = rInStm.Tell();
|
|
bool bOk = true;
|
|
|
|
SvMetaAttribute * pAttr = rBase.ReadKnownAttr( rInStm, rSlot.GetType() );
|
|
if( pAttr )
|
|
{
|
|
SvMetaSlot * pKnownSlot = dynamic_cast<SvMetaSlot*>( pAttr );
|
|
if( !pKnownSlot )
|
|
throw SvParseException( rInStm, "attribute " + pAttr->GetName() + " is method or variable but not a slot" );
|
|
rSlot.SetRef( pKnownSlot );
|
|
rSlot.SetName( pKnownSlot->GetName() );
|
|
if( ReadIf( '[' ) )
|
|
{
|
|
sal_uInt32 nBeginPos = 0; // can not happen with Tell
|
|
while( nBeginPos != rInStm.Tell() )
|
|
{
|
|
nBeginPos = rInStm.Tell();
|
|
ReadSlotAttribute(rSlot);
|
|
ReadIfDelimiter();
|
|
}
|
|
Read( ']' );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bOk = rSlot.SvMetaAttribute::ReadSvIdl( rBase, rInStm );
|
|
SvMetaAttribute *pAttr2 = rBase.FindKnownAttr( rSlot.GetSlotId() );
|
|
if( pAttr2 )
|
|
{
|
|
SvMetaSlot * pKnownSlot = dynamic_cast<SvMetaSlot*>( pAttr2 );
|
|
if( !pKnownSlot )
|
|
throw SvParseException( rInStm, "attribute " + pAttr2->GetName() + " is method or variable but not a slot" );
|
|
rSlot.SetRef( pKnownSlot );
|
|
// names may differ, because explicitly given
|
|
if ( pKnownSlot->GetName() != rSlot.GetName() )
|
|
throw SvParseException( rInStm, "Illegal definition!"_ostr );
|
|
}
|
|
}
|
|
|
|
if( !bOk )
|
|
rInStm.Seek( nTokPos );
|
|
|
|
return bOk;
|
|
}
|
|
|
|
void SvIdlParser::ReadSlotAttribute( SvMetaSlot& rSlot )
|
|
{
|
|
ReadIfIdAttribute(rSlot.aGroupId, SvHash_GroupId() );
|
|
ReadIfIdAttribute(rSlot.aExecMethod, SvHash_ExecMethod() );
|
|
ReadIfIdAttribute(rSlot.aStateMethod, SvHash_StateMethod() );
|
|
ReadStringSvIdl( SvHash_DisableFlags(), rInStm, rSlot.aDisableFlags );
|
|
ReadIfBoolAttribute(rSlot.aReadOnlyDoc, SvHash_ReadOnlyDoc() );
|
|
|
|
ReadIfBoolAttribute(rSlot.aToggle, SvHash_Toggle() );
|
|
ReadIfBoolAttribute(rSlot.aAutoUpdate, SvHash_AutoUpdate() );
|
|
ReadIfBoolAttribute(rSlot.aAsynchron, SvHash_Asynchron() );
|
|
ReadIfBoolAttribute(rSlot.aRecordAbsolute, SvHash_RecordAbsolute() );
|
|
|
|
if( ReadIfBoolAttribute(rSlot.aRecordPerItem, SvHash_RecordPerItem()) )
|
|
{
|
|
if (rSlot.aRecordPerSet.IsSet() || rSlot.aNoRecord.IsSet())
|
|
throw SvParseException(rInStm, "conflicting attributes"_ostr);
|
|
rSlot.SetRecordPerItem( rSlot.aRecordPerItem );
|
|
}
|
|
if( ReadIfBoolAttribute(rSlot.aRecordPerSet, SvHash_RecordPerSet() ) )
|
|
{
|
|
if (rSlot.aRecordPerItem.IsSet() || rSlot.aNoRecord.IsSet())
|
|
throw SvParseException(rInStm, "conflicting attributes"_ostr);
|
|
rSlot.SetRecordPerSet( rSlot.aRecordPerSet );
|
|
}
|
|
if( ReadIfBoolAttribute(rSlot.aNoRecord, SvHash_NoRecord() ) )
|
|
{
|
|
if (rSlot.aRecordPerItem.IsSet() || rSlot.aRecordPerSet.IsSet())
|
|
throw SvParseException(rInStm, "conflicting attributes"_ostr);
|
|
rSlot.SetNoRecord( rSlot.aNoRecord );
|
|
}
|
|
|
|
ReadIfBoolAttribute(rSlot.aMenuConfig, SvHash_MenuConfig() );
|
|
ReadIfBoolAttribute(rSlot.aToolBoxConfig, SvHash_ToolBoxConfig() );
|
|
ReadIfBoolAttribute(rSlot.aAccelConfig, SvHash_AccelConfig() );
|
|
|
|
ReadIfBoolAttribute(rSlot.aFastCall, SvHash_FastCall() );
|
|
ReadIfBoolAttribute(rSlot.aContainer, SvHash_Container() );
|
|
}
|
|
|
|
void SvIdlParser::ReadInterfaceOrShellMethod( SvMetaAttribute& rAttr )
|
|
{
|
|
rAttr.SetName( ReadIdentifier() );
|
|
ReadSlotId( rAttr.aSlotId );
|
|
|
|
// read method arguments
|
|
Read( '(' );
|
|
tools::SvRef<SvMetaType> xT(new SvMetaType() );
|
|
xT->SetRef(rAttr.GetType() );
|
|
rAttr.aType = xT;
|
|
rAttr.aType->SetType( MetaTypeType::Method );
|
|
if (ReadIf(')'))
|
|
return;
|
|
|
|
while (true)
|
|
{
|
|
tools::SvRef<SvMetaAttribute> xParamAttr( new SvMetaAttribute() );
|
|
xParamAttr->aType = ReadKnownType();
|
|
xParamAttr->SetName( ReadIdentifier() );
|
|
ReadSlotId(xParamAttr->aSlotId);
|
|
rAttr.aType->GetAttrList().push_back( xParamAttr.get() );
|
|
if (!ReadIfDelimiter())
|
|
break;
|
|
}
|
|
Read(')');
|
|
}
|
|
|
|
void SvIdlParser::ReadSlotId(SvIdentifier& rSlotId)
|
|
{
|
|
rSlotId.setString( ReadIdentifier() );
|
|
sal_uInt32 n;
|
|
if( !rBase.FindId( rSlotId.getString(), &n ) )
|
|
throw SvParseException( rInStm, "no value for identifier <" + rSlotId.getString() + "> " );
|
|
rSlotId.SetValue(n);
|
|
}
|
|
|
|
SvMetaClass * SvIdlParser::ReadKnownClass()
|
|
{
|
|
OString aName(ReadIdentifier());
|
|
SvMetaClass* pClass = rBase.FindKnownClass( aName );
|
|
if( !pClass )
|
|
throw SvParseException( rInStm, "unknown class"_ostr );
|
|
return pClass;
|
|
}
|
|
|
|
SvMetaType * SvIdlParser::ReadKnownType()
|
|
{
|
|
OString aName = ReadIdentifier();
|
|
for( const auto& aType : rBase.GetTypeList() )
|
|
{
|
|
if( aType->GetName() == aName )
|
|
return aType;
|
|
}
|
|
throw SvParseException( rInStm, "wrong typedef: "_ostr);
|
|
}
|
|
|
|
bool SvIdlParser::ReadIfBoolAttribute( SvBOOL& rBool, SvStringHashEntry const * pName )
|
|
{
|
|
sal_uInt32 nTokPos = rInStm.Tell();
|
|
SvToken& rTok = rInStm.GetToken_Next();
|
|
|
|
if( rTok.Is( pName ) )
|
|
{
|
|
if( rInStm.ReadIf( '=' ) )
|
|
{
|
|
rTok = rInStm.GetToken();
|
|
if( !rTok.IsBool() )
|
|
throw SvParseException(rInStm, "xxx"_ostr);
|
|
rBool = rTok.GetBool();
|
|
rInStm.GetToken_Next();
|
|
}
|
|
else
|
|
rBool = true; //default action set to TRUE
|
|
return true;
|
|
}
|
|
rInStm.Seek( nTokPos );
|
|
return false;
|
|
}
|
|
|
|
void SvIdlParser::ReadIfIdAttribute( SvIdentifier& rIdentifier, SvStringHashEntry const * pName )
|
|
{
|
|
sal_uInt32 nTokPos = rInStm.Tell();
|
|
SvToken& rTok = rInStm.GetToken_Next();
|
|
|
|
if( rTok.Is( pName ) )
|
|
{
|
|
if( rInStm.ReadIf( '=' ) )
|
|
{
|
|
rTok = rInStm.GetToken();
|
|
if( !rTok.IsIdentifier() )
|
|
throw SvParseException(rInStm, "expected identifier"_ostr);
|
|
rIdentifier.setString(rTok.GetString());
|
|
rInStm.GetToken_Next();
|
|
}
|
|
}
|
|
else
|
|
rInStm.Seek( nTokPos );
|
|
}
|
|
|
|
void SvIdlParser::ReadDelimiter()
|
|
{
|
|
if( !ReadIfDelimiter() )
|
|
throw SvParseException(rInStm, "expected delimiter"_ostr);
|
|
}
|
|
|
|
bool SvIdlParser::ReadIfDelimiter()
|
|
{
|
|
if( rInStm.GetToken().IsChar()
|
|
&& (';' == rInStm.GetToken().GetChar()
|
|
|| ',' == rInStm.GetToken().GetChar()) )
|
|
{
|
|
rInStm.GetToken_Next();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
OString SvIdlParser::ReadIdentifier()
|
|
{
|
|
SvToken& rTok = rInStm.GetToken();
|
|
if( !rTok.IsIdentifier() )
|
|
throw SvParseException("expected identifier"_ostr, rTok);
|
|
rInStm.GetToken_Next();
|
|
return rTok.GetString();
|
|
}
|
|
|
|
OString SvIdlParser::ReadString()
|
|
{
|
|
SvToken& rTok = rInStm.GetToken();
|
|
if( !rTok.IsString() )
|
|
throw SvParseException("expected string"_ostr, rTok);
|
|
rInStm.GetToken_Next();
|
|
return rTok.GetString();
|
|
}
|
|
|
|
void SvIdlParser::Read(char cChar)
|
|
{
|
|
if( !ReadIf(cChar) )
|
|
throw SvParseException(rInStm, "expected char '" + OStringChar(cChar) + "'");
|
|
}
|
|
|
|
bool SvIdlParser::ReadIf(char cChar)
|
|
{
|
|
if( rInStm.GetToken().IsChar() && rInStm.GetToken().GetChar() == cChar )
|
|
{
|
|
rInStm.GetToken_Next();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void SvIdlParser::Read(SvStringHashEntry const * entry)
|
|
{
|
|
if( !rInStm.GetToken().Is(entry) )
|
|
throw SvParseException("expected " + entry->GetName(), rInStm.GetToken());
|
|
rInStm.GetToken_Next();
|
|
}
|
|
|
|
bool SvIdlParser::ReadIf(SvStringHashEntry const * entry)
|
|
{
|
|
if( rInStm.GetToken().Is(entry) )
|
|
{
|
|
rInStm.GetToken_Next();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|