diff --git a/basic/CppunitTest_basic_scanner.mk b/basic/CppunitTest_basic_scanner.mk index 55a6e0faf311..03701864f8f7 100644 --- a/basic/CppunitTest_basic_scanner.mk +++ b/basic/CppunitTest_basic_scanner.mk @@ -11,6 +11,12 @@ $(eval $(call gb_CppunitTest_CppunitTest,basic_scanner)) $(eval $(call gb_CppunitTest_use_ure,basic_scanner)) +$(eval $(call gb_CppunitTest_use_externals,basic_scanner,\ + icu_headers \ + icuuc \ + icui18n \ +)) + $(eval $(call gb_CppunitTest_add_exception_objects,basic_scanner, \ basic/qa/cppunit/test_scanner \ )) diff --git a/basic/Library_sb.mk b/basic/Library_sb.mk index b0e6e454a99b..be0cbaeef005 100644 --- a/basic/Library_sb.mk +++ b/basic/Library_sb.mk @@ -25,6 +25,12 @@ $(eval $(call gb_Library_set_include,sb,\ -I$(SRCDIR)/basic/source/inc \ )) +$(eval $(call gb_Library_use_externals,sb,\ + icu_headers \ + icuuc \ + icui18n \ +)) + $(eval $(call gb_Library_set_precompiled_header,sb,basic/inc/pch/precompiled_sb)) $(eval $(call gb_Library_use_custom_headers,sb,\ diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index 5d8a2ba2ffc3..20bbedc9d6f0 100644 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -49,9 +49,7 @@ #include #include -#include -#include -#include +#include #include @@ -1470,7 +1468,7 @@ namespace int seenright = 0; - sResult.append('^'); + sResult.append("\\A"); // Match at the beginning of the input while (start < end) { @@ -1534,7 +1532,7 @@ namespace } } - sResult.append('$'); + sResult.append("\\z"); // Match if the current position is at the end of input return sResult.makeStringAndClear(); } @@ -1546,13 +1544,7 @@ void SbiRuntime::StepLIKE() SbxVariableRef refVar2 = PopVar(); OUString value = refVar2->GetOUString(); - - i18nutil::SearchOptions2 aSearchOpt; - - aSearchOpt.AlgorithmType2 = css::util::SearchAlgorithms2::REGEXP; - - aSearchOpt.Locale = Application::GetSettings().GetLanguageTag().getLocale(); - aSearchOpt.searchString = VBALikeToRegexp(refVar1->GetOUString()); + OUString regex = VBALikeToRegexp(refVar1->GetOUString()); bool bTextMode(true); bool bCompatibility = ( GetSbData()->pInst && GetSbData()->pInst->IsCompatibility() ); @@ -1560,14 +1552,35 @@ void SbiRuntime::StepLIKE() { bTextMode = IsImageFlag( SbiImageFlags::COMPARETEXT ); } + sal_uInt32 searchFlags = UREGEX_UWORD | UREGEX_DOTALL; // Dot matches newline if( bTextMode ) { - aSearchOpt.transliterateFlags |= TransliterationFlags::IGNORE_CASE; + searchFlags |= UREGEX_CASE_INSENSITIVE; + } + + static sal_uInt32 cachedSearchFlags = 0; + static OUString cachedRegex; + static std::optional oRegexMatcher; + UErrorCode nIcuErr = U_ZERO_ERROR; + if (regex != cachedRegex || searchFlags != cachedSearchFlags || !oRegexMatcher) + { + cachedRegex = regex; + cachedSearchFlags = searchFlags; + icu::UnicodeString sRegex(false, reinterpret_cast(cachedRegex.getStr()), + cachedRegex.getLength()); + oRegexMatcher.emplace(sRegex, cachedSearchFlags, nIcuErr); + } + + icu::UnicodeString sSource(false, reinterpret_cast(value.getStr()), + value.getLength()); + oRegexMatcher->reset(sSource); + + bool bRes = oRegexMatcher->matches(nIcuErr); + if (nIcuErr) + { + Error(ERRCODE_BASIC_INTERNAL_ERROR); } SbxVariable* pRes = new SbxVariable; - utl::TextSearch aSearch( aSearchOpt); - sal_Int32 nStart=0, nEnd=value.getLength(); - bool bRes = aSearch.SearchForward(value, &nStart, &nEnd); pRes->PutBool( bRes ); PushVar( pRes );