2016-02-11 09:26:19 +02:00
|
|
|
/* -*- 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 <parser.hxx>
|
|
|
|
#include <database.hxx>
|
|
|
|
#include <globals.hxx>
|
|
|
|
#include <osl/file.hxx>
|
|
|
|
|
2016-02-11 11:41:21 +02:00
|
|
|
bool SvIdlParser::ReadSvIdl( bool bImported, const OUString & rPath )
|
2016-02-11 09:26:19 +02:00
|
|
|
{
|
|
|
|
rBase.SetPath(rPath); // only valid for this iteration
|
|
|
|
bool bOk = true;
|
2016-02-11 10:37:29 +02:00
|
|
|
SvToken& rTok = rInStm.GetToken();
|
2016-02-11 09:26:19 +02:00
|
|
|
|
2016-02-11 10:01:26 +02:00
|
|
|
while( bOk )
|
2016-02-11 09:26:19 +02:00
|
|
|
{
|
2016-02-11 10:37:29 +02:00
|
|
|
rTok = rInStm.GetToken();
|
|
|
|
if( rTok.IsEof() )
|
2016-02-11 09:26:19 +02:00
|
|
|
return true;
|
|
|
|
|
2016-02-11 10:37:29 +02:00
|
|
|
if( rTok.Is( SvHash_module() ) )
|
2016-02-11 09:26:19 +02:00
|
|
|
{
|
|
|
|
tools::SvRef<SvMetaModule> aModule = new SvMetaModule( bImported );
|
2016-02-11 15:41:48 +02:00
|
|
|
if( ReadModuleHeader(*aModule) )
|
2016-02-11 09:26:19 +02:00
|
|
|
rBase.GetModuleList().push_back( aModule );
|
|
|
|
else
|
|
|
|
bOk = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bOk = false;
|
|
|
|
}
|
2016-02-11 10:37:29 +02:00
|
|
|
if( !bOk || !rTok.IsEof() )
|
2016-02-11 09:26:19 +02:00
|
|
|
{
|
|
|
|
// error treatment
|
|
|
|
rBase.WriteError( rInStm );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-02-11 15:41:48 +02:00
|
|
|
bool SvIdlParser::ReadModuleHeader(SvMetaModule& rModule)
|
2016-02-11 15:19:50 +02:00
|
|
|
{
|
2016-02-11 15:41:48 +02:00
|
|
|
sal_uInt32 nTokPos = rInStm.Tell();
|
|
|
|
SvToken& rTok = rInStm.GetToken_Next();
|
|
|
|
bool bOk = true;
|
|
|
|
|
|
|
|
rTok = rInStm.GetToken_Next();
|
|
|
|
if( !rTok.IsIdentifier() )
|
|
|
|
{
|
|
|
|
rInStm.Seek( nTokPos );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
rBase.Push( &rModule ); // onto the context stack
|
|
|
|
rModule.SetName( rTok.GetString() );
|
|
|
|
bOk = ReadModuleBody(rModule);
|
|
|
|
rBase.GetStack().pop_back(); // remove from stack
|
|
|
|
if( !bOk )
|
|
|
|
rInStm.Seek( nTokPos );
|
|
|
|
return bOk;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SvIdlParser::ReadModuleBody(SvMetaModule& rModule)
|
|
|
|
{
|
|
|
|
sal_uInt32 nTokPos = rInStm.Tell();
|
2016-02-11 15:19:50 +02:00
|
|
|
bool bOk = true;
|
2016-02-11 15:41:48 +02:00
|
|
|
if( rInStm.ReadIf( '[' ) )
|
2016-02-11 15:19:50 +02:00
|
|
|
{
|
2016-02-12 08:58:26 +02:00
|
|
|
while( true )
|
2016-02-11 15:19:50 +02:00
|
|
|
{
|
2016-02-11 15:41:48 +02:00
|
|
|
OString aSlotIdFile;
|
2016-02-12 08:58:26 +02:00
|
|
|
if( !ReadStringSvIdl( SvHash_SlotIdFile(), rInStm, aSlotIdFile ) )
|
|
|
|
break;
|
|
|
|
if( !rBase.ReadIdFile( OStringToOUString(aSlotIdFile, RTL_TEXTENCODING_ASCII_US)) )
|
2016-02-11 15:41:48 +02:00
|
|
|
{
|
2016-02-12 08:58:26 +02:00
|
|
|
throw SvParseException( rInStm, "cannot read file: " + aSlotIdFile );
|
2016-02-11 15:19:50 +02:00
|
|
|
}
|
2016-02-11 15:41:48 +02:00
|
|
|
rInStm.ReadIfDelimiter();
|
2016-02-11 15:19:50 +02:00
|
|
|
}
|
2016-02-12 08:58:26 +02:00
|
|
|
ReadChar( ']' );
|
2016-02-11 15:41:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if( !rInStm.ReadIf( '{' ) )
|
|
|
|
return bOk;
|
|
|
|
|
2016-02-12 08:58:26 +02:00
|
|
|
sal_uInt32 nBeginPos = 0;
|
2016-02-11 15:41:48 +02:00
|
|
|
while( nBeginPos != rInStm.Tell() )
|
|
|
|
{
|
|
|
|
nBeginPos = rInStm.Tell();
|
|
|
|
ReadModuleElement( rModule );
|
|
|
|
rInStm.ReadIfDelimiter();
|
|
|
|
}
|
2016-02-12 08:58:26 +02:00
|
|
|
ReadChar( '}' );
|
2016-02-11 15:41:48 +02:00
|
|
|
|
|
|
|
if( !bOk )
|
|
|
|
rInStm.Seek( nTokPos );
|
2016-02-11 15:19:50 +02:00
|
|
|
return bOk;
|
|
|
|
}
|
2016-02-11 15:41:48 +02:00
|
|
|
|
|
|
|
void SvIdlParser::ReadModuleElement( SvMetaModule& rModule )
|
|
|
|
{
|
|
|
|
sal_uInt32 nTokPos = rInStm.Tell();
|
|
|
|
if( rInStm.GetToken().Is( SvHash_interface() )
|
|
|
|
|| rInStm.GetToken().Is( SvHash_shell() ) )
|
|
|
|
{
|
|
|
|
tools::SvRef<SvMetaClass> aClass( new SvMetaClass() );
|
|
|
|
if( aClass->ReadSvIdl( rBase, rInStm ) )
|
|
|
|
{
|
|
|
|
rModule.aClassList.push_back( aClass );
|
|
|
|
// announce globally
|
|
|
|
rBase.GetClassList().push_back( aClass );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( rInStm.GetToken().Is( SvHash_enum() ) )
|
|
|
|
{
|
|
|
|
tools::SvRef<SvMetaTypeEnum> aEnum( new SvMetaTypeEnum() );
|
|
|
|
|
2016-02-12 08:58:26 +02:00
|
|
|
ReadEnum(*aEnum);
|
|
|
|
// announce globally
|
|
|
|
rBase.GetTypeList().push_back( aEnum );
|
2016-02-11 15:41:48 +02:00
|
|
|
}
|
|
|
|
else if( rInStm.GetToken().Is( SvHash_item() )
|
|
|
|
|| rInStm.GetToken().Is( SvHash_struct() ) )
|
|
|
|
{
|
|
|
|
tools::SvRef<SvMetaType> xItem(new SvMetaType() );
|
|
|
|
|
|
|
|
if( xItem->ReadSvIdl( rBase, rInStm ) )
|
|
|
|
{
|
|
|
|
// announce globally
|
|
|
|
rBase.GetTypeList().push_back( xItem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( rInStm.GetToken().Is( SvHash_include() ) )
|
|
|
|
{
|
|
|
|
bool bOk = false;
|
|
|
|
rInStm.GetToken_Next();
|
|
|
|
SvToken& rTok = rInStm.GetToken_Next();
|
|
|
|
if( rTok.IsString() )
|
|
|
|
{
|
|
|
|
OUString aFullName(OStringToOUString(rTok.GetString(), RTL_TEXTENCODING_ASCII_US));
|
|
|
|
rBase.StartNewFile( aFullName );
|
|
|
|
osl::FileBase::RC searchError = osl::File::searchFileURL(aFullName, rBase.GetPath(), aFullName);
|
|
|
|
if( osl::FileBase::E_None != searchError )
|
|
|
|
{
|
|
|
|
OStringBuffer aStr("cannot find file:");
|
|
|
|
aStr.append(OUStringToOString(aFullName, RTL_TEXTENCODING_UTF8));
|
|
|
|
throw SvParseException(aStr.makeStringAndClear(), rTok);
|
|
|
|
}
|
|
|
|
osl::FileBase::getSystemPathFromFileURL( aFullName, aFullName );
|
|
|
|
rBase.AddDepFile( aFullName );
|
|
|
|
SvTokenStream aTokStm( aFullName );
|
|
|
|
|
|
|
|
if( SVSTREAM_OK != aTokStm.GetStream().GetError() )
|
|
|
|
{
|
|
|
|
OStringBuffer aStr("cannot open file: ");
|
|
|
|
aStr.append(OUStringToOString(aFullName, RTL_TEXTENCODING_UTF8));
|
|
|
|
throw SvParseException(aStr.makeStringAndClear(), rTok);
|
|
|
|
}
|
|
|
|
// rescue error from old file
|
|
|
|
SvIdlError aOldErr = rBase.GetError();
|
|
|
|
// reset error
|
|
|
|
rBase.SetError( SvIdlError() );
|
|
|
|
|
2016-02-12 08:58:26 +02:00
|
|
|
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);
|
2016-02-11 15:41:48 +02:00
|
|
|
}
|
|
|
|
bOk = aTokStm.GetToken().IsEof();
|
|
|
|
if( !bOk )
|
|
|
|
{
|
|
|
|
rBase.WriteError( aTokStm );
|
|
|
|
}
|
|
|
|
// recover error from old file
|
|
|
|
rBase.SetError( aOldErr );
|
|
|
|
}
|
|
|
|
if( !bOk )
|
|
|
|
rInStm.Seek( nTokPos );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tools::SvRef<SvMetaSlot> xSlot( new SvMetaSlot() );
|
|
|
|
|
|
|
|
if( xSlot->ReadSvIdl( rBase, rInStm ) )
|
|
|
|
{
|
|
|
|
if( xSlot->Test( rInStm ) )
|
|
|
|
{
|
|
|
|
// announce globally
|
|
|
|
rBase.AppendSlot( xSlot );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-12 08:58:26 +02:00
|
|
|
void SvIdlParser::ReadEnum(SvMetaTypeEnum& rEnum)
|
|
|
|
{
|
|
|
|
rInStm.GetToken_Next();
|
|
|
|
rEnum.SetType( MetaTypeType::Enum );
|
|
|
|
rEnum.SetName( ReadIdentifier() );
|
|
|
|
|
|
|
|
ReadChar('{');
|
|
|
|
while( true )
|
|
|
|
{
|
|
|
|
ReadEnumValue( rEnum );
|
|
|
|
if( !rInStm.ReadIfDelimiter() )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ReadChar( '}' );
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
OString getCommonSubPrefix(const OString &rA, const OString &rB)
|
|
|
|
{
|
|
|
|
sal_Int32 nMax = std::min(rA.getLength(), rB.getLength());
|
|
|
|
sal_Int32 nI = 0;
|
|
|
|
while (nI < nMax)
|
|
|
|
{
|
|
|
|
if (rA[nI] != rB[nI])
|
|
|
|
break;
|
|
|
|
++nI;
|
|
|
|
}
|
|
|
|
return rA.copy(0, nI);
|
|
|
|
}
|
|
|
|
}
|
2016-02-11 15:41:48 +02:00
|
|
|
|
|
|
|
|
2016-02-12 08:58:26 +02:00
|
|
|
void SvIdlParser::ReadEnumValue( SvMetaTypeEnum& rEnum )
|
|
|
|
{
|
|
|
|
sal_uInt32 nTokPos = rInStm.Tell();
|
|
|
|
|
|
|
|
tools::SvRef<SvMetaEnumValue> aEnumVal = new SvMetaEnumValue();
|
|
|
|
bool bOk = aEnumVal->ReadSvIdl( rBase, rInStm );
|
|
|
|
if( bOk )
|
|
|
|
{
|
|
|
|
if( rEnum.aEnumValueList.empty() )
|
|
|
|
{
|
|
|
|
// the first
|
|
|
|
rEnum.aPrefix = aEnumVal->GetName();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rEnum.aPrefix = getCommonSubPrefix(rEnum.aPrefix, aEnumVal->GetName());
|
|
|
|
}
|
|
|
|
rEnum.aEnumValueList.push_back( aEnumVal );
|
|
|
|
}
|
|
|
|
if( !bOk )
|
|
|
|
rInStm.Seek( nTokPos );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SvIdlParser::ReadChar(char cChar)
|
|
|
|
{
|
|
|
|
if( !rInStm.ReadIf( cChar ) )
|
|
|
|
throw SvParseException(rInStm, "expected char '" + OString(cChar) + "'");
|
|
|
|
}
|
|
|
|
|
|
|
|
void SvIdlParser::ReadDelimiter()
|
|
|
|
{
|
|
|
|
if( !rInStm.ReadIfDelimiter() )
|
|
|
|
throw SvParseException(rInStm, "expected delimiter");
|
|
|
|
}
|
|
|
|
|
|
|
|
OString SvIdlParser::ReadIdentifier()
|
|
|
|
{
|
|
|
|
SvToken& rTok = rInStm.GetToken_Next();
|
|
|
|
if( !rTok.IsIdentifier() )
|
|
|
|
throw SvParseException("expected identifier", rTok);
|
|
|
|
return rTok.GetString();
|
|
|
|
}
|
2016-02-11 09:26:19 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|