diff options
author | Noel Power <noel.power@novell.com> | 2012-03-02 13:04:18 +0000 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2012-05-11 17:49:49 +0200 |
commit | 2edf8cba49e8ba72fa7b0e02d24a38cab45c697c (patch) | |
tree | cb2c3d4d491d5c57b5ce4dbf668daac2348f6a14 | |
parent | 16e3dc5b81abde7144eab5a597c80417c2480e9a (diff) |
weed out unmatched Sub/End Sub statements when importing VBA fdo#46889
fix mishandling of 'End Sub' is there is a trailing comment fod#46889
Signed-off-by: Miklos Vajna <vmiklos@suse.cz>
-rw-r--r-- | oox/source/ole/vbamodule.cxx | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/oox/source/ole/vbamodule.cxx b/oox/source/ole/vbamodule.cxx index cbd9744b03d0..12e1110616d4 100644 --- a/oox/source/ole/vbamodule.cxx +++ b/oox/source/ole/vbamodule.cxx @@ -218,6 +218,7 @@ void VbaModule::createEmptyModule( const Reference< XNameContainer >& rxBasicLib OUString VbaModule::readSourceCode( StorageBase& rVbaStrg, const Reference< XNameContainer >& rxOleNameOverrides ) const { OUStringBuffer aSourceCode; + const static rtl::OUString sUnmatchedRemovedTag( RTL_CONSTASCII_USTRINGPARAM( "Rem removed unmatched Sub/End: " ) ); if( (maStreamName.getLength() > 0) && (mnOffset != SAL_MAX_UINT32) ) { BinaryXInputStream aInStrm( rVbaStrg.openInputStream( maStreamName ), true ); @@ -231,6 +232,14 @@ OUString VbaModule::readSourceCode( StorageBase& rVbaStrg, const Reference< XNam VbaInputStream aVbaStrm( aInStrm ); // load the source code line-by-line, with some more processing TextInputStream aVbaTextStrm( mxContext, aVbaStrm, meTextEnc ); + + struct ProcedurePair + { + bool bInProcedure; + sal_uInt32 nPos; + ProcedurePair() : bInProcedure( false ), nPos( 0 ) {}; + } procInfo; + while( !aVbaTextStrm.isEof() ) { OUString aCodeLine = aVbaTextStrm.readLine(); @@ -241,6 +250,45 @@ OUString VbaModule::readSourceCode( StorageBase& rVbaStrg, const Reference< XNam } else { + // Hack here to weed out any unmatched End Sub / Sub Foo statements. + // The behaviour of the vba ide practically guarantees the case and + // spacing of Sub statement(s). However, indentation can be arbitrary hence + // the trim. + rtl::OUString trimLine( aCodeLine.trim() ); + if ( mbExecutable && ( + trimLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("Sub ") ) || + trimLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("Public Sub ") ) || + trimLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("Private Sub ") ) || + trimLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("Static Sub ") ) ) ) + { + // this should never happen, basic doesn't support nested procedures + // first Sub Foo must be bogus + if ( procInfo.bInProcedure ) + { + // comment out the line + aSourceCode.insert( procInfo.nPos, sUnmatchedRemovedTag ); + // mark location of this Sub + procInfo.nPos = aSourceCode.getLength(); + } + else + { + procInfo.bInProcedure = true; + procInfo.nPos = aSourceCode.getLength(); + } + } + else if ( mbExecutable && aCodeLine.trim().matchAsciiL( RTL_CONSTASCII_STRINGPARAM("End Sub")) ) + { + // un-matched End Sub + if ( !procInfo.bInProcedure ) + { + aSourceCode.append( sUnmatchedRemovedTag ); + } + else + { + procInfo.bInProcedure = false; + procInfo.nPos = 0; + } + } // normal source code line if( !mbExecutable ) aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Rem " ) ); |