tdf#125637 - Correctly hand names ending with an underscore

If a name is ending with an underscore at the end of the line, it won't
be recognized correctly and it will be wrongly interpreted as the
respective name without the underscore at the end. Instead of changing
the macro source, use a flag in order to correclty identify the line end.

Change-Id: I6f933d7382b510bffed3e2692d32c232b7084624
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123833
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124050
diff --git a/basic/qa/basic_coverage/test_tdf125637.vb b/basic/qa/basic_coverage/test_tdf125637.vb
new file mode 100644
index 0000000..58fd1db
--- /dev/null
+++ b/basic/qa/basic_coverage/test_tdf125637.vb
@@ -0,0 +1,54 @@
'
' 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/.
'

Option Explicit

Dim passCount As Integer
Dim failCount As Integer
Dim result As String

Function doUnitTest() As String
    result = verify_tdf125637()
    If failCount <> 0 Or passCount = 0 Then
        doUnitTest = 0
    Else
        doUnitTest = 1
    End If
End Function

Function verify_tdf125637() As String

    passCount = 0
    failCount = 0

    result = "Test Results" & Chr$(10) & "============" & Chr$(10)

    ' tdf#125637 - correctly hand names ending with an underscore character at the end of the line
    Dim test As Long
    Dim test_ As Long
    test_ = 1234
    test = test_

    ' Without the fix in place, this test would have failed with:
    ' - Expected: 1234
    ' - Actual  : 0
    TestLog_ASSERT test, 1234, "Assignment of the variable failed (tdf#125637)"

    result = result & Chr$(10) & "Tests passed: " & passCount & Chr$(10) & "Tests failed: " & failCount & Chr$(10)
    verify_tdf125637 = result

End Function

Sub TestLog_ASSERT(actual As Variant, expected As Variant, testName As String)
    If expected = actual Then
        passCount = passCount + 1
    Else
        result = result & Chr$(10) & "Failed: " & testName & " returned " & actual & ", expected " & expected
        failCount = failCount + 1
    End If
End Sub
diff --git a/basic/qa/cppunit/test_scanner.cxx b/basic/qa/cppunit/test_scanner.cxx
index 5663c44..01d16e7 100644
--- a/basic/qa/cppunit/test_scanner.cxx
+++ b/basic/qa/cppunit/test_scanner.cxx
@@ -297,7 +297,8 @@ void ScannerTest::testAlphanum()
    CPPUNIT_ASSERT_EQUAL(size_t(2), symbols.size());
    CPPUNIT_ASSERT_EQUAL(OUString("joxclk_"), symbols[0].text);
    CPPUNIT_ASSERT_EQUAL(SbxVARIANT, symbols[0].type);
    CPPUNIT_ASSERT_EQUAL(OUString("joxclk "), source7); // Change the trailing '_' to a ' '
    // tdf#125637 - don't change underscore to space
    CPPUNIT_ASSERT_EQUAL(OUString("joxclk_"), source7);
    CPPUNIT_ASSERT_EQUAL(cr, symbols[1].text);
    CPPUNIT_ASSERT_EQUAL(SbxVARIANT, symbols[1].type);

diff --git a/basic/source/comp/scanner.cxx b/basic/source/comp/scanner.cxx
index f74259d..8196d2c 100644
--- a/basic/source/comp/scanner.cxx
+++ b/basic/source/comp/scanner.cxx
@@ -51,6 +51,7 @@ SbiScanner::SbiScanner(const OUString& rBuf, StarBASIC* p)
    , bCompatible(false)
    , bVBASupportOn(false)
    , bPrevLineExtentsComment(false)
    , bClosingUnderscore(false)
    , bInStatement(false)
{
}
@@ -286,19 +287,11 @@ bool SbiScanner::NextSym()
        if(nCol < aLine.getLength() && bCompatible && aSym.equalsIgnoreAsciiCase("go"))
            scanGoto();

        // replace closing '_' by space when end of line is following
        // (wrong line continuation otherwise)
        // tdf#125637 - check for closing underscore
        if (nCol == aLine.getLength() && aLine[nCol - 1] == '_')
        {
            // We are going to modify a potentially shared string, so force
            // a copy, so that aSym is not modified by the following operation
            OUString aSymCopy( aSym.getStr(), aSym.getLength() );
            aSym = aSymCopy;

            // HACK: modifying a potentially shared string here!
            const_cast<sal_Unicode*>(aLine.getStr())[nLineIdx - 1] = ' ';
            bClosingUnderscore = true;
        }

        // type recognition?
        // don't test the exclamation mark
        // if there's a symbol behind it
@@ -685,7 +678,7 @@ PrevLineCommentLbl:


eoln:
    if( nCol && aLine[--nLineIdx] == '_' )
    if (nCol && aLine[--nLineIdx] == '_' && !bClosingUnderscore)
    {
        nLineIdx = -1;
        bool bRes = NextSym();
@@ -706,6 +699,7 @@ eoln:
        nCol2 = nOldCol2;
        aSym = "\n";
        nColLock = 0;
        bClosingUnderscore = false;
        return true;
    }
}
diff --git a/basic/source/inc/scanner.hxx b/basic/source/inc/scanner.hxx
index 339b442..e5575e9 100644
--- a/basic/source/inc/scanner.hxx
+++ b/basic/source/inc/scanner.hxx
@@ -61,6 +61,7 @@ protected:
    bool   bCompatible;                 // true: OPTION compatible
    bool   bVBASupportOn;               // true: OPTION VBASupport 1 otherwise default False
    bool   bPrevLineExtentsComment;     // true: Previous line is comment and ends on "... _"
    bool   bClosingUnderscore;          // true: Closing underscore followed by end of line

    bool   bInStatement;
    void   GenError( ErrCode );