tdf#143332 - Use utl::TextSearch to implement the InStrRev function

Change-Id: I2dae038d061f036b3b7c0fbbcb6a821305d4839e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119094
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
(cherry picked from commit f5e030a343bec9f0f2c7b30e2dfb21ba5c94e5e8)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119177
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
diff --git a/basic/qa/vba_tests/instrrev.vb b/basic/qa/vba_tests/instrrev.vb
index 506d407..7d047fc 100644
--- a/basic/qa/vba_tests/instrrev.vb
+++ b/basic/qa/vba_tests/instrrev.vb
@@ -28,7 +28,14 @@ Sub verify_testInStrRev()
    SearchChar = "P"    ' Search for "P".
    TestUtil.AssertEqual(InStrRev(SearchString, SearchChar, 4, 1),   3, "InStrRev(SearchString, SearchChar, 4, 1)")
    TestUtil.AssertEqual(InStrRev(SearchString, SearchChar, -1, 0), 12, "InStrRev(SearchString, SearchChar, -1, 0)")
    TestUtil.AssertEqual(InStrRev(SearchString, "W", 1),             0, "InStrRev(SearchString, ""W"", 1)")
    TestUtil.AssertEqual(InStrRev(SearchString, "W", 1), 0, "InStrRev(SearchString, ""W"", 1)")

    ' tdf#143332 - case-insensitive operation for non-ASCII characters
    TestUtil.AssertEqual(InStrRev("α", "Α", -1, 1),      1, "InStrRev(""α"", ""Α"", -1, 1)")
    TestUtil.AssertEqual(InStrRev("abc", "d", -1, 1),    0, "InStrRev(""abc"", ""d"", -1, 1)")
    ' tdf#143332 - German Eszett is uppercased to a two-character 'SS'.
    ' This test should fail after tdf#110003 has been fixed.
    TestUtil.AssertEqual(InStrRev("Straße", "s", -1, 1), 5, "InStrRev(""Straße"", ""s"", -1, 1)")

    Exit Sub
errorHandler:
diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx
index ff2474a..e3a30f3 100644
--- a/basic/source/runtime/methods.cxx
+++ b/basic/source/runtime/methods.cxx
@@ -929,8 +929,8 @@ void SbRtl_InStrRev(StarBASIC *, SbxArray & rPar, bool)
    }
    else
    {
        OUString aStr1 = rPar.Get(1)->GetOUString();
        OUString aToken = rPar.Get(2)->GetOUString();
        const OUString aStr1 = rPar.Get(1)->GetOUString();
        const OUString aToken = rPar.Get(2)->GetOUString();

        sal_Int32 nStartPos = -1;
        if ( nArgCount >= 3 )
@@ -959,7 +959,7 @@ void SbRtl_InStrRev(StarBASIC *, SbxArray & rPar, bool)
        {
            bTextMode = rPar.Get(4)->GetInteger();
        }
        sal_Int32 nStrLen = aStr1.getLength();
        const sal_Int32 nStrLen = aStr1.getLength();
        if( nStartPos == -1 )
        {
            nStartPos = nStrLen;
@@ -982,10 +982,16 @@ void SbRtl_InStrRev(StarBASIC *, SbxArray & rPar, bool)
                }
                else
                {
                    aStr1 = aStr1.toAsciiUpperCase();
                    aToken = aToken.toAsciiUpperCase();
                    // tdf#143332 - case-insensitive operation for non-ASCII characters
                    i18nutil::SearchOptions2 aSearchOptions;
                    aSearchOptions.searchString = aToken;
                    aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
                    aSearchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
                    utl::TextSearch textSearch(aSearchOptions);

                    nPos = aStr1.lastIndexOf( aToken, nStartPos ) + 1;
                    sal_Int32 nStart = 0;
                    sal_Int32 nEnd = nStartPos;
                    nPos = textSearch.SearchBackward(aStr1, &nEnd, &nStart) ? nStart : 0;
                }
            }
        }