[PATCH] weed out unmatched Sub/End Sub statements when importing VBA fdo#46889

Noel Power noel.power at novell.com
Fri Mar 2 05:04:18 PST 2012


fix mishandling of 'End Sub' is there is a trailing comment fod#46889
---
 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 daeb70d..6a6bacc 100644
--- a/oox/source/ole/vbamodule.cxx
+++ b/oox/source/ole/vbamodule.cxx
@@ -221,6 +221,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 );
@@ -234,6 +235,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();
@@ -275,6 +284,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 " ) );
-- 
1.7.3.4


--------------050900090000080505000402--


More information about the LibreOffice mailing list