diff options
Diffstat (limited to '')
-rw-r--r-- | idl/source/cmptools/hash.cxx | 65 | ||||
-rw-r--r-- | idl/source/cmptools/lex.cxx | 336 | ||||
-rw-r--r-- | idl/source/objects/basobj.cxx | 141 | ||||
-rw-r--r-- | idl/source/objects/bastype.cxx | 120 | ||||
-rw-r--r-- | idl/source/objects/module.cxx | 34 | ||||
-rw-r--r-- | idl/source/objects/object.cxx | 347 | ||||
-rw-r--r-- | idl/source/objects/slot.cxx | 620 | ||||
-rw-r--r-- | idl/source/objects/types.cxx | 320 | ||||
-rw-r--r-- | idl/source/prj/command.cxx | 296 | ||||
-rw-r--r-- | idl/source/prj/database.cxx | 553 | ||||
-rw-r--r-- | idl/source/prj/globals.cxx | 84 | ||||
-rw-r--r-- | idl/source/prj/parser.cxx | 590 | ||||
-rw-r--r-- | idl/source/prj/svidl.cxx | 213 |
13 files changed, 3719 insertions, 0 deletions
diff --git a/idl/source/cmptools/hash.cxx b/idl/source/cmptools/hash.cxx new file mode 100644 index 000000000..d3993881a --- /dev/null +++ b/idl/source/cmptools/hash.cxx @@ -0,0 +1,65 @@ +/* -*- 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 . + */ + + +// program-sensitive includes +#include <hash.hxx> + +SvStringHashEntry * SvStringHashTable::Insert( const OString& rElement, sal_uInt32 * pInsertPos ) +{ + auto it = maString2IntMap.find(rElement); + if (it != maString2IntMap.end()) { + *pInsertPos = it->second; + return maInt2EntryMap[*pInsertPos].get(); + } + maString2IntMap[rElement] = mnNextId; + maInt2EntryMap[mnNextId] = std::make_unique<SvStringHashEntry>(rElement); + *pInsertPos = mnNextId; + mnNextId++; + return maInt2EntryMap[*pInsertPos].get(); +} + +bool SvStringHashTable::Test( const OString& rElement, sal_uInt32 * pInsertPos ) +{ + auto it = maString2IntMap.find(rElement); + if (it != maString2IntMap.end()) { + *pInsertPos = it->second; + return true; + } + return false; +} + +SvStringHashEntry * SvStringHashTable::Get( sal_uInt32 nInsertPos ) const +{ + auto it = maInt2EntryMap.find(nInsertPos); + return it->second.get(); +} + +OString SvStringHashTable::GetNearString( std::string_view rName ) const +{ + for( auto const & rPair : maInt2EntryMap ) + { + SvStringHashEntry * pE = rPair.second.get(); + if( pE->GetName().equalsIgnoreAsciiCase( rName ) && pE->GetName() != rName ) + return pE->GetName(); + } + return OString(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/cmptools/lex.cxx b/idl/source/cmptools/lex.cxx new file mode 100644 index 000000000..eb9ad1170 --- /dev/null +++ b/idl/source/cmptools/lex.cxx @@ -0,0 +1,336 @@ +/* -*- 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 <memory> +#include <hash.hxx> +#include <lex.hxx> +#include <globals.hxx> +#include <rtl/strbuf.hxx> +#include<rtl/character.hxx> + +OString SvToken::GetTokenAsString() const +{ + OString aStr; + switch( nType ) + { + case SVTOKENTYPE::Empty: + break; + case SVTOKENTYPE::Comment: + aStr = aString; + break; + case SVTOKENTYPE::Integer: + aStr = OString::number(nLong); + break; + case SVTOKENTYPE::String: + aStr = aString; + break; + case SVTOKENTYPE::Bool: + aStr = bBool ? "TRUE" : "FALSE"; + break; + case SVTOKENTYPE::Identifier: + aStr = aString; + break; + case SVTOKENTYPE::Char: + aStr = OString(cChar); + break; + case SVTOKENTYPE::EndOfFile: + case SVTOKENTYPE::HashId: + break; + } + + return aStr; +} + +SvToken & SvToken::operator = ( const SvToken & rObj ) +{ + if( this != &rObj ) + { + nLine = rObj.nLine; + nColumn = rObj.nColumn; + nType = rObj.nType; + aString = rObj.aString; + nLong = rObj.nLong; + } + return *this; +} + +void SvTokenStream::InitCtor() +{ + aStrTrue = OString("TRUE"); + aStrFalse = OString("FALSE"); + nLine = nColumn = 0; + nBufPos = 0; + nMaxPos = 0; + c = GetNextChar(); + FillTokenList(); +} + +SvTokenStream::SvTokenStream( const OUString & rFileName ) + : pInStream( new SvFileStream( rFileName, StreamMode::STD_READ ) ) + , aFileName( rFileName ) +{ + InitCtor(); +} + +SvTokenStream::~SvTokenStream() +{ +} + +void SvTokenStream::FillTokenList() +{ + SvToken * pToken = new SvToken(); + aTokList.push_back(std::unique_ptr<SvToken>(pToken)); + do + { + if( !MakeToken( *pToken ) ) + { + if (!aTokList.empty()) + { + *pToken = SvToken(); + std::vector<std::unique_ptr<SvToken> >::const_iterator it = aTokList.begin(); + + pToken->SetLine((*it)->GetLine()); + pToken->SetColumn((*it)->GetColumn()); + } + break; + } + else if( pToken->IsComment() ) + *pToken = SvToken(); + else if( pToken->IsEof() ) + break; + else + { + pToken = new SvToken(); + aTokList.push_back(std::unique_ptr<SvToken>(pToken)); + } + } + while( !pToken->IsEof() ); + pCurToken = aTokList.begin(); +} + +char SvTokenStream::GetNextChar() +{ + char nChar; + while (aBufStr.getLength() <= nBufPos) + { + if (pInStream->ReadLine(aBufStr)) + { + nLine++; + nColumn = 0; + nBufPos = 0; + } + else + { + aBufStr.clear(); + nColumn = 0; + nBufPos = 0; + return '\0'; + } + } + nChar = aBufStr[nBufPos++]; + nColumn += nChar == '\t' ? nTabSize : 1; + return nChar; +} + +sal_uInt64 SvTokenStream::GetNumber() +{ + sal_uInt64 l = 0; + short nLog = 10; + + if( '0' == c ) + { + c = GetFastNextChar(); + if( 'x' == c ) + { + nLog = 16; + c = GetFastNextChar(); + } + } + + if( nLog == 16 ) + { + while( rtl::isAsciiHexDigit( static_cast<unsigned char>(c) ) ) + { + if( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) ) + l = l * nLog + (c - '0'); + else + l = l * nLog + + (rtl::toAsciiUpperCase( static_cast<unsigned char>(c) ) + - 'A' + 10 ); + c = GetFastNextChar(); + } + } + else + { + while( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) || 'x' == c ) + { + l = l * nLog + (c - '0'); + c = GetFastNextChar(); + } + } + + return l; +} + +bool SvTokenStream::MakeToken( SvToken & rToken ) +{ + do + { + if( 0 == c ) + c = GetNextChar(); + // skip whitespace + while( rtl::isAsciiWhiteSpace( static_cast<unsigned char>(c) ) + || 26 == c ) + { + c = GetFastNextChar(); + nColumn += c == '\t' ? nTabSize : 1; + } + } + while( 0 == c && !IsEof() && ( ERRCODE_NONE == pInStream->GetError() ) ); + + sal_uInt64 nLastLine = nLine; + sal_uInt64 nLastColumn = nColumn; + // comment + if( '/' == c ) + { + // time optimization, no comments + char c1 = c; + c = GetFastNextChar(); + if( '/' == c ) + { + while( '\0' != c ) + { + c = GetFastNextChar(); + } + c = GetNextChar(); + rToken.nType = SVTOKENTYPE::Comment; + } + else if( '*' == c ) + { + c = GetFastNextChar(); + do + { + while( '*' != c ) + { + if( '\0' == c ) + { + c = GetNextChar(); + if( IsEof() ) + return false; + } + else + c = GetFastNextChar(); + } + c = GetFastNextChar(); + } + while( '/' != c && !IsEof() && ( ERRCODE_NONE == pInStream->GetError() ) ); + if( IsEof() || ( ERRCODE_NONE != pInStream->GetError() ) ) + return false; + c = GetNextChar(); + rToken.nType = SVTOKENTYPE::Comment; + CalcColumn(); + } + else + { + rToken.nType = SVTOKENTYPE::Char; + rToken.cChar = c1; + } + } + else if( c == '"' ) + { + OStringBuffer aStr(128); + bool bDone = false; + while( !bDone && !IsEof() && c ) + { + c = GetFastNextChar(); + if( '\0' == c ) + { + // read strings beyond end of line + aStr.append('\n'); + c = GetNextChar(); + if( IsEof() ) + return false; + } + if( c == '"' ) + { + c = GetFastNextChar(); + bDone = true; + } + else + aStr.append(c); + } + if( IsEof() || ( ERRCODE_NONE != pInStream->GetError() ) ) + return false; + rToken.nType = SVTOKENTYPE::String; + rToken.aString = aStr.makeStringAndClear(); + } + else if( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) ) + { + rToken.nType = SVTOKENTYPE::Integer; + rToken.nLong = GetNumber(); + + } + else if( rtl::isAsciiAlpha (static_cast<unsigned char>(c)) || (c == '_') ) + { + OStringBuffer aBuf(64); + while( rtl::isAsciiAlphanumeric( static_cast<unsigned char>(c) ) + || c == '_' || c == ':') + { + aBuf.append(c); + c = GetFastNextChar(); + } + OString aStr = aBuf.makeStringAndClear(); + if( aStr.equalsIgnoreAsciiCase( aStrTrue ) ) + { + rToken.nType = SVTOKENTYPE::Bool; + rToken.bBool = true; + } + else if( aStr.equalsIgnoreAsciiCase( aStrFalse ) ) + { + rToken.nType = SVTOKENTYPE::Bool; + rToken.bBool = false; + } + else + { + sal_uInt32 nHashId; + if( GetIdlApp().pHashTable->Test( aStr, &nHashId ) ) + rToken.SetHash( GetIdlApp().pHashTable->Get( nHashId ) ); + else + { + rToken.nType = SVTOKENTYPE::Identifier; + rToken.aString = aStr; + } + } + } + else if( IsEof() ) + { + rToken.nType = SVTOKENTYPE::EndOfFile; + } + else + { + rToken.nType = SVTOKENTYPE::Char; + rToken.cChar = c; + c = GetFastNextChar(); + } + rToken.SetLine( nLastLine ); + rToken.SetColumn( nLastColumn ); + return pInStream->GetError() == ERRCODE_NONE; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/basobj.cxx b/idl/source/objects/basobj.cxx new file mode 100644 index 000000000..872b42b39 --- /dev/null +++ b/idl/source/objects/basobj.cxx @@ -0,0 +1,141 @@ +/* -*- 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 <rtl/character.hxx> + +#include <basobj.hxx> +#include <database.hxx> + +void SvMetaObject::WriteTab( SvStream & rOutStm, sal_uInt16 nTab ) +{ + while( nTab-- ) + rOutStm.WriteCharPtr( " " ); +} + +void SvMetaObject::WriteStars( SvStream & rOutStm ) +{ + rOutStm.WriteChar( '/' ); + for( int i = 6; i > 0; i-- ) + rOutStm.WriteCharPtr( "**********" ); + rOutStm.WriteChar( '/' ) << endl; +} + +void SvMetaObject::Back2Delimiter( SvStream & rOutStm ) +{ + // write no empty brackets + sal_uInt64 nPos = rOutStm.Tell(); + rOutStm.SeekRel( -1 ); + char c = 0; + rOutStm.ReadChar( c ); + + while( rtl::isAsciiWhiteSpace( static_cast<unsigned char>(c) ) + && rOutStm.Tell() != 1 ) + { + rOutStm.SeekRel( -2 ); + rOutStm.ReadChar( c ); + } + + if( c == ';' || c == ',' ) + rOutStm.SeekRel( -1 ); + else + rOutStm.Seek( nPos ); +} + +SvMetaObject::SvMetaObject() +{ +} + +void SvMetaObject::SetName( const OString& rName ) +{ + aName = rName; +} + +bool SvMetaObject::ReadNameSvIdl( SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + // read module name + if( rTok.IsIdentifier() ) + { + SetName( rTok.GetString() ); + return true; + } + + rInStm.Seek( nTokPos ); + return false; +} + +void SvMetaObject::ReadAttributesSvIdl( SvIdlDataBase & , + SvTokenStream & ) +{ +} + +void SvMetaObject::DoReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nBeginPos = 0; // can not happen with Tell + while( nBeginPos != rInStm.Tell() ) + { + nBeginPos = rInStm.Tell(); + ReadContextSvIdl( rBase, rInStm ); + rInStm.ReadIfDelimiter(); + } +} + +void SvMetaObject::ReadContextSvIdl( SvIdlDataBase &, SvTokenStream & ) +{ +} + +bool SvMetaObject::ReadSvIdl( SvIdlDataBase & rBase, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + bool bOk = true; + if( rInStm.ReadIf( '[' ) ) + { + sal_uInt32 nBeginPos = 0; // can not happen with Tell + while( nBeginPos != rInStm.Tell() ) + { + nBeginPos = rInStm.Tell(); + ReadAttributesSvIdl( rBase, rInStm ); + rInStm.ReadIfDelimiter(); + } + bOk = rInStm.ReadIf( ']' ); + } + + if( bOk && rInStm.ReadIf( '{' ) ) + { + DoReadContextSvIdl( rBase, rInStm ); + bOk = rInStm.ReadIf( '}' ); + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + return bOk; +} + + +SvMetaReference::SvMetaReference() +{ +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/bastype.cxx b/idl/source/objects/bastype.cxx new file mode 100644 index 000000000..6a36db617 --- /dev/null +++ b/idl/source/objects/bastype.cxx @@ -0,0 +1,120 @@ +/* -*- 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 <bastype.hxx> +#include <lex.hxx> +#include <hash.hxx> +#include <database.hxx> + +bool SvBOOL::ReadSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm ) +{ + 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"); + *this = rTok.GetBool(); + rInStm.GetToken_Next(); + } + else + *this = true; //default action set to TRUE + return true; + } + rInStm.Seek( nTokPos ); + return false; +} + +void SvIdentifier::ReadSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + bool bOk = true; + bool bBracket = rInStm.ReadIf( '(' ); + if( bBracket || rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( rTok.IsIdentifier() ) + { + setString(rTok.GetString()); + rInStm.GetToken_Next(); + } + if( bOk && bBracket ) + bOk = rInStm.ReadIf( ')' ); + } + if( bOk ) + return; + } + rInStm.Seek( nTokPos ); +} + +void SvIdentifier::ReadSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.IsIdentifier() ) + { + sal_uInt32 n; + if( !rBase.FindId( rTok.GetString(), &n ) ) + rBase.SetAndWriteError( rInStm, "no value for identifier <" + getString() + "> " ); + setString(rTok.GetString()); + nValue = n; + return; + } + rInStm.Seek( nTokPos ); +} + +bool ReadStringSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm, OString& aRetString ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + bool bOk = true; + bool bBracket = rInStm.ReadIf( '(' ); + if( bBracket || rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( rTok.IsString() ) + { + aRetString = rTok.GetString(); + rInStm.GetToken_Next(); + } + if( bOk && bBracket ) + bOk = rInStm.ReadIf( ')' ); + } + if( bOk ) + return true; + } + rInStm.Seek( nTokPos ); + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/module.cxx b/idl/source/objects/module.cxx new file mode 100644 index 000000000..dc692f608 --- /dev/null +++ b/idl/source/objects/module.cxx @@ -0,0 +1,34 @@ +/* -*- 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 <module.hxx> +#include <database.hxx> + +SvMetaModule::SvMetaModule() {} + +void SvMetaModule::WriteSfx(SvIdlDataBase& rBase, SvStream& rOutStm) +{ + for (size_t n = 0; n < aClassList.size(); n++) + { + SvMetaClass* pClass = aClassList[n]; + pClass->WriteSfx(rBase, rOutStm); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/object.cxx b/idl/source/objects/object.cxx new file mode 100644 index 000000000..510d3a8a7 --- /dev/null +++ b/idl/source/objects/object.cxx @@ -0,0 +1,347 @@ +/* -*- 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 <rtl/strbuf.hxx> +#include <sal/log.hxx> + +#include <object.hxx> +#include <globals.hxx> +#include <database.hxx> +#include <slot.hxx> + + +SvClassElement::SvClassElement() +{ +}; + +SvMetaClass::SvMetaClass() +{ +} + +void SvMetaClass::ReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( SvHash_import() ) ) + { + SvMetaClass * pClass = rBase.ReadKnownClass( rInStm ); + if( !pClass ) + throw SvParseException( rInStm, "unknown imported interface" ); + SvClassElement aEle; + aEle.SetClass( pClass ); + aClassElementList.push_back( aEle ); + + rTok = rInStm.GetToken(); + if( rTok.IsString() ) + { + aEle.SetPrefix( rTok.GetString() ); + rInStm.GetToken_Next(); + } + return; + } + else + { + rInStm.Seek( nTokPos ); + SvMetaType * pType = rBase.ReadKnownType( rInStm ); + + bool bOk = false; + tools::SvRef<SvMetaAttribute> xAttr; + if( !pType || pType->IsItem() ) + { + xAttr = new SvMetaSlot( pType ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + bOk = xAttr->Test( rInStm ); + } + else + { + xAttr = new SvMetaAttribute( pType ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + bOk = xAttr->Test( rInStm ); + } + + if( bOk ) + bOk = TestAttribute( rBase, rInStm, *xAttr ); + if( bOk ) + { + if( !xAttr->GetSlotId().IsSet() ) + { + SvIdentifier aI; + aI.SetValue( rBase.GetUniqueId() ); + xAttr->SetSlotId( aI ); + } + aAttrList.push_back( xAttr.get() ); + return; + } + } + rInStm.Seek( nTokPos ); +} + +bool SvMetaClass::TestAttribute( SvIdlDataBase & rBase, SvTokenStream & rInStm, + SvMetaAttribute & rAttr ) const +{ + if ( !rAttr.GetRef() && dynamic_cast<const SvMetaSlot *>(&rAttr) ) + { + SAL_WARN( "idl", "new slot : " << rAttr.GetSlotId().getString() ); + } + + for( size_t n = 0; n < aAttrList.size(); n++ ) + { + SvMetaAttribute * pS = aAttrList[n]; + if( pS->GetName() == rAttr.GetName() ) + { + // values have to match + if( pS->GetSlotId().GetValue() != rAttr.GetSlotId().GetValue() ) + { + throw SvParseException( rInStm, "Attribute's " + pS->GetName() + " with different id's"); + } + } + else + { + sal_uInt32 nId1 = pS->GetSlotId().GetValue(); + sal_uInt32 nId2 = rAttr.GetSlotId().GetValue(); + if( nId1 == nId2 && nId1 != 0 ) + { + OString aStr = "Attribute " + pS->GetName() + " and Attribute " + rAttr.GetName() + " with equal id's"; + throw SvParseException(rInStm, aStr); + } + } + } + SvMetaClass * pSC = aSuperClass.get(); + if( pSC ) + return pSC->TestAttribute( rBase, rInStm, rAttr ); + return true; +} + +sal_uInt16 SvMetaClass::WriteSlotParamArray( SvIdlDataBase & rBase, + SvSlotElementList & rSlotList, + SvStream & rOutStm ) +{ + sal_uInt16 nCount = 0; + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pAttr = rSlotList[ i ]; + nCount = nCount + pAttr->WriteSlotParamArray( rBase, rOutStm ); + } + + return nCount; +} + +sal_uInt16 SvMetaClass::WriteSlots( std::string_view rShellName, + SvSlotElementList & rSlotList, + SvIdlDataBase & rBase, + SvStream & rOutStm ) +{ + sal_uInt16 nSCount = 0; + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot * pAttr = rSlotList[ i ]; + nSCount = nSCount + pAttr->WriteSlotMap( rShellName, nSCount, + rSlotList, i, rBase, + rOutStm ); + } + + return nSCount; +} + +void SvMetaClass::InsertSlots( SvSlotElementList& rList, std::vector<sal_uLong>& rSuperList, + SvMetaClassList &rClassList, + const OString& rPrefix, SvIdlDataBase& rBase) +{ + // was this class already written? + for ( size_t i = 0, n = rClassList.size(); i < n ; ++i ) + if ( rClassList[ i ] == this ) + return; + + rClassList.push_back( this ); + + // write all direct attributes + sal_uLong n; + for( n = 0; n < aAttrList.size(); n++ ) + { + SvMetaAttribute * pAttr = aAttrList[n]; + + sal_uLong nId = pAttr->GetSlotId().GetValue(); + + std::vector<sal_uLong>::iterator iter = std::find(rSuperList.begin(), + rSuperList.end(),nId); + + if( iter == rSuperList.end() ) + { + // Write only if not already written by subclass or + // imported interface. + rSuperList.push_back(nId); + pAttr->Insert(rList); + } + } + + // All Interfaces already imported by SuperShell should not be + // written any more. + // It is prohibited that Shell and SuperShell directly import the same + // class. + if( GetMetaTypeType() == MetaTypeType::Shell && aSuperClass.is() ) + aSuperClass->FillClasses( rClassList ); + + // Write all attributes of the imported classes, as long as they have + // not already been imported by the superclass. + for( n = 0; n < aClassElementList.size(); n++ ) + { + SvClassElement& rElement = aClassElementList[n]; + SvMetaClass * pCl = rElement.GetClass(); + OStringBuffer rPre(rPrefix.getLength() + 1 + rElement.GetPrefix().getLength()); + rPre.append(rPrefix); + if( !rPre.isEmpty() && !rElement.GetPrefix().isEmpty() ) + rPre.append('.'); + rPre.append(rElement.GetPrefix()); + + // first of all write direct imported interfaces + pCl->InsertSlots( rList, rSuperList, rClassList, + rPre.makeStringAndClear(), rBase ); + } + + // only write superclass if no shell and not in the list + if( GetMetaTypeType() != MetaTypeType::Shell && aSuperClass.is() ) + { + aSuperClass->InsertSlots( rList, rSuperList, rClassList, rPrefix, rBase ); + } +} + +void SvMetaClass::FillClasses( SvMetaClassList & rList ) +{ + // Am I not yet in? + for ( size_t i = 0, n = rList.size(); i < n; ++i ) + if ( rList[ i ] == this ) + return; + + rList.push_back( this ); + + // my imports + for( size_t n = 0; n < aClassElementList.size(); n++ ) + { + SvClassElement& rElement = aClassElementList[n]; + SvMetaClass * pCl = rElement.GetClass(); + pCl->FillClasses( rList ); + } + + // my superclass + if( aSuperClass.is() ) + aSuperClass->FillClasses( rList ); +} + + +void SvMetaClass::WriteSlotStubs( std::string_view rShellName, + SvSlotElementList & rSlotList, + std::vector<OString> & rList, + SvStream & rOutStm ) +{ + // write all attributes + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pAttr = rSlotList[ i ]; + pAttr->WriteSlotStubs( rShellName, rList, rOutStm ); + } +} + +void SvMetaClass::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + WriteStars( rOutStm ); + // define class + rOutStm.WriteCharPtr( "#ifdef ShellClass_" ).WriteOString( GetName() ) << endl; + rOutStm.WriteCharPtr( "#undef ShellClass" ) << endl; + rOutStm.WriteCharPtr( "#undef ShellClass_" ).WriteOString( GetName() ) << endl; + rOutStm.WriteCharPtr( "#define ShellClass " ).WriteOString( GetName() ) << endl; + + // no slotmaps get written for interfaces + if( GetMetaTypeType() != MetaTypeType::Shell ) + { + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; + return; + } + // write parameter array + rOutStm.WriteCharPtr("static SfxFormalArgument a").WriteOString(GetName()).WriteCharPtr("Args_Impl[] =") << endl; + rOutStm.WriteChar('{') << endl; + + std::vector<sal_uLong> aSuperList; + SvMetaClassList classList; + SvSlotElementList aSlotList; + InsertSlots(aSlotList, aSuperList, classList, OString(), rBase); + for ( size_t i = 0, n = aSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pSlot = aSlotList[ i ]; + pSlot->SetListPos( i ); + } + + size_t nSlotCount = aSlotList.size(); + + // write all attributes + sal_uInt16 nArgCount = WriteSlotParamArray( rBase, aSlotList, rOutStm ); + if( nArgCount ) + Back2Delimiter( rOutStm ); + else + { + // at least one dummy + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl; + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl << endl; + + std::vector<OString> aStringList; + WriteSlotStubs( GetName(), aSlotList, aStringList, rOutStm ); + aStringList.clear(); + + rOutStm << endl; + + // write slotmap + rOutStm.WriteCharPtr("static SfxSlot a").WriteOString(GetName()).WriteCharPtr("Slots_Impl[] =") << endl; + rOutStm.WriteChar( '{' ) << endl; + + // write all attributes + WriteSlots( GetName(), aSlotList, rBase, rOutStm ); + if( nSlotCount ) + Back2Delimiter( rOutStm ); + else + { + // at least one dummy + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr( "SFX_SLOT_ARG(" ).WriteOString( GetName() ) + .WriteCharPtr( ", 0, SfxGroupId::NONE, " ) + .WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE," ) + .WriteCharPtr( "SFX_STUB_PTR_STATE_NONE," ) + .WriteCharPtr( "SfxSlotMode::NONE, SfxVoidItem, 0, 0, \"\", SfxSlotMode::NONE )" ) << endl; + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; + + for( size_t i = 0, n = aSlotList.size(); i < n; ++i ) + { + SvMetaSlot* pAttr = aSlotList[ i ]; + pAttr->ResetSlotPointer(); + } + + aSlotList.clear(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/slot.cxx b/idl/source/objects/slot.cxx new file mode 100644 index 000000000..17b8970ed --- /dev/null +++ b/idl/source/objects/slot.cxx @@ -0,0 +1,620 @@ +/* -*- 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 <osl/diagnose.h> +#include <tools/debug.hxx> +#include <slot.hxx> +#include <globals.hxx> +#include <database.hxx> + + +SvMetaSlot::SvMetaSlot() + : aRecordPerSet( true ) + , aRecordAbsolute( false ) + , pNextSlot(nullptr) + , nListPos(0) + , aReadOnlyDoc ( true ) +{ +} + +SvMetaSlot::SvMetaSlot( SvMetaType * pType ) + : SvMetaAttribute( pType ) + , aRecordPerSet( true ) + , aRecordAbsolute( false ) + , pNextSlot(nullptr) + , nListPos(0) + , aReadOnlyDoc ( true ) +{ +} + +bool SvMetaSlot::GetReadOnlyDoc() const +{ + if( aReadOnlyDoc.IsSet() || !GetRef() ) return aReadOnlyDoc; + return static_cast<SvMetaSlot *>(GetRef())->GetReadOnlyDoc(); +} + +bool SvMetaSlot::IsVariable() const +{ + SvMetaType * pType = GetType(); + return pType->GetMetaTypeType() != MetaTypeType::Method; +} + +bool SvMetaSlot::IsMethod() const +{ + SvMetaType * pType = GetType(); + return pType->GetMetaTypeType() == MetaTypeType::Method; +} + +/************************************************************************* +|* reference +|* +|* description Second FALSE in the SvBOOL-Objects means +|* IsSet() provides FALSE (default initialization). +*************************************************************************/ +/** reference disbandment **/ +const OString& SvMetaSlot::GetGroupId() const +{ + if( !aGroupId.getString().isEmpty() || !GetRef() ) return aGroupId.getString(); + return static_cast<SvMetaSlot *>(GetRef())->GetGroupId(); +} +const OString& SvMetaSlot::GetDisableFlags() const +{ + if( !aDisableFlags.isEmpty() || !GetRef() ) return aDisableFlags; + return static_cast<SvMetaSlot *>(GetRef())->GetDisableFlags(); +} +const OString& SvMetaSlot::GetExecMethod() const +{ + if( !aExecMethod.getString().isEmpty() || !GetRef() ) return aExecMethod.getString(); + return static_cast<SvMetaSlot *>(GetRef())->GetExecMethod(); +} +const OString& SvMetaSlot::GetStateMethod() const +{ + if( !aStateMethod.getString().isEmpty() || !GetRef() ) return aStateMethod.getString(); + return static_cast<SvMetaSlot *>(GetRef())->GetStateMethod(); +} +bool SvMetaSlot::GetToggle() const +{ + if( aToggle.IsSet() || !GetRef() ) return aToggle; + return static_cast<SvMetaSlot *>(GetRef())->GetToggle(); +} +bool SvMetaSlot::GetAutoUpdate() const +{ + if( aAutoUpdate.IsSet() || !GetRef() ) return aAutoUpdate; + return static_cast<SvMetaSlot *>(GetRef())->GetAutoUpdate(); +} +bool SvMetaSlot::GetAsynchron() const +{ + // Synchron and Asynchron are exclusive + if( !GetRef() || aAsynchron.IsSet() ) + return aAsynchron; + return static_cast<SvMetaSlot *>(GetRef())->GetAsynchron(); +} +bool SvMetaSlot::GetRecordPerItem() const +{ + // Record- PerItem, No, PerSet and Manual are exclusive + if( !GetRef() || aRecordPerItem.IsSet() || aNoRecord.IsSet() + || aRecordPerSet.IsSet() ) + return aRecordPerItem; + return static_cast<SvMetaSlot *>(GetRef())->GetRecordPerItem(); +} +bool SvMetaSlot::GetRecordPerSet() const +{ + // Record- PerItem, No, PerSet and Manual are exclusive + if( !GetRef() || aRecordPerItem.IsSet() || aNoRecord.IsSet() + || aRecordPerSet.IsSet() ) + return aRecordPerSet; + return static_cast<SvMetaSlot *>(GetRef())->GetRecordPerSet(); +} +bool SvMetaSlot::GetNoRecord() const +{ + // Record- PerItem, No, PerSet and Manual are exclusive + if( !GetRef() || aRecordPerItem.IsSet() || aNoRecord.IsSet() + || aRecordPerSet.IsSet() ) + return aNoRecord; + return static_cast<SvMetaSlot *>(GetRef())->GetNoRecord(); +} +bool SvMetaSlot::GetRecordAbsolute() const +{ + if( !GetRef() || aRecordAbsolute.IsSet() ) + return aRecordAbsolute; + return static_cast<SvMetaSlot *>(GetRef())->GetRecordAbsolute(); +} +bool SvMetaSlot::GetMenuConfig() const +{ + if( aMenuConfig.IsSet() || !GetRef() ) return aMenuConfig; + return static_cast<SvMetaSlot *>(GetRef())->GetMenuConfig(); +} +bool SvMetaSlot::GetToolBoxConfig() const +{ + if( aToolBoxConfig.IsSet() || !GetRef() ) return aToolBoxConfig; + return static_cast<SvMetaSlot *>(GetRef())->GetToolBoxConfig(); +} +bool SvMetaSlot::GetAccelConfig() const +{ + if( aAccelConfig.IsSet() || !GetRef() ) return aAccelConfig; + return static_cast<SvMetaSlot *>(GetRef())->GetAccelConfig(); +} +bool SvMetaSlot::GetFastCall() const +{ + if( aFastCall.IsSet() || !GetRef() ) return aFastCall; + return static_cast<SvMetaSlot *>(GetRef())->GetFastCall(); +} +bool SvMetaSlot::GetContainer() const +{ + if( aContainer.IsSet() || !GetRef() ) return aContainer; + return static_cast<SvMetaSlot *>(GetRef())->GetContainer(); +} + +void SvMetaSlot::ReadAttributesSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + SvMetaAttribute::ReadAttributesSvIdl( rBase, rInStm ); + + aGroupId.ReadSvIdl( SvHash_GroupId(), rInStm ); + aExecMethod.ReadSvIdl( SvHash_ExecMethod(), rInStm ); + aStateMethod.ReadSvIdl( SvHash_StateMethod(), rInStm ); + ReadStringSvIdl( SvHash_DisableFlags(), rInStm, aDisableFlags ); + aReadOnlyDoc.ReadSvIdl( SvHash_ReadOnlyDoc(), rInStm ); + aToggle.ReadSvIdl( SvHash_Toggle(), rInStm ); + aAutoUpdate.ReadSvIdl( SvHash_AutoUpdate(), rInStm ); + aAsynchron.ReadSvIdl( SvHash_Asynchron(), rInStm ); + aRecordAbsolute.ReadSvIdl( SvHash_RecordAbsolute(), rInStm ); + + if( aRecordPerItem.ReadSvIdl( SvHash_RecordPerItem(), rInStm ) ) + { + SetRecordPerItem( aRecordPerItem ); + } + if( aRecordPerSet.ReadSvIdl( SvHash_RecordPerSet(), rInStm ) ) + { + SetRecordPerSet( aRecordPerSet ); + } + if( aNoRecord.ReadSvIdl( SvHash_NoRecord(), rInStm ) ) + { + SetNoRecord( aNoRecord ); + } + + aMenuConfig.ReadSvIdl( SvHash_MenuConfig(), rInStm ); + aToolBoxConfig.ReadSvIdl( SvHash_ToolBoxConfig(), rInStm ); + aAccelConfig.ReadSvIdl( SvHash_AccelConfig(), rInStm ); + + aFastCall.ReadSvIdl( SvHash_FastCall(), rInStm ); + aContainer.ReadSvIdl( SvHash_Container(), rInStm ); +} + +bool SvMetaSlot::Test( SvTokenStream & rInStm ) +{ + bool bOk = SvMetaAttribute::Test( rInStm ); + if( bOk ) + { + SvMetaType * pType = GetType(); + if( pType->GetMetaTypeType() == MetaTypeType::Method ) + pType = pType->GetReturnType(); + if( !pType->IsItem() ) + { + throw SvParseException( rInStm, "this attribute is not a slot" ); + } + } + + return bOk; +} + +bool SvMetaSlot::ReadSvIdl( SvIdlDataBase & rBase, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + bool bOk = true; + + SvMetaAttribute * pAttr = rBase.ReadKnownAttr( rInStm, GetType() ); + if( pAttr ) + { + // c + SvMetaSlot * pKnownSlot = dynamic_cast<SvMetaSlot*>( pAttr ); + if( !pKnownSlot ) + throw SvParseException( rInStm, "attribute " + pAttr->GetName() + " is method or variable but not a slot" ); + SetRef( pKnownSlot ); + SetName( pKnownSlot->GetName() ); + bOk = SvMetaObject::ReadSvIdl( rBase, rInStm ); + } + else + { + bOk = SvMetaAttribute::ReadSvIdl( rBase, rInStm ); + + SvMetaAttribute *pAttr2 = rBase.FindKnownAttr( GetSlotId() ); + if( pAttr2 ) + { + // for testing purposes: reference in case of complete definition + SvMetaSlot * pKnownSlot = dynamic_cast<SvMetaSlot*>( pAttr2 ); + if( !pKnownSlot ) + throw SvParseException( rInStm, "attribute " + pAttr2->GetName() + " is method or variable but not a slot" ); + SetRef( pKnownSlot ); + + // names may differ, because explicitly given + if ( pKnownSlot->GetName() != GetName() ) + { + OSL_FAIL("Illegal definition!"); + rInStm.Seek( nTokPos ); + return false; + } + + SetName( pKnownSlot->GetName() ); + } + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + + return bOk; +} + +void SvMetaSlot::Insert( SvSlotElementList& rList) +{ + // get insert position through binary search in slotlist + sal_uInt16 nId = static_cast<sal_uInt16>(GetSlotId().GetValue()); + sal_uInt16 nListCount = static_cast<sal_uInt16>(rList.size()); + sal_uInt16 nPos; + + if ( !nListCount ) + nPos = 0; + else if ( nListCount == 1 ) + nPos = rList[ 0 ]->GetSlotId().GetValue() >= nId ? 0 : 1; + else + { + sal_uInt16 nMid = 0, nLow = 0; + sal_uInt16 nHigh = nListCount - 1; + bool bFound = false; + while ( !bFound && nLow <= nHigh ) + { + nMid = (nLow + nHigh) >> 1; + DBG_ASSERT( nMid < nListCount, "bsearch is buggy" ); + int nDiff = static_cast<int>(nId) - static_cast<int>(rList[ nMid ]->GetSlotId().GetValue()); + if ( nDiff < 0) + { + if ( nMid == 0 ) + break; + nHigh = nMid - 1; + } + else if ( nDiff > 0 ) + { + nLow = nMid + 1; + if ( nLow == 0 ) + break; + } + else + bFound = true; + } + + DBG_ASSERT(!bFound, "Duplicate SlotId!"); + nPos = bFound ? nMid : nLow; + } + + DBG_ASSERT( nPos <= nListCount, + "nPos too large" ); + DBG_ASSERT( nPos == nListCount || nId <= + static_cast<sal_uInt16>(rList[ nPos ]->GetSlotId().GetValue()), + "Successor has lower SlotId" ); + DBG_ASSERT( nPos == 0 || nId > + static_cast<sal_uInt16>(rList[ nPos-1 ]->GetSlotId().GetValue()), + "Predecessor has higher SlotId" ); + DBG_ASSERT( nPos+1 >= nListCount || nId < + static_cast<sal_uInt16>(rList[ nPos+1 ]->GetSlotId().GetValue()), + "Successor has lower SlotId" ); + + if ( nPos < rList.size() ) + { + SvSlotElementList::iterator it = rList.begin(); + std::advance( it, nPos ); + rList.insert( it, this ); + } + else + { + rList.push_back( this ); + } +} + + +static OString MakeSlotName( SvStringHashEntry const * pEntry ) +{ + return "SfxSlotMode::" + pEntry->GetName().toAsciiUpperCase(); +}; + +void SvMetaSlot::WriteSlotStubs( std::string_view rShellName, + std::vector<OString> & rList, + SvStream & rOutStm ) const +{ + OString aMethodName( GetExecMethod() ); + if ( !aMethodName.isEmpty() && + aMethodName != "NoExec" ) + { + bool bIn = false; + for( size_t n = 0; n < rList.size(); n++ ) + { + if (rList[n] == aMethodName) + { + bIn = true; + break; + } + } + + if ( !bIn ) + { + rList.push_back( aMethodName ); + rOutStm.WriteCharPtr( "SFX_EXEC_STUB(" ) + .WriteOString( rShellName ) + .WriteChar( ',' ) + .WriteOString( aMethodName ) + .WriteChar( ')' ) << endl; + } + } + + aMethodName = GetStateMethod(); + if (aMethodName.isEmpty() || aMethodName == "NoState") + return; + + bool bIn = false; + for ( size_t n=0; n < rList.size(); n++ ) + { + if (rList[n] == aMethodName) + { + bIn = true; + break; + } + } + + if ( !bIn ) + { + rList.push_back( aMethodName ); + rOutStm.WriteCharPtr( "SFX_STATE_STUB(" ) + .WriteOString( rShellName ) + .WriteChar( ',' ) + .WriteOString( aMethodName ) + .WriteChar( ')' ) << endl; + } +} + +void SvMetaSlot::WriteSlot( std::string_view rShellName, sal_uInt16 nCount, + std::string_view rSlotId, + SvSlotElementList& rSlotList, + size_t nStart, + SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + rOutStm.WriteCharPtr( "// Slot Nr. " ) + .WriteOString( OString::number(nListPos) ) + .WriteCharPtr( " : " ); + OString aSlotIdValue(OString::number(GetSlotId().GetValue())); + rOutStm.WriteOString( aSlotIdValue ) << endl; + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr( "SFX_NEW_SLOT_ARG( " ).WriteOString( rShellName ).WriteChar( ',' ) ; + + rOutStm.WriteOString( rSlotId ).WriteChar( ',' ); + + // GroupId + if( !GetGroupId().isEmpty() ) + rOutStm.WriteOString( GetGroupId() ); + else + rOutStm.WriteCharPtr( "SfxGroupId::NONE" ); + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + + // look for the next slot with the same StateMethod like me + // the slotlist is set to the current slot + size_t i = nStart; + SvMetaSlot* pEle = ( ++i < rSlotList.size() ) ? rSlotList[ i ] : nullptr; + pNextSlot = pEle; + while ( pNextSlot ) + { + if ( !pNextSlot->pNextSlot && + pNextSlot->GetStateMethod() == GetStateMethod() + ) { + break; + } + pEle = ( ++i < rSlotList.size() ) ? rSlotList[ i ] : nullptr; + pNextSlot = pEle; + } + + if ( !pNextSlot ) + { + // There is no slot behind me that has the same ExecMethod. + // So I search for the first slot with it (could be myself). + i = 0; + pEle = rSlotList.empty() ? nullptr : rSlotList[ i ]; + pNextSlot = pEle; + while (pNextSlot && pNextSlot != this) + { + if ( pNextSlot->GetStateMethod() == GetStateMethod() ) + break; + pEle = ( ++i < rSlotList.size() ) ? rSlotList[ i ] : nullptr; + pNextSlot = pEle; + } + } + + assert(pNextSlot); + + rOutStm.WriteCharPtr( "&a" ).WriteOString( rShellName ).WriteCharPtr( "Slots_Impl[" ) + .WriteOString( OString::number(pNextSlot->GetListPos()) ) + .WriteCharPtr( "] /*Offset Next*/, " ) << endl; + + WriteTab( rOutStm, 4 ); + + // write ExecMethod, with standard name if not specified + if( !GetExecMethod().isEmpty() && + GetExecMethod() != "NoExec") + { + rOutStm.WriteCharPtr( "SFX_STUB_PTR(" ).WriteOString( rShellName ).WriteChar( ',' ) + .WriteOString( GetExecMethod() ).WriteChar( ')' ); + } + else + rOutStm.WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE" ); + rOutStm.WriteChar( ',' ); + + // write StateMethod, with standard name if not specified + if( !GetStateMethod().isEmpty() && + GetStateMethod() != "NoState") + { + rOutStm.WriteCharPtr( "SFX_STUB_PTR(" ).WriteOString( rShellName ).WriteChar( ',' ) + .WriteOString( GetStateMethod() ).WriteChar( ')' ); + } + else + rOutStm.WriteCharPtr( "SFX_STUB_PTR_STATE_NONE" ); + + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + + // write flags + if( GetToggle() ) + rOutStm.WriteOString( MakeSlotName( SvHash_Toggle() ) ).WriteChar( '|' ); + if( GetAutoUpdate() ) + rOutStm.WriteOString( MakeSlotName( SvHash_AutoUpdate() ) ).WriteChar( '|' ); + if( GetAsynchron() ) + rOutStm.WriteOString( MakeSlotName( SvHash_Asynchron() ) ).WriteChar( '|' ); + if( GetRecordPerItem() ) + rOutStm.WriteOString( MakeSlotName( SvHash_RecordPerItem() ) ).WriteChar( '|' ); + if( GetRecordPerSet() ) + rOutStm.WriteOString( MakeSlotName( SvHash_RecordPerSet() ) ).WriteChar( '|' ); + if( GetNoRecord() ) + rOutStm.WriteOString( MakeSlotName( SvHash_NoRecord() ) ).WriteChar( '|' ); + if( GetRecordAbsolute() ) + rOutStm.WriteOString( MakeSlotName( SvHash_RecordAbsolute() ) ).WriteChar( '|' ); + if( GetMenuConfig() ) + rOutStm.WriteOString( MakeSlotName( SvHash_MenuConfig() ) ).WriteChar( '|' ); + if( GetToolBoxConfig() ) + rOutStm.WriteOString( MakeSlotName( SvHash_ToolBoxConfig() ) ).WriteChar( '|' ); + if( GetAccelConfig() ) + rOutStm.WriteOString( MakeSlotName( SvHash_AccelConfig() ) ).WriteChar( '|' ); + if( GetFastCall() ) + rOutStm.WriteOString( MakeSlotName( SvHash_FastCall() ) ).WriteChar( '|' ); + if( GetContainer() ) + rOutStm.WriteOString( MakeSlotName( SvHash_Container() ) ).WriteChar( '|' ); + if ( GetReadOnlyDoc() ) + rOutStm.WriteOString( MakeSlotName( SvHash_ReadOnlyDoc() ) ).WriteChar( '|' ); + rOutStm.WriteCharPtr( "SfxSlotMode::NONE" ); + + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + if ( GetDisableFlags().isEmpty() ) + rOutStm.WriteCharPtr( "SfxDisableFlags::NONE" ); + else + rOutStm.WriteOString( GetDisableFlags() ); + + // write attribute type + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + + SvMetaType * pT = GetType(); + if( !IsVariable() ) + { + SvMetaType * pRT = GetType()->GetReturnType(); + pT = pRT ? pRT : rBase.FindType( "SfxVoidItem" ); + } + + if( pT ) + { + assert(pT->IsItem()); + rOutStm.WriteOString( pT->GetName() ); + if( !SvIdlDataBase::FindType( pT, rBase.aUsedTypes ) ) + rBase.aUsedTypes.push_back( pT ); + } + else + rOutStm.WriteCharPtr( "SfxVoidItem not defined" ); + + { + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + rOutStm + .WriteOString( OString::number(nCount) ) + .WriteCharPtr( "/*Offset*/, " ); + + if( IsMethod() ) + { + SvMetaType * pType = GetType(); + sal_uLong nSCount = pType->GetAttrCount(); + rOutStm + .WriteOString( OString::number(nSCount) ) + .WriteCharPtr( "/*Count*/," ); + } + else + rOutStm.WriteCharPtr( "0," ); + + rOutStm.WriteCharPtr( " " ); + + // Method/Property flags + if( IsMethod() ) + rOutStm.WriteCharPtr( "SfxSlotMode::METHOD|" ); + + rOutStm.WriteCharPtr( "SfxSlotMode::NONE" ); + } + + { + rOutStm.WriteCharPtr( ",\"" ); + rOutStm.WriteOString( GetName() ); + rOutStm.WriteCharPtr( "\"" ); + } + + rOutStm.WriteCharPtr( " )," ) << endl; +} + +sal_uInt16 SvMetaSlot::WriteSlotParamArray( SvIdlDataBase & rBase, SvStream & rOutStm ) const +{ + if( !IsMethod() ) + return 0; + + SvMetaType * pType = GetType(); + + if( !SvIdlDataBase::FindType( pType, rBase.aUsedTypes ) ) + rBase.aUsedTypes.push_back( pType ); + + const SvRefMemberList<SvMetaAttribute *>& rList = + pType->GetAttrList(); + for( size_t n = 0; n < rList.size(); n++ ) + { + SvMetaAttribute * pPar = rList[n]; + SvMetaType * pPType = pPar->GetType(); + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr("{ (const SfxType*) &a") + // item type + .WriteOString(pPType->GetName()).WriteCharPtr("_Impl, ") + // parameter name + .WriteCharPtr("\"").WriteOString(pPar->GetName()).WriteCharPtr("\", ") + // slot id + .WriteOString(pPar->GetSlotId().getString()).WriteCharPtr(" },") << endl; + if( !SvIdlDataBase::FindType( pPType, rBase.aUsedTypes ) ) + rBase.aUsedTypes.push_back( pPType ); + } + return static_cast<sal_uInt16>(rList.size()); +} + +sal_uInt16 SvMetaSlot::WriteSlotMap( std::string_view rShellName, sal_uInt16 nCount, + SvSlotElementList& rSlotList, + size_t nStart, + SvIdlDataBase & rBase, + SvStream & rOutStm ) +{ + // SlotId, if not specified generate from name + OString slotId = GetSlotId().getString(); + + sal_uInt16 nSCount = 0; + if( IsMethod() ) + { + SvMetaType * pType = GetType(); + nSCount = static_cast<sal_uInt16>(pType->GetAttrCount()); + } + + WriteSlot( rShellName, nCount, slotId, rSlotList, nStart, rBase, rOutStm ); + return nSCount; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/types.cxx b/idl/source/objects/types.cxx new file mode 100644 index 000000000..08492b4b6 --- /dev/null +++ b/idl/source/objects/types.cxx @@ -0,0 +1,320 @@ +/* -*- 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 <tools/debug.hxx> + +#include <types.hxx> +#include <globals.hxx> +#include <database.hxx> + +SvMetaAttribute::SvMetaAttribute() +{ +} + +SvMetaAttribute::SvMetaAttribute( SvMetaType * pType ) + : aType( pType ) +{ +} + +SvMetaType * SvMetaAttribute::GetType() const +{ + if( aType.is() || !GetRef() ) return aType.get(); + return static_cast<SvMetaAttribute *>(GetRef())->GetType(); +} + +const SvIdentifier & SvMetaAttribute::GetSlotId() const +{ + if( aSlotId.IsSet() || !GetRef() ) return aSlotId; + return static_cast<SvMetaAttribute *>(GetRef())->GetSlotId(); +} + +bool SvMetaAttribute::Test( SvTokenStream & rInStm ) +{ + if( GetType()->IsItem() && !GetSlotId().IsSet() ) + { + throw SvParseException( rInStm, "slot without id declared" ); + } + return true; +} + +bool SvMetaAttribute::ReadSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + if( !GetType() ) + // no type in ctor passed on + aType = rBase.ReadKnownType( rInStm ); + bool bOk = false; + if( GetType() ) + { + ReadNameSvIdl( rInStm ); + aSlotId.ReadSvIdl( rBase, rInStm ); + + bOk = true; + SvToken& rTok = rInStm.GetToken(); + if( rTok.IsChar() && rTok.GetChar() == '(' ) + { + tools::SvRef<SvMetaType> xT(new SvMetaType() ); + xT->SetRef( GetType() ); + aType = xT; + bOk = aType->ReadMethodArgs( rBase, rInStm ); + } + if( bOk ) + bOk = SvMetaObject::ReadSvIdl( rBase, rInStm ); + } + else + { + SvToken& rTok = rInStm.GetToken(); + rBase.SetError( "unknown type of token. Each new SID needs an " + "item statement in an SDI file, eg. " + "SfxVoidItem FooItem " + rTok.GetTokenAsString() + + " ... which describes the slot more fully", rTok ); + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + return bOk; +} + +size_t SvMetaAttribute::MakeSfx( OStringBuffer& rAttrArray ) const +{ + SvMetaType * pType = GetType(); + DBG_ASSERT( pType, "no type for attribute" ); + SvMetaType * pBaseType = pType->GetBaseType(); + DBG_ASSERT( pBaseType, "no base type for attribute" ); + if( pBaseType->GetMetaTypeType() == MetaTypeType::Struct ) + return pBaseType->MakeSfx( rAttrArray ); + else + { + rAttrArray.append('{'); + rAttrArray.append(GetSlotId().getString()); + rAttrArray.append(",\""); + rAttrArray.append(GetName()); + rAttrArray.append("\"}"); + return 1; + } +} + +void SvMetaAttribute::Insert(SvSlotElementList&) +{ +} + +SvMetaType::SvMetaType() + : nType( MetaTypeType::Base ) + , bIsItem( false ) +{ +} + +SvMetaType::SvMetaType( const OString& rName ) + : SvMetaType() +{ + SetName( rName ); +} + +SvMetaType::~SvMetaType() +{} + +void SvMetaType::SetType( MetaTypeType nT ) +{ + nType = nT; +} + +SvMetaType * SvMetaType::GetBaseType() const +{ + if( GetRef() && GetMetaTypeType() == MetaTypeType::Base ) + return static_cast<SvMetaType *>(GetRef())->GetBaseType(); + return const_cast<SvMetaType *>(this); +} + +SvMetaType * SvMetaType::GetReturnType() const +{ + DBG_ASSERT( GetMetaTypeType() == MetaTypeType::Method, "no method" ); + DBG_ASSERT( GetRef(), "no return type" ); + return static_cast<SvMetaType *>(GetRef()); +} + +bool SvMetaType::ReadHeaderSvIdl( SvTokenStream & rInStm ) +{ + bool bOk = false; + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( SvHash_interface() ) ) + { + SetType( MetaTypeType::Interface ); + bOk = ReadNameSvIdl( rInStm ); + } + else if( rTok.Is( SvHash_shell() ) ) + { + SetType( MetaTypeType::Shell ); + bOk = ReadNameSvIdl( rInStm ); + } + if( !bOk ) + rInStm.Seek( nTokPos ); + return bOk; +} + +bool SvMetaType::ReadSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + if( ReadHeaderSvIdl( rInStm ) ) + { + rBase.Write(OString('.')); + return SvMetaReference::ReadSvIdl( rBase, rInStm ); + } + return false; +} + +void SvMetaType::ReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + tools::SvRef<SvMetaAttribute> xAttr( new SvMetaAttribute() ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + { + if( xAttr->Test( rInStm ) ) + GetAttrList().push_back( xAttr.get() ); + } +} + +size_t SvMetaType::MakeSfx( OStringBuffer& rAttrArray ) +{ + size_t nC = 0; + + if( GetBaseType()->GetMetaTypeType() == MetaTypeType::Struct ) + { + size_t nAttrCount = GetAttrCount(); + // write the single attributes + for( size_t n = 0; n < nAttrCount; n++ ) + { + nC += aAttrList[n]->MakeSfx( rAttrArray ); + if( n +1 < nAttrCount ) + rAttrArray.append(", "); + } + } + return nC; +} + +void SvMetaType::WriteSfxItem( + std::string_view rItemName, SvIdlDataBase const & rBase, SvStream& rOutStm ) +{ + WriteStars( rOutStm ); + OString aVarName = OString::Concat(" a") + rItemName + "_Impl"; + + OStringBuffer aAttrArray(1024); + size_t nAttrCount = MakeSfx( aAttrArray ); + OString aAttrCount( OString::number(nAttrCount)); + OString aTypeName = "SfxType" + aAttrCount; + + bool bExport = false, bReturn = false; + // these are exported from sfx library + if (rItemName == "SfxBoolItem" || + rItemName == "SfxInt16Item" || + rItemName == "SfxStringItem" || + rItemName == "SfxUInt16Item" || + rItemName == "SfxUInt32Item" || + rItemName == "SfxVoidItem") + { + bExport = true; + if (!rBase.sSlotMapFile.endsWith("sfxslots.hxx")) + bReturn = true; + } + + rOutStm.WriteCharPtr( "extern " ); + if (bExport) + rOutStm.WriteCharPtr( "SFX2_DLLPUBLIC " ); + rOutStm.WriteOString( aTypeName ) + .WriteOString( aVarName ).WriteChar( ';' ) << endl; + if (bReturn) + return; + + // write the implementation part + rOutStm.WriteCharPtr( "#ifdef SFX_TYPEMAP" ) << endl; + rOutStm.WriteCharPtr( "#if !defined(_WIN32) && (defined(DISABLE_DYNLOADING) && (defined(ANDROID) || defined(IOS) || defined(EMSCRIPTEN) || defined(LINUX)))" ) << endl; + rOutStm.WriteCharPtr( "__attribute__((__weak__))" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl; + rOutStm.WriteOString( aTypeName ).WriteOString( aVarName ) + .WriteCharPtr( " = " ) << endl; + rOutStm.WriteChar( '{' ) << endl; + + rOutStm.WriteCharPtr( "\tcreateSfxPoolItem<" ).WriteOString( rItemName ) + .WriteCharPtr(">, &typeid(").WriteOString( rItemName ).WriteCharPtr( "), " ); + rOutStm.WriteOString( aAttrCount ); + if( nAttrCount ) + { + rOutStm.WriteCharPtr( ", { " ); + // write the single attributes + rOutStm.WriteCharPtr( aAttrArray.getStr() ); + rOutStm.WriteCharPtr( " }" ); + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; +} + +void SvMetaType::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + if( IsItem() ) + { + if( GetBaseType()->GetMetaTypeType() == MetaTypeType::Struct ) + GetBaseType()->WriteSfxItem( GetName(), rBase, rOutStm ); + else + WriteSfxItem( GetName(), rBase, rOutStm ); + } +} + +bool SvMetaType::ReadMethodArgs( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + if( rInStm.ReadIf( '(' ) ) + { + DoReadContextSvIdl( rBase, rInStm ); + if( rInStm.ReadIf( ')' ) ) + { + SetType( MetaTypeType::Method ); + return true; + } + } + rInStm.Seek( nTokPos ); + return false; +} + +SvMetaTypeString::SvMetaTypeString() + : SvMetaType( "String" ) +{ +} + +SvMetaEnumValue::SvMetaEnumValue() +{ +} + +SvMetaTypeEnum::SvMetaTypeEnum() +{ +} + +SvMetaTypevoid::SvMetaTypevoid() + : SvMetaType( "void" ) +{ +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/prj/command.cxx b/idl/source/prj/command.cxx new file mode 100644 index 000000000..0c9436ce3 --- /dev/null +++ b/idl/source/prj/command.cxx @@ -0,0 +1,296 @@ +/* -*- 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 <stdlib.h> +#include <stdio.h> + +#include <osl/diagnose.h> +#include <rtl/character.hxx> + +#include <command.hxx> +#include <globals.hxx> +#include <database.hxx> +#include <parser.hxx> + +char const * const SyntaxStrings[] = { +"basic-type:", +"\tvoid| char| int| float| double|", +"\tUINT16| INT16| UINT32| INT32| BOOL|", +"\tBYTE| String| SbxObject", +"", +"{ import \"filename\" }\n", +"module definition:", +"module", +"\tunique id range (ask MM)", +"modul-name", +"'['", +"\tSlotIdFile( \"filename\" )", +"']'", +"'{'", +"\t{ include \"filename\" }\n", + +"\titem definition:", +"\titem type item-name;\n", + +"\ttype definition:", +"\tstruct identifier", +"\t'{'", +"\t\t{ type identifier }", +"\t'}'", +"\t|", +"\tenum identifier", +"\t'{'", +"\t\t{ identifier, }", +"\t'}'", +"\t|", +"\ttypedef type identifier\n", + +"\titem-method-args:", +"\t( { item parameter-name SLOT_ID } )\n", + +"\tslot definition:", +"\titem identifier SLOT_ID [ item-method-args ]", +"\t'['", +"\t\tAccelConfig, MenuConfig, ToolbarConfig", +"\t\tAutoUpdate", +"\t\tContainer", +"\t\tExecMethod = Identifier", +"\t\tFastCall", +"\t\tGroupId = Identifier", +"\t\tReadOnlyDoc*", +"\t\tRecordPerSet*, RecordPerItem, NoRecord", +"\t\tRecordAbsolute", +"\t\tStateMethod = Identifier", +"\t\tAsynchron", +"\t\tToggle", +"\t']'\n", + +"\tinterface definition:", +"\tshell | interface identifier ':' interface", +"\t'{'", +"\t\t{ slot }", +"\t'}'\n", +"---syntax example is sfx.idl---\n", +nullptr }; + +char const CommandLineSyntax[] = +"-fs<slotmap file>\n" +"-fm<makefile target file>\n" +"-help, ? @<file> response file\n" +" <filenames>\n"; + +void Init() +{ + if( !GetIdlApp().pHashTable ) + GetIdlApp().pHashTable.reset( new SvStringHashTable ); + if( !GetIdlApp().pGlobalNames ) + GetIdlApp().pGlobalNames.reset( new SvGlobalHashNames() ); +} + +bool ReadIdl( SvIdlWorkingBase * pDataBase, const SvCommand & rCommand ) +{ + for( size_t n = 0; n < rCommand.aInFileList.size(); ++n ) + { + OUString aFileName ( rCommand.aInFileList[ n ] ); + pDataBase->AddDepFile(aFileName); + SvTokenStream aTokStm( aFileName ); + try { + SvIdlParser aParser(*pDataBase, aTokStm); + aParser.ReadSvIdl( rCommand.aPath ); + } catch (const SvParseException& ex) { + pDataBase->SetError(ex.aError); + pDataBase->WriteError(aTokStm); + return false; + } + } + return true; +} + +static bool ResponseFile( std::vector<OUString> * pList, int argc, char ** argv ) +{ + // program name + pList->push_back( OUString::createFromAscii(*argv) ); + for( int i = 1; i < argc; i++ ) + { + if( '@' == **(argv +i) ) + { // when @, then response file + SvFileStream aStm( OUString::createFromAscii((*(argv +i)) +1), StreamMode::STD_READ ); + if( aStm.GetError() != ERRCODE_NONE ) + return false; + + OStringBuffer aStr; + while( aStm.ReadLine( aStr ) ) + { + sal_uInt16 n = 0; + sal_uInt16 nPos = 1; + while( n != nPos ) + { + while( aStr[n] + && rtl::isAsciiWhiteSpace( + static_cast<unsigned char>(aStr[n]) ) ) + n++; + nPos = n; + while( aStr[n] + && !rtl::isAsciiWhiteSpace( + static_cast<unsigned char>(aStr[n]) ) ) + n++; + if( n != nPos ) + pList->push_back( OStringToOUString(std::string_view(aStr).substr(nPos, n - nPos), RTL_TEXTENCODING_ASCII_US) ); + } + } + } + else if( argv[ i ] ) + pList->push_back( OUString::createFromAscii( argv[ i ] ) ); + } + return true; +} + +SvCommand::SvCommand( int argc, char ** argv ) + : nVerbosity(1) +{ + std::vector<OUString> aList; + + if( ResponseFile( &aList, argc, argv ) ) + { + for( size_t i = 1; i < aList.size(); i++ ) + { + OUString aParam( aList[ i ] ); + sal_Unicode aFirstChar( aParam[0] ); + if( '-' == aFirstChar ) + { + aParam = aParam.copy( 1 ); + aFirstChar = aParam[0]; + if( aFirstChar == 'F' || aFirstChar == 'f' ) + { + aParam = aParam.copy( 1 ); + aFirstChar = aParam[0]; + OUString aName( aParam.copy( 1 ) ); + if( 's' == aFirstChar ) + { // name of slot output + aSlotMapFile = aName; + } + else if( 'm' == aFirstChar ) + { // name of info file + aTargetFile = aName; + } + else if( 'x' == aFirstChar ) + { // name of IDL file for the CSV file + aExportFile = aName; + } + else if( 'M' == aFirstChar ) + { + m_DepFile = aName; + } + else + { + printf( + "unknown switch: %s\n", + OUStringToOString( + aParam, RTL_TEXTENCODING_UTF8).getStr()); + exit( -1 ); + } + } + else if( aParam.equalsIgnoreAsciiCase( "help" ) || aParam.equalsIgnoreAsciiCase( "?" ) ) + { // help + printf( "%s", CommandLineSyntax ); + } + else if( aParam.equalsIgnoreAsciiCase( "quiet" ) ) + { + nVerbosity = 0; + } + else if( aParam.equalsIgnoreAsciiCase( "verbose" ) ) + { + nVerbosity = 2; + } + else if( aParam.equalsIgnoreAsciiCase( "syntax" ) ) + { // help + int j = 0; + while(SyntaxStrings[j]) + printf("%s\n",SyntaxStrings[j++]); + } + else if (aParam == "isystem") + { + // ignore "-isystem" and following arg + if (i < aList.size()) + { + ++i; + } + } + else if (aParam.startsWith("isystem")) + { + // ignore args starting with "-isystem" + } + else if( aParam.startsWithIgnoreAsciiCase( "i" ) ) + { // define include paths + OUString aName( aParam.copy( 1 ) ); + if( !aPath.isEmpty() ) + aPath += OUStringChar(SAL_PATHSEPARATOR); + aPath += aName; + } + else if( aParam.startsWithIgnoreAsciiCase( "rsc" ) ) + { // first line in *.srs file + OSL_ENSURE(false, "does anything use this option, doesn't look like it belong here"); + if( !aList[ i + 1 ].isEmpty() ) + { + i++; + } + } + else + { + // temporary compatibility hack + printf( + "unknown switch: %s\n", + OUStringToOString( + aParam, RTL_TEXTENCODING_UTF8).getStr()); + exit( -1 ); + } + } + else + { + aInFileList.push_back( aParam ); + } + } + } + else + { + printf( "%s", CommandLineSyntax ); + } + + aList.clear(); + + auto const env = getenv("INCLUDE"); + OString aInc(env == nullptr ? "" : env); + // append include environment variable + if( aInc.getLength() ) + { + if( !aPath.isEmpty() ) + aPath += OUStringChar(SAL_PATHSEPARATOR); + aPath += OStringToOUString(aInc, RTL_TEXTENCODING_ASCII_US); + } +} + +SvCommand::~SvCommand() +{ + // release String list + aInFileList.clear(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/prj/database.cxx b/idl/source/prj/database.cxx new file mode 100644 index 000000000..9aba715ed --- /dev/null +++ b/idl/source/prj/database.cxx @@ -0,0 +1,553 @@ +/* -*- 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 <stdio.h> +#include <string_view> + +#include <command.hxx> +#include <database.hxx> +#include <globals.hxx> +#include <slot.hxx> +#include <rtl/strbuf.hxx> +#include <osl/file.hxx> + + +SvParseException::SvParseException( SvTokenStream const & rInStm, const OString& rError ) +{ + SvToken& rTok = rInStm.GetToken(); + aError = SvIdlError( rTok.GetLine(), rTok.GetColumn() ); + aError.SetText( rError ); +}; + +SvParseException::SvParseException( const OString& rError, SvToken const & rTok ) +{ + aError = SvIdlError( rTok.GetLine(), rTok.GetColumn() ); + aError.SetText( rError ); +}; + + +SvIdlDataBase::SvIdlDataBase( const SvCommand& rCmd ) + : bExport( false ) + , nUniqueId( 0 ) + , nVerbosity( rCmd.nVerbosity ) +{ + sSlotMapFile = rCmd.aSlotMapFile; +} + +SvIdlDataBase::~SvIdlDataBase() +{ + aIdFileList.clear(); +} + +#define ADD_TYPE( Name ) \ + aTypeList.push_back( new SvMetaType( SvHash_##Name()->GetName() ) ); + +SvRefMemberList<SvMetaType *>& SvIdlDataBase::GetTypeList() +{ + if( aTypeList.empty() ) + { // fill initially + aTypeList.push_back( new SvMetaTypeString() ); + aTypeList.push_back( new SvMetaTypevoid() ); + + // MI: IDispatch::Invoke can not unsigned + ADD_TYPE( UINT16 ); + ADD_TYPE( INT16 ); + ADD_TYPE( UINT32 ); + ADD_TYPE( INT32 ); + ADD_TYPE( BOOL ); + ADD_TYPE( BYTE ); + ADD_TYPE( float ); + ADD_TYPE( double ); + ADD_TYPE( SbxObject ); + + // Attention! When adding types all binary data bases get incompatible + + } + return aTypeList; +} + +void SvIdlDataBase::SetError( const OString& rError, SvToken const & rTok ) +{ + if( rTok.GetLine() > 10000 ) + aError.SetText( "line count overflow" ); + + if( aError.nLine < rTok.GetLine() + || (aError.nLine == rTok.GetLine() && aError.nColumn < rTok.GetColumn()) ) + { + aError = SvIdlError( rTok.GetLine(), rTok.GetColumn() ); + aError.SetText( rError ); + } +} + +void SvIdlDataBase::SetAndWriteError( SvTokenStream & rInStm, const OString& rError ) +{ + SetError( rError, rInStm.GetToken() ); + WriteError( rInStm ); +} + +void SvIdlDataBase::Push( SvMetaObject * pObj ) +{ + GetStack().push_back( pObj ); +} + +bool SvIdlDataBase::FindId( const OString& rIdName, sal_uInt32 * pVal ) +{ + if( pIdTable ) + { + sal_uInt32 nHash; + if( pIdTable->Test( rIdName, &nHash ) ) + { + *pVal = pIdTable->Get( nHash )->GetValue(); + return true; + } + } + return false; +} + +void SvIdlDataBase::InsertId( const OString& rIdName, sal_uInt32 nVal ) +{ + if( !pIdTable ) + pIdTable.reset( new SvStringHashTable ); + + sal_uInt32 nHash; + pIdTable->Insert( rIdName, &nHash )->SetValue( nVal ); +} + +bool SvIdlDataBase::ReadIdFile( std::string_view rOFileName ) +{ + OUString rFileName = OStringToOUString(rOFileName, RTL_TEXTENCODING_ASCII_US); + OUString aFullName; + osl::File::searchFileURL( rFileName, GetPath(), aFullName); + osl::FileBase::getSystemPathFromFileURL( aFullName, aFullName ); + + for ( size_t i = 0, n = aIdFileList.size(); i < n; ++i ) + if ( aIdFileList[ i ] == rFileName ) + return true; + + aIdFileList.push_back( rFileName ); + AddDepFile( aFullName ); + SvTokenStream aTokStm( aFullName ); + if( aTokStm.GetStream().GetError() != ERRCODE_NONE ) + return false; + + SvToken& rTok = aTokStm.GetToken_Next(); + + while( !rTok.IsEof() ) + { + if( rTok.IsChar() && rTok.GetChar() == '#' ) + { + rTok = aTokStm.GetToken_Next(); + if( rTok.Is( SvHash_define() ) ) + { + rTok = aTokStm.GetToken_Next(); + OString aDefName; + if( !rTok.IsIdentifier() ) + throw SvParseException( "unexpected token after define", rTok ); + aDefName = rTok.GetString(); + + sal_uInt32 nVal = 0; + bool bOk = true; + while( bOk ) + { + rTok = aTokStm.GetToken_Next(); + if (rTok.GetTokenAsString().startsWith("TypedWhichId")) + { + rTok = aTokStm.GetToken_Next(); + if( !rTok.IsChar() || rTok.GetChar() != '<') + throw SvParseException( "expected '<'", rTok ); + rTok = aTokStm.GetToken_Next(); + if (rTok.IsChar() && rTok.GetChar() == ':') + { + // add support for "::avmedia::MediaItem" namespaced identifier + rTok = aTokStm.GetToken_Next(); + if( !rTok.IsChar() || rTok.GetChar() != ':') + throw SvParseException( "expected ':'", rTok ); + // the lexer reads "avmedia::MediaItem" as an identifier + rTok = aTokStm.GetToken_Next(); + if( !rTok.IsIdentifier() ) + throw SvParseException( "expected identifier", rTok ); + } + else if( !rTok.IsIdentifier() ) + throw SvParseException( "expected identifier", rTok ); + rTok = aTokStm.GetToken_Next(); + if( !rTok.IsChar() || rTok.GetChar() != '>') + throw SvParseException( "expected '<'", rTok ); + rTok = aTokStm.GetToken_Next(); + } + else if( rTok.IsIdentifier() ) + { + sal_uInt32 n; + if( FindId( rTok.GetString(), &n ) ) + nVal += n; + else + bOk = false; + } + else if( rTok.IsChar() ) + { + if( rTok.GetChar() == '-' + || rTok.GetChar() == '/' + || rTok.GetChar() == '*' + || rTok.GetChar() == '&' + || rTok.GetChar() == '|' + || rTok.GetChar() == '^' + || rTok.GetChar() == '~' ) + { + throw SvParseException( "unknown operator '" + OStringChar(rTok.GetChar()) + "'in define", rTok ); + } + if( rTok.GetChar() != '+' + && rTok.GetChar() != '(' + && rTok.GetChar() != ')' ) + // only + is allowed, parentheses are immaterial + // because + is commutative + break; + } + else if( rTok.IsInteger() ) + { + nVal += rTok.GetNumber(); + } + else + break; + } + if( bOk ) + { + InsertId( aDefName, nVal ); + } + } + else if( rTok.Is( SvHash_include() ) ) + { + rTok = aTokStm.GetToken_Next(); + OStringBuffer aNameBuf(128); + if( rTok.IsString() ) + aNameBuf.append(rTok.GetString()); + else if( rTok.IsChar() && rTok.GetChar() == '<' ) + { + rTok = aTokStm.GetToken_Next(); + while( !rTok.IsEof() + && !(rTok.IsChar() && rTok.GetChar() == '>') ) + { + aNameBuf.append(rTok.GetTokenAsString()); + rTok = aTokStm.GetToken_Next(); + } + if( rTok.IsEof() ) + { + throw SvParseException("unexpected eof in #include", rTok); + } + } + OString aName(aNameBuf.makeStringAndClear()); + if (aName == "sfx2/groupid.hxx") + { + // contains C++ code which we cannot parse + // we special-case this by defining a macro internally in... + } + else if (aName == "svl/typedwhich.hxx") + { + // contains C++ code which we cannot parse + } + else if (!ReadIdFile(aName)) + { + throw SvParseException("cannot read file: " + aName, rTok); + } + } + } + else + rTok = aTokStm.GetToken_Next(); + } + return true; +} + +SvMetaType * SvIdlDataBase::FindType( const SvMetaType * pPType, + SvRefMemberList<SvMetaType *>& rList ) +{ + for (auto const& elem : rList) + if( elem == pPType ) + return elem; + return nullptr; +} + +SvMetaType * SvIdlDataBase::FindType( std::string_view rName ) +{ + for (auto const& elem : aTypeList) + if( rName == elem->GetName() ) + return elem; + return nullptr; +} + +SvMetaType * SvIdlDataBase::ReadKnownType( SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.IsIdentifier() ) + { + const OString& aName = rTok.GetString(); + for( const auto& aType : GetTypeList() ) + { + if( aType->GetName() == aName ) + { + return aType; + } + } + } + rInStm.Seek( nTokPos ); + return nullptr; +} + +SvMetaAttribute * SvIdlDataBase::ReadKnownAttr +( + SvTokenStream & rInStm, + SvMetaType * pType /* If pType == NULL, then the type has + still to be read. */ +) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + + if( !pType ) + pType = ReadKnownType( rInStm ); + + if( !pType ) + { + // otherwise SlotId? + SvToken& rTok = rInStm.GetToken_Next(); + if( rTok.IsIdentifier() ) + { + sal_uInt32 n; + if( FindId( rTok.GetString(), &n ) ) + { + for( size_t i = 0; i < aSlotList.size(); i++ ) + { + SvMetaSlot * pSlot = aSlotList[i]; + if( pSlot->GetSlotId().getString() == rTok.GetString() ) + return pSlot; + } + } + + OSL_FAIL(OString("Not found : " + rTok.GetString()).getStr()); + } + } + + rInStm.Seek( nTokPos ); + return nullptr; +} + +SvMetaAttribute* SvIdlDataBase::FindKnownAttr( const SvIdentifier& rId ) +{ + sal_uInt32 n; + if( FindId( rId.getString(), &n ) ) + { + for( size_t i = 0; i < aSlotList.size(); i++ ) + { + SvMetaSlot * pSlot = aSlotList[i]; + if( pSlot->GetSlotId().getString() == rId.getString() ) + return pSlot; + } + } + + return nullptr; +} + +SvMetaClass * SvIdlDataBase::ReadKnownClass( SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.IsIdentifier() ) + { + SvMetaClass* p = FindKnownClass(rTok.GetString()); + if (p) + return p; + } + + rInStm.Seek( nTokPos ); + return nullptr; +} + +SvMetaClass * SvIdlDataBase::FindKnownClass( std::string_view aName ) +{ + for( size_t n = 0; n < aClassList.size(); n++ ) + { + SvMetaClass * pClass = aClassList[n]; + if( pClass->GetName() == aName ) + return pClass; + } + return nullptr; +} + +void SvIdlDataBase::Write(const OString& rText) const +{ + if( nVerbosity != 0 ) + fprintf( stdout, "%s", rText.getStr() ); +} + +void SvIdlDataBase::WriteError( SvTokenStream & rInStm ) +{ + // error treatment + OUString aFileName( rInStm.GetFileName() ); + OStringBuffer aErrorText; + sal_uInt64 nRow = 0, nColumn = 0; + + rInStm.SeekToMax(); + SvToken& rTok = rInStm.GetToken(); + + // error position + nRow = rTok.GetLine(); + nColumn = rTok.GetColumn(); + + if( aError.IsError() ) + { // error set + // search error token + // error text + if( !aError.GetText().isEmpty() ) + { + aErrorText.append("may be <"); + aErrorText.append(aError.GetText()); + } + SvToken * pPrevTok = nullptr; + while( &rTok != pPrevTok ) + { + pPrevTok = &rTok; + if( rTok.GetLine() == aError.nLine + && rTok.GetColumn() == aError.nColumn ) + break; + rTok = rInStm.GetToken_PrevAll(); + } + + // error position + aErrorText.append("> at ( "); + aErrorText.append(static_cast<sal_Int64>(aError.nLine)); + aErrorText.append(", "); + aErrorText.append(static_cast<sal_Int64>(aError.nColumn)); + aErrorText.append(" )"); + + // reset error + aError = SvIdlError(); + } + + // error treatment + fprintf( stderr, "\n%s --- %s: ( %" SAL_PRIuUINT64 ", %" SAL_PRIuUINT64 " )\n", + OUStringToOString(aFileName, RTL_TEXTENCODING_UTF8).getStr(), + "error", nRow, nColumn ); + + if( !aErrorText.isEmpty() ) + { // error set + fprintf( stderr, "\t%s\n", aErrorText.getStr() ); + } + + // look for identifier close by + if( !rTok.IsIdentifier() ) + { + rInStm.GetToken_PrevAll(); + rTok = rInStm.GetToken(); + } + if( rTok.IsIdentifier() ) + { + OString aN = GetIdlApp().pHashTable->GetNearString( rTok.GetString() ); + if( !aN.isEmpty() ) + fprintf( stderr, "%s versus %s\n", rTok.GetString().getStr(), aN.getStr() ); + } +} + +SvIdlWorkingBase::SvIdlWorkingBase(const SvCommand& rCmd) : SvIdlDataBase(rCmd) +{ +} + + +bool SvIdlWorkingBase::WriteSfx( SvStream & rOutStm ) +{ + if( rOutStm.GetError() != ERRCODE_NONE ) + return false; + + // reset all tmp variables for writing + WriteReset(); + SvMemoryStream aTmpStm( 256000, 256000 ); + size_t n; + for( n = 0; n < GetModuleList().size(); n++ ) + { + SvMetaModule * pModule = GetModuleList()[n]; + pModule->WriteSfx( *this, aTmpStm ); + aTmpStm.Seek( 0 ); + } + for( n = 0; n < aUsedTypes.size(); n++ ) + { + SvMetaType * pType = aUsedTypes[n]; + pType->WriteSfx( *this, rOutStm ); + } + aUsedTypes.clear(); + rOutStm.WriteStream( aTmpStm ); + return true; +} + +void SvIdlDataBase::StartNewFile( std::u16string_view rName ) +{ + bExport = aExportFile.equalsIgnoreAsciiCase( rName ); + assert ( !bExport ); +} + +void SvIdlDataBase::AppendSlot( SvMetaSlot *pSlot ) +{ + aSlotList.push_back( pSlot ); + assert ( !bExport ); +} + +void SvIdlDataBase::AddDepFile(OUString const& rFileName) +{ + m_DepFiles.insert(rFileName); +} + +namespace { + +struct WriteDep +{ + SvFileStream & m_rStream; + explicit WriteDep(SvFileStream & rStream) : m_rStream(rStream) { } + void operator() (std::u16string_view rItem) + { + m_rStream.WriteCharPtr( " \\\n " ); + m_rStream.WriteOString( OUStringToOString(rItem, RTL_TEXTENCODING_UTF8) ); + } +}; + +// write a dummy target for one included file, so the incremental build does +// not break with "No rule to make target" if the included file is removed +struct WriteDummy +{ + SvFileStream & m_rStream; + explicit WriteDummy(SvFileStream & rStream) : m_rStream(rStream) { } + void operator() (std::u16string_view rItem) + { + m_rStream.WriteOString( OUStringToOString(rItem, RTL_TEXTENCODING_UTF8) ); + m_rStream.WriteCharPtr( " :\n\n" ); + } +}; + +} + +void SvIdlDataBase::WriteDepFile( + SvFileStream & rStream, std::u16string_view rTarget) +{ + rStream.WriteOString( OUStringToOString(rTarget, RTL_TEXTENCODING_UTF8) ); + rStream.WriteCharPtr( " :" ); + ::std::for_each(m_DepFiles.begin(), m_DepFiles.end(), WriteDep(rStream)); + rStream.WriteCharPtr( "\n\n" ); + ::std::for_each(m_DepFiles.begin(), m_DepFiles.end(), WriteDummy(rStream)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/prj/globals.cxx b/idl/source/prj/globals.cxx new file mode 100644 index 000000000..cf8d2ad44 --- /dev/null +++ b/idl/source/prj/globals.cxx @@ -0,0 +1,84 @@ +/* -*- 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 <globals.hxx> + +IdlDll & GetIdlApp() +{ + static IdlDll aIdlDll; + return aIdlDll; +} + +IdlDll::IdlDll() +{} + +IdlDll::~IdlDll() +{ +} + +static SvStringHashEntry * INS( const OString& rName ) +{ + sal_uInt32 nIdx; + GetIdlApp().pHashTable->Insert( rName, &nIdx ); + return GetIdlApp().pHashTable->Get( nIdx ); +} +#define A_ENTRY( Name ) , MM_##Name( INS( #Name ) ) + +SvGlobalHashNames::SvGlobalHashNames() + : MM_module( INS( "module" ) ) + , MM_interface( INS( "interface" ) ) + , MM_shell( INS( "shell" ) ) + , MM_Toggle( INS( "Toggle" ) ) + , MM_AutoUpdate( INS( "AutoUpdate" ) ) + , MM_Asynchron( INS( "Asynchron" ) ) + A_ENTRY(RecordPerSet) + A_ENTRY(RecordPerItem) + A_ENTRY(NoRecord) + A_ENTRY(RecordAbsolute) + A_ENTRY(enum) + A_ENTRY(UINT16) + A_ENTRY(INT16) + A_ENTRY(UINT32) + A_ENTRY(INT32) + A_ENTRY(BOOL) + A_ENTRY(BYTE) + A_ENTRY(float) + A_ENTRY(double) + A_ENTRY(item) + A_ENTRY(import) + A_ENTRY(SlotIdFile) + A_ENTRY(include) + A_ENTRY(ExecMethod) + A_ENTRY(StateMethod) + A_ENTRY(GroupId) + A_ENTRY(define) + A_ENTRY(MenuConfig) + A_ENTRY(ToolBoxConfig) + A_ENTRY(AccelConfig) + A_ENTRY(FastCall) + A_ENTRY(SbxObject) + A_ENTRY(Container) + A_ENTRY(ReadOnlyDoc) + A_ENTRY(struct) + A_ENTRY(DisableFlags) +{} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/prj/parser.cxx b/idl/source/prj/parser.cxx new file mode 100644 index 000000000..31bbee9a9 --- /dev/null +++ b/idl/source/prj/parser.cxx @@ -0,0 +1,590 @@ +/* -*- 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!" ); + } + } + + 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"); + rSlot.SetRecordPerItem( rSlot.aRecordPerItem ); + } + if( ReadIfBoolAttribute(rSlot.aRecordPerSet, SvHash_RecordPerSet() ) ) + { + if (rSlot.aRecordPerItem.IsSet() || rSlot.aNoRecord.IsSet()) + throw SvParseException(rInStm, "conflicting attributes"); + rSlot.SetRecordPerSet( rSlot.aRecordPerSet ); + } + if( ReadIfBoolAttribute(rSlot.aNoRecord, SvHash_NoRecord() ) ) + { + if (rSlot.aRecordPerItem.IsSet() || rSlot.aRecordPerSet.IsSet()) + throw SvParseException(rInStm, "conflicting attributes"); + 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" ); + 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: "); +} + +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"); + 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"); + rIdentifier.setString(rTok.GetString()); + rInStm.GetToken_Next(); + } + } + else + rInStm.Seek( nTokPos ); +} + +void SvIdlParser::ReadDelimiter() +{ + if( !ReadIfDelimiter() ) + throw SvParseException(rInStm, "expected delimiter"); +} + +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", rTok); + rInStm.GetToken_Next(); + return rTok.GetString(); +} + +OString SvIdlParser::ReadString() +{ + SvToken& rTok = rInStm.GetToken(); + if( !rTok.IsString() ) + throw SvParseException("expected string", 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: */ diff --git a/idl/source/prj/svidl.cxx b/idl/source/prj/svidl.cxx new file mode 100644 index 000000000..2c9fbf63d --- /dev/null +++ b/idl/source/prj/svidl.cxx @@ -0,0 +1,213 @@ +/* -*- 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 <stdio.h> +#include <database.hxx> +#include <command.hxx> +#include <rtl/ustring.hxx> +#include <osl/file.hxx> +#include <memory> + +#define BR 0x8000 +static bool FileMove_Impl( const OUString & rFile1, const OUString & rFile2, bool bMoveAlways ) +{ + //printf( "Move from %s to %s\n", rFile2.GetStr(), rFile1.GetStr() ); + sal_uLong nC1 = 0; + sal_uLong nC2 = 1; + if( !bMoveAlways ) + { + SvFileStream aOutStm1( rFile1, StreamMode::STD_READ ); + SvFileStream aOutStm2( rFile2, StreamMode::STD_READ ); + if( aOutStm1.GetError() == ERRCODE_NONE ) + { + std::unique_ptr<sal_uInt8[]> pBuf1(new sal_uInt8[ BR ]); + std::unique_ptr<sal_uInt8[]> pBuf2(new sal_uInt8[ BR ]); + nC1 = aOutStm1.ReadBytes(pBuf1.get(), BR); + nC2 = aOutStm2.ReadBytes(pBuf2.get(), BR); + while( nC1 == nC2 ) + { + if( memcmp( pBuf1.get(), pBuf2.get(), nC1 ) ) + { + nC1++; + break; + } + else + { + if( 0x8000 != nC1 ) + break; + nC1 = aOutStm1.ReadBytes(pBuf1.get(), BR); + nC2 = aOutStm2.ReadBytes(pBuf2.get(), BR); + } + } + } + } + OUString fileURL2; + osl::FileBase::getFileURLFromSystemPath( rFile2, fileURL2 ); + if( nC1 != nC2 ) + {// something has changed + OUString fileURL1; + osl::FileBase::getFileURLFromSystemPath( rFile1, fileURL1 ); + // move file + if( osl::FileBase::E_None != osl::File::move( fileURL2, fileURL1 ) ) + { + // delete both files + osl::File::remove( fileURL1 ); + osl::File::remove( fileURL2 ); + return false; + } + return true; + } + return osl::FileBase::E_None == osl::File::remove( fileURL2 ); +} + +//This function gets a system path to a file [fname], creates a temp file in +//the same folder as [fname] and returns the system path of the temp file. +static OUString tempFileHelper(std::u16string_view fname) +{ + OUString aTmpFile; + + size_t delimIndex = fname.rfind( '/' ); + if( delimIndex > 0 && delimIndex != std::u16string_view::npos) + { + OUString aTmpDir( fname.substr( 0, delimIndex ) ); + osl::FileBase::getFileURLFromSystemPath( aTmpDir, aTmpDir ); + osl::FileBase::createTempFile( &aTmpDir, nullptr, &aTmpFile ); + osl::FileBase::getSystemPathFromFileURL( aTmpFile, aTmpFile ); + } + else + { + OString aStr = "invalid filename: " + + OUStringToOString(fname, RTL_TEXTENCODING_UTF8); + fprintf(stderr, "%s\n", aStr.getStr()); + } + return aTmpFile; +} + +int main ( int argc, char ** argv) +{ + OUString aTmpSlotMapFile; + OUString aTmpDepFile; + + SvCommand aCommand( argc, argv ); + + if( aCommand.nVerbosity != 0 ) + printf( "StarView Interface Definition Language (IDL) Compiler 3.0\n" ); + + Init(); + std::unique_ptr<SvIdlWorkingBase> pDataBase( new SvIdlWorkingBase(aCommand)); + + int nExit = 0; + if( !aCommand.aExportFile.isEmpty() ) + { + osl::DirectoryItem aDI; + osl::FileStatus fileStatus( osl_FileStatus_Mask_FileName ); + (void)osl::DirectoryItem::get( aCommand.aExportFile, aDI ); + (void)aDI.getFileStatus(fileStatus); + pDataBase->SetExportFile( fileStatus.getFileName() ); + } + + if( ReadIdl( pDataBase.get(), aCommand ) ) + { + if( nExit == 0 && !aCommand.aSlotMapFile.isEmpty() ) + { + aTmpSlotMapFile = tempFileHelper(aCommand.aSlotMapFile); + SvFileStream aOutStm( aTmpSlotMapFile, StreamMode::READWRITE | StreamMode::TRUNC ); + if( !pDataBase->WriteSfx( aOutStm ) ) + { + nExit = -1; + OString aStr = "cannot write slotmap file: " + + OUStringToOString(aCommand.aSlotMapFile, RTL_TEXTENCODING_UTF8); + fprintf(stderr, "%s\n", aStr.getStr()); + } + } + if (nExit == 0 && !aCommand.m_DepFile.isEmpty()) + { + aTmpDepFile = tempFileHelper(aCommand.m_DepFile); + SvFileStream aOutStm( aTmpDepFile, StreamMode::READWRITE | StreamMode::TRUNC ); + pDataBase->WriteDepFile(aOutStm, aCommand.aTargetFile); + if( aOutStm.GetError() != ERRCODE_NONE ) + { + nExit = -1; + fprintf( stderr, "cannot write dependency file: %s\n", + OUStringToOString( aCommand.m_DepFile, + RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + } + else + nExit = -1; + + if( nExit == 0 ) + { + bool bErr = false; + bool bDoMove = aCommand.aTargetFile.isEmpty(); + OUString aErrFile, aErrFile2; + if (!aCommand.aSlotMapFile.isEmpty()) + { + bErr = !FileMove_Impl( aCommand.aSlotMapFile, aTmpSlotMapFile, bDoMove ); + if( bErr ) { + aErrFile = aCommand.aSlotMapFile; + aErrFile2 = aTmpSlotMapFile; + } + } + if (!bErr && !aCommand.m_DepFile.isEmpty()) + { + bErr |= !FileMove_Impl( aCommand.m_DepFile, aTmpDepFile, bDoMove ); + if (bErr) { + aErrFile = aCommand.m_DepFile; + aErrFile2 = aTmpDepFile; + } + } + + if( bErr ) + { + nExit = -1; + OString aStr = "cannot move file from: " + + OUStringToOString(aErrFile2, RTL_TEXTENCODING_UTF8) + + "\n to file: " + + OUStringToOString(aErrFile, RTL_TEXTENCODING_UTF8); + fprintf( stderr, "%s\n", aStr.getStr() ); + } + else + { + if( !aCommand.aTargetFile.isEmpty() ) + { + // stamp file, because idl passed through correctly + SvFileStream aOutStm( aCommand.aTargetFile, + StreamMode::READWRITE | StreamMode::TRUNC ); + } + } + } + + if( nExit != 0 ) + { + if( !aCommand.aSlotMapFile.isEmpty() ) + { + osl::FileBase::getSystemPathFromFileURL( aTmpSlotMapFile, aTmpSlotMapFile ); + osl::File::remove( aTmpSlotMapFile ); + } + } + + if( nExit != 0 ) + fprintf( stderr, "svidl terminated with errors\n" ); + return nExit; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |