diff --git a/i18npool/source/localedata/LocaleNode.cxx b/i18npool/source/localedata/LocaleNode.cxx index b0d9156ddbb9..e5123969644c 100644 --- a/i18npool/source/localedata/LocaleNode.cxx +++ b/i18npool/source/localedata/LocaleNode.cxx @@ -794,7 +794,7 @@ void LCFormatNode::generateCode (const OFileWriter &of) const if (n100s < 0) incErrorInt( "Error: Time100SecSeparator not present in FormatCode formatindex=\"%d\".\n", formatindex); - n100s = aCode.indexOf( pSep->getValue() + "00"); + n100s = aCode.indexOf( OUString(pSep->getValue() + "00")); if (n100s < 0) incErrorInt( "Error: Time100SecSeparator+00 not present in FormatCode formatindex=\"%d\".\n", formatindex); diff --git a/include/rtl/stringutils.hxx b/include/rtl/stringutils.hxx index 29a7904e6019..2a6f841ecaed 100644 --- a/include/rtl/stringutils.hxx +++ b/include/rtl/stringutils.hxx @@ -94,6 +94,7 @@ struct SAL_WARN_UNUSED OUStringChar_ { constexpr OUStringChar_(sal_Unicode theC): c(theC) {} constexpr OUStringChar_(char theC): c(theC) { assert(c <= 0x7F); } template OUStringChar_(T &&) = delete; + constexpr operator std::u16string_view() const { return {&c, 1}; } sal_Unicode const c; }; using OUStringChar = OUStringChar_ const; diff --git a/include/rtl/ustring.h b/include/rtl/ustring.h index 5e481c21c4c4..6bf0d2aef0eb 100644 --- a/include/rtl/ustring.h +++ b/include/rtl/ustring.h @@ -2001,6 +2001,41 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllUtf16LUtf16L( sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength) SAL_THROW_EXTERN_C(); +#if defined LIBO_INTERNAL_ONLY +/** Create a new string by replacing all occurrences of a given substring with + another substring. + + Replacing subsequent occurrences picks up only after a given replacement. + That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". + + @param[in, out] newStr pointer to the new string; must not be null; must + point to null or a valid rtl_uString; upon return, points to the newly + allocated string or to null if there was either an out-of-memory condition + or the resulting number of UTF-16 code units would have been larger than + SAL_MAX_INT32 + + @param str pointer to the original string; must not be null + + @param from pointer to the substring to be replaced; must not be null and + must point to memory of at least \p fromLength UTF-16 code units + + @param fromLength the length of the \p from substring; must be non-negative + + @param to pointer to the substring to be replaced; must not be null and + must point to memory of at least \p toLength UTF-16 code units + + @param toLength the length of the \p to substring; must be non-negative + + @param fromIndex the position in the string where we will begin searching + + @since LibreOffice 7.1 +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllFromIndexUtf16LUtf16L( + rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from, + sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLengt, sal_Int32 fromIndex) + SAL_THROW_EXTERN_C(); +#endif + /** Create a new string by converting all ASCII uppercase letters to lowercase within another string. diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx index 8e7a61f79005..d53eab6c3038 100644 --- a/include/rtl/ustring.hxx +++ b/include/rtl/ustring.hxx @@ -789,11 +789,18 @@ public: < 0 - if this string is less than the string argument > 0 - if this string is greater than the string argument */ +#if defined LIBO_INTERNAL_ONLY + sal_Int32 reverseCompareTo(std::u16string_view sv) const { + return rtl_ustr_reverseCompare_WithLength( + pData->buffer, pData->length, sv.data(), sv.size()); + } +#else sal_Int32 reverseCompareTo( const OUString & str ) const { return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length, str.pData->buffer, str.pData->length ); } +#endif /** @overload @@ -811,25 +818,6 @@ public: libreoffice_internal::ConstCharArrayDetector::length); } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - reverseCompareTo(T & literal) const { - return rtl_ustr_reverseCompare_WithLength( - pData->buffer, pData->length, - libreoffice_internal::ConstCharArrayDetector::toPointer(literal), - libreoffice_internal::ConstCharArrayDetector::length); - } - - /** @overload @since LibreOffice 5.4 */ - sal_Int32 reverseCompareTo(OUStringLiteral const & literal) const { - return rtl_ustr_reverseCompare_WithLength( - pData->buffer, pData->length, literal.data, literal.size); - } -#endif - /** Perform a comparison of two strings. @@ -865,6 +853,14 @@ public: @return true if the strings are equal; false, otherwise. */ +#if defined LIBO_INTERNAL_ONLY + bool equalsIgnoreAsciiCase(std::u16string_view sv) const { + return + rtl_ustr_compareIgnoreAsciiCase_WithLength( + pData->buffer, pData->length, sv.data(), sv.size()) + == 0; + } +#else bool equalsIgnoreAsciiCase( const OUString & str ) const { if ( pData->length != str.pData->length ) @@ -874,6 +870,7 @@ public: return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, str.pData->buffer, str.pData->length ) == 0; } +#endif /** Perform an ASCII lowercase comparison of two strings. @@ -890,12 +887,18 @@ public: @since LibreOffice 4.0 */ +#if defined LIBO_INTERNAL_ONLY + sal_Int32 compareToIgnoreAsciiCase(std::u16string_view sv) const { + return rtl_ustr_compareIgnoreAsciiCase_WithLength( + pData->buffer, pData->length, sv.data(), sv.size()); + } +#else sal_Int32 compareToIgnoreAsciiCase( const OUString & str ) const { return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, str.pData->buffer, str.pData->length ); } - +#endif /** @overload @@ -917,29 +920,6 @@ public: == 0); } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - equalsIgnoreAsciiCase(T & literal) const { - return - rtl_ustr_compareIgnoreAsciiCase_WithLength( - pData->buffer, pData->length, - libreoffice_internal::ConstCharArrayDetector::toPointer( - literal), - libreoffice_internal::ConstCharArrayDetector::length) - == 0; - } - - /** @overload @since LibreOffice 5.4 */ - bool equalsIgnoreAsciiCase(OUStringLiteral const & literal) const { - return - rtl_ustr_compareIgnoreAsciiCase_WithLength( - pData->buffer, pData->length, literal.data, literal.size) - == 0; - } -#endif - /** Match against a substring appearing in this string. @@ -955,11 +935,21 @@ public: at the given position; false, otherwise. */ +#if defined LIBO_INTERNAL_ONLY + bool match(std::u16string_view sv, sal_Int32 fromIndex = 0) const { + return + rtl_ustr_shortenedCompare_WithLength( + pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size(), + sv.size()) + == 0; + } +#else bool match( const OUString & str, sal_Int32 fromIndex = 0 ) const { return rtl_ustr_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, str.pData->buffer, str.pData->length, str.pData->length ) == 0; } +#endif /** @overload @@ -980,32 +970,6 @@ public: == 0; } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - match(T & literal, sal_Int32 fromIndex = 0) const { - assert(fromIndex >= 0); - return - rtl_ustr_shortenedCompare_WithLength( - pData->buffer + fromIndex, pData->length - fromIndex, - libreoffice_internal::ConstCharArrayDetector::toPointer( - literal), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::length) - == 0; - } - - /** @overload @since LibreOffice 5.4 */ - bool match(OUStringLiteral const & literal, sal_Int32 fromIndex = 0) const { - return - rtl_ustr_shortenedCompare_WithLength( - pData->buffer + fromIndex, pData->length - fromIndex, - literal.data, literal.size, literal.size) - == 0; - } -#endif - /** Match against a substring appearing in this string, ignoring the case of ASCII letters. @@ -1024,12 +988,22 @@ public: at the given position; false, otherwise. */ +#if defined LIBO_INTERNAL_ONLY + bool matchIgnoreAsciiCase(std::u16string_view sv, sal_Int32 fromIndex = 0) const { + return + rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( + pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size(), + sv.size()) + == 0; + } +#else bool matchIgnoreAsciiCase( const OUString & str, sal_Int32 fromIndex = 0 ) const { return rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, str.pData->buffer, str.pData->length, str.pData->length ) == 0; } +#endif /** @overload @@ -1050,34 +1024,6 @@ public: == 0; } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - matchIgnoreAsciiCase(T & literal, sal_Int32 fromIndex = 0) const { - assert(fromIndex >= 0); - return - rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( - pData->buffer + fromIndex, pData->length - fromIndex, - libreoffice_internal::ConstCharArrayDetector::toPointer( - literal), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::length) - == 0; - } - - /** @overload @since LibreOffice 5.4 */ - bool matchIgnoreAsciiCase( - OUStringLiteral const & literal, sal_Int32 fromIndex = 0) const - { - return - rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( - pData->buffer+fromIndex, pData->length-fromIndex, literal.data, - literal.size, literal.size) - == 0; - } -#endif - /** Compares two strings. @@ -1363,6 +1309,15 @@ public: @since LibreOffice 4.0 */ +#if defined LIBO_INTERNAL_ONLY + bool startsWith(std::u16string_view sv, OUString * rest = nullptr) const { + auto const b = match(sv); + if (b && rest != nullptr) { + *rest = copy(sv.size()); + } + return b; + } +#else bool startsWith(OUString const & str, OUString * rest = NULL) const { bool b = match(str); if (b && rest != NULL) { @@ -1370,6 +1325,7 @@ public: } return b; } +#endif /** @overload @@ -1397,43 +1353,6 @@ public: return b; } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - startsWith(T & literal, OUString * rest = nullptr) const { - bool b - = (libreoffice_internal::ConstCharArrayDetector::length - <= sal_uInt32(pData->length)) - && (rtl_ustr_reverseCompare_WithLength( - pData->buffer, - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer( - literal), - libreoffice_internal::ConstCharArrayDetector::length) - == 0); - if (b && rest != nullptr) { - *rest = copy( - libreoffice_internal::ConstCharArrayDetector::length); - } - return b; - } - - /** @overload @since LibreOffice 5.4 */ - bool startsWith(OUStringLiteral const & literal, OUString * rest = nullptr) - const - { - bool b = literal.size <= pData->length - && (rtl_ustr_reverseCompare_WithLength( - pData->buffer, literal.size, literal.data, literal.size) - == 0); - if (b && rest != nullptr) { - *rest = copy(literal.size); - } - return b; - } -#endif - /** Check whether this string starts with a given string, ignoring the case of ASCII letters. @@ -1454,6 +1373,15 @@ public: @since LibreOffice 4.0 */ +#if defined LIBO_INTERNAL_ONLY + bool startsWithIgnoreAsciiCase(std::u16string_view sv, OUString * rest = nullptr) const { + auto const b = matchIgnoreAsciiCase(sv); + if (b && rest != nullptr) { + *rest = copy(sv.size()); + } + return b; + } +#else bool startsWithIgnoreAsciiCase(OUString const & str, OUString * rest = NULL) const { @@ -1463,6 +1391,7 @@ public: } return b; } +#endif /** @overload @@ -1490,43 +1419,6 @@ public: return b; } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - startsWithIgnoreAsciiCase(T & literal, OUString * rest = nullptr) const { - bool b - = (libreoffice_internal::ConstCharArrayDetector::length - <= sal_uInt32(pData->length)) - && (rtl_ustr_compareIgnoreAsciiCase_WithLength( - pData->buffer, - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer( - literal), - libreoffice_internal::ConstCharArrayDetector::length) - == 0); - if (b && rest != nullptr) { - *rest = copy( - libreoffice_internal::ConstCharArrayDetector::length); - } - return b; - } - - /** @overload @since LibreOffice 5.4 */ - bool startsWithIgnoreAsciiCase( - OUStringLiteral const & literal, OUString * rest = nullptr) const - { - bool b - = (rtl_ustr_compareIgnoreAsciiCase_WithLength( - pData->buffer, literal.size, literal.data, literal.size) - == 0); - if (b && rest != nullptr) { - *rest = copy(literal.size); - } - return b; - } -#endif - /** Check whether this string ends with a given substring. @@ -1541,6 +1433,16 @@ public: @since LibreOffice 3.6 */ +#if defined LIBO_INTERNAL_ONLY + bool endsWith(std::u16string_view sv, OUString * rest = nullptr) const { + auto const b = sv.size() <= sal_uInt32(pData->length) + && match(sv, pData->length - sv.size()); + if (b && rest != nullptr) { + *rest = copy(0, (pData->length - sv.size())); + } + return b; + } +#else bool endsWith(OUString const & str, OUString * rest = NULL) const { bool b = str.getLength() <= getLength() && match(str, getLength() - str.getLength()); @@ -1549,6 +1451,7 @@ public: } return b; } +#endif /** @overload @@ -1579,47 +1482,6 @@ public: return b; } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - endsWith(T & literal, OUString * rest = nullptr) const { - bool b - = (libreoffice_internal::ConstCharArrayDetector::length - <= sal_uInt32(pData->length)) - && (rtl_ustr_reverseCompare_WithLength( - (pData->buffer + pData->length - - libreoffice_internal::ConstCharArrayDetector::length), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer( - literal), - libreoffice_internal::ConstCharArrayDetector::length) - == 0); - if (b && rest != nullptr) { - *rest = copy( - 0, - (getLength() - - libreoffice_internal::ConstCharArrayDetector::length)); - } - return b; - } - - /** @overload @since LibreOffice 5.4 */ - bool endsWith(OUStringLiteral const & literal, OUString * rest = nullptr) - const - { - bool b = literal.size <= pData->length - && (rtl_ustr_reverseCompare_WithLength( - pData->buffer + pData->length - literal.size, literal.size, - literal.data, literal.size) - == 0); - if (b && rest != nullptr) { - *rest = copy(0, (getLength() - literal.size)); - } - return b; - } -#endif - /** Check whether this string ends with a given ASCII string. @@ -1660,6 +1522,16 @@ public: @since LibreOffice 3.6 */ +#if defined LIBO_INTERNAL_ONLY + bool endsWithIgnoreAsciiCase(std::u16string_view sv, OUString * rest = nullptr) const { + auto const b = sv.size() <= sal_uInt32(pData->length) + && matchIgnoreAsciiCase(sv, pData->length - sv.size()); + if (b && rest != nullptr) { + *rest = copy(0, pData->length - sv.size()); + } + return b; + } +#else bool endsWithIgnoreAsciiCase(OUString const & str, OUString * rest = NULL) const { bool b = str.getLength() <= getLength() @@ -1669,6 +1541,7 @@ public: } return b; } +#endif /** @overload @@ -1701,47 +1574,6 @@ public: return b; } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - endsWithIgnoreAsciiCase(T & literal, OUString * rest = nullptr) const { - bool b - = (libreoffice_internal::ConstCharArrayDetector::length - <= sal_uInt32(pData->length)) - && (rtl_ustr_compareIgnoreAsciiCase_WithLength( - (pData->buffer + pData->length - - libreoffice_internal::ConstCharArrayDetector::length), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer( - literal), - libreoffice_internal::ConstCharArrayDetector::length) - == 0); - if (b && rest != nullptr) { - *rest = copy( - 0, - (getLength() - - libreoffice_internal::ConstCharArrayDetector::length)); - } - return b; - } - - /** @overload @since LibreOffice 5.4 */ - bool endsWithIgnoreAsciiCase( - OUStringLiteral const & literal, OUString * rest = nullptr) const - { - bool b = literal.size <= pData->length - && (rtl_ustr_compareIgnoreAsciiCase_WithLength( - pData->buffer + pData->length - literal.size, - literal.size, literal.data, literal.size) - == 0); - if (b && rest != nullptr) { - *rest = copy(0, getLength() - literal.size); - } - return b; - } -#endif - /** Check whether this string ends with a given ASCII string, ignoring the case of ASCII letters. @@ -2105,12 +1937,20 @@ public: returned. If it does not occur as a substring starting at fromIndex or beyond, -1 is returned. */ +#if defined LIBO_INTERNAL_ONLY + sal_Int32 indexOf(std::u16string_view sv, sal_Int32 fromIndex = 0) const { + auto const n = rtl_ustr_indexOfStr_WithLength( + pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size()); + return n < 0 ? n : n + fromIndex; + } +#else sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const { sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, str.pData->buffer, str.pData->length ); return (ret < 0 ? ret : ret+fromIndex); } +#endif /** @overload @@ -2129,31 +1969,6 @@ public: return n < 0 ? n : n + fromIndex; } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - indexOf(T & literal, sal_Int32 fromIndex = 0) const { - assert(fromIndex >= 0); - auto n = rtl_ustr_indexOfStr_WithLength( - pData->buffer + fromIndex, pData->length - fromIndex, - libreoffice_internal::ConstCharArrayDetector::toPointer(literal), - libreoffice_internal::ConstCharArrayDetector::length); - return n < 0 ? n : n + fromIndex; - } - - /** @overload @since LibreOffice 5.4 */ - sal_Int32 indexOf(OUStringLiteral const & literal, sal_Int32 fromIndex = 0) - const - { - sal_Int32 n = rtl_ustr_indexOfStr_WithLength( - pData->buffer + fromIndex, pData->length - fromIndex, literal.data, - literal.size); - return n < 0 ? n : n + fromIndex; - } -#endif - /** Returns the index within this string of the first occurrence of the specified ASCII substring, starting at the specified index. @@ -2208,11 +2023,18 @@ public: the last such substring is returned. If it does not occur as a substring, -1 is returned. */ +#if defined LIBO_INTERNAL_ONLY + sal_Int32 lastIndexOf(std::u16string_view sv) const { + return rtl_ustr_lastIndexOfStr_WithLength( + pData->buffer, pData->length, sv.data(), sv.size()); + } +#else sal_Int32 lastIndexOf( const OUString & str ) const { return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length, str.pData->buffer, str.pData->length ); } +#endif /** Returns the index within this string of the last occurrence of @@ -2231,11 +2053,17 @@ public: of the first character of the last such substring is returned. Otherwise, -1 is returned. */ +#if defined LIBO_INTERNAL_ONLY + sal_Int32 lastIndexOf(std::u16string_view sv, sal_Int32 fromIndex) const { + return rtl_ustr_lastIndexOfStr_WithLength(pData->buffer, fromIndex, sv.data(), sv.size()); + } +#else sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const { return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex, str.pData->buffer, str.pData->length ); } +#endif /** @overload @@ -2253,25 +2081,6 @@ public: libreoffice_internal::ConstCharArrayDetector::length); } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - lastIndexOf(T & literal) const { - return rtl_ustr_lastIndexOfStr_WithLength( - pData->buffer, pData->length, - libreoffice_internal::ConstCharArrayDetector::toPointer(literal), - libreoffice_internal::ConstCharArrayDetector::length); - } - - /** @overload @since LibreOffice 5.4 */ - sal_Int32 lastIndexOf(OUStringLiteral const & literal) const { - return rtl_ustr_lastIndexOfStr_WithLength( - pData->buffer, pData->length, literal.data, literal.size); - } -#endif - /** Returns the index within this string of the last occurrence of the specified ASCII substring. @@ -2411,6 +2220,18 @@ public: @since LibreOffice 3.6 */ +#if defined LIBO_INTERNAL_ONLY + [[nodiscard]] OUString replaceFirst( + std::u16string_view from, std::u16string_view to, sal_Int32 * index = nullptr) const + { + rtl_uString * s = nullptr; + sal_Int32 i = 0; + rtl_uString_newReplaceFirstUtf16LUtf16L( + &s, pData, from.data(), from.size(), to.data(), to.size(), + index == nullptr ? &i : index); + return OUString(s, SAL_NO_ACQUIRE); + } +#else SAL_WARN_UNUSED_RESULT OUString replaceFirst( OUString const & from, OUString const & to, sal_Int32 * index = NULL) const { @@ -2420,6 +2241,7 @@ public: &s, pData, from.pData, to.pData, index == NULL ? &i : index); return OUString(s, SAL_NO_ACQUIRE); } +#endif /** Returns a new string resulting from replacing the first occurrence of a @@ -2439,6 +2261,21 @@ public: @since LibreOffice 3.6 */ +#if defined LIBO_INTERNAL_ONLY + template [[nodiscard]] + typename libreoffice_internal::ConstCharArrayDetector::Type replaceFirst( + T & from, std::u16string_view to, sal_Int32 * index = nullptr) const + { + assert(libreoffice_internal::ConstCharArrayDetector::isValid(from)); + rtl_uString * s = nullptr; + sal_Int32 i = 0; + rtl_uString_newReplaceFirstAsciiLUtf16L( + &s, pData, libreoffice_internal::ConstCharArrayDetector::toPointer(from), + libreoffice_internal::ConstCharArrayDetector::length, to.data(), to.size(), + index == nullptr ? &i : index); + return OUString(s, SAL_NO_ACQUIRE); + } +#else template< typename T > SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( T& from, OUString const & to, sal_Int32 * index = NULL) const @@ -2453,6 +2290,7 @@ public: index == NULL ? &i : index); return OUString(s, SAL_NO_ACQUIRE); } +#endif /** Returns a new string resulting from replacing the first occurrence of a @@ -2472,6 +2310,21 @@ public: @since LibreOffice 5.1 */ +#if defined LIBO_INTERNAL_ONLY + template [[nodiscard]] + typename libreoffice_internal::ConstCharArrayDetector::Type replaceFirst( + std::u16string_view from, T & to, sal_Int32 * index = nullptr) const + { + assert(libreoffice_internal::ConstCharArrayDetector::isValid(to)); + rtl_uString * s = nullptr; + sal_Int32 i = 0; + rtl_uString_newReplaceFirstUtf16LAsciiL( + &s, pData, from.data(), from.size(), + libreoffice_internal::ConstCharArrayDetector::toPointer(to), + libreoffice_internal::ConstCharArrayDetector::length, index == nullptr ? &i : index); + return OUString(s, SAL_NO_ACQUIRE); + } +#else template< typename T > SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( OUString const & from, T& to, sal_Int32 * index = NULL) const @@ -2486,6 +2339,7 @@ public: index == NULL ? &i : index); return OUString(s, SAL_NO_ACQUIRE); } +#endif /** Returns a new string resulting from replacing the first occurrence of a @@ -2523,224 +2377,6 @@ public: return OUString(s, SAL_NO_ACQUIRE); } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - replaceFirst(T & from, OUString const & to, sal_Int32 * index = nullptr) - const - { - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, - to.pData->buffer, to.pData->length, index == nullptr ? &i : index); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - replaceFirst(OUString const & from, T & to, sal_Int32 * index = nullptr) - const - { - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LUtf16L( - &s, pData, from.pData->buffer, from.pData->length, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length, - index == nullptr ? &i : index); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector< - T1, - typename libreoffice_internal::ConstCharArrayDetector< - T2, OUString>::TypeUtf16 - >::TypeUtf16 - replaceFirst(T1 & from, T2 & to, sal_Int32 * index = nullptr) const { - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length, - index == nullptr ? &i : index); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector< - T1, - typename libreoffice_internal::ConstCharArrayDetector< - T2, OUString>::Type - >::TypeUtf16 - replaceFirst(T1 & from, T2 & to, sal_Int32 * index = nullptr) const { - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LAsciiL( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length, - index == nullptr ? &i : index); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector< - T1, - typename libreoffice_internal::ConstCharArrayDetector< - T2, OUString>::TypeUtf16 - >::Type - replaceFirst(T1 & from, T2 & to, sal_Int32 * index = nullptr) const { - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstAsciiLUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length, - index == nullptr ? &i : index); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - - /** @overload @since LibreOffice 5.4 */ - [[nodiscard]] OUString replaceFirst( - OUStringLiteral const & from, OUString const & to, - sal_Int32 * index = nullptr) const - { - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LUtf16L( - &s, pData, from.data, from.size, to.pData->buffer, to.pData->length, - index == nullptr ? &i : index); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - [[nodiscard]] OUString replaceFirst( - OUString const & from, OUStringLiteral const & to, - sal_Int32 * index = nullptr) const - { - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LUtf16L( - &s, pData, from.pData->buffer, from.pData->length, to.data, to.size, - index == nullptr ? &i : index); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - [[nodiscard]] OUString replaceFirst( - OUStringLiteral const & from, OUStringLiteral const & to, - sal_Int32 * index = nullptr) const - { - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LUtf16L( - &s, pData, from.data, from.size, to.data, to.size, - index == nullptr ? &i : index); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - template [[nodiscard]] - typename libreoffice_internal::ConstCharArrayDetector::Type - replaceFirst( - OUStringLiteral const & from, T & to, sal_Int32 * index = nullptr) const - { - assert(libreoffice_internal::ConstCharArrayDetector::isValid(to)); - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LAsciiL( - &s, pData, from.data, from.size, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length, - index == nullptr ? &i : index); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - template [[nodiscard]] - typename libreoffice_internal::ConstCharArrayDetector::Type - replaceFirst( - T & from, OUStringLiteral const & to, sal_Int32 * index = nullptr) const - { - assert(libreoffice_internal::ConstCharArrayDetector::isValid(from)); - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstAsciiLUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, to.data, - to.size, index == nullptr ? &i : index); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - replaceFirst( - OUStringLiteral const & from, T & to, sal_Int32 * index = nullptr) const - { - assert(libreoffice_internal::ConstCharArrayDetector::isValid(to)); - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LUtf16L( - &s, pData, from.data, from.size, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length, - index == nullptr ? &i : index); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - replaceFirst( - T & from, OUStringLiteral const & to, sal_Int32 * index = nullptr) const - { - assert(libreoffice_internal::ConstCharArrayDetector::isValid(from)); - rtl_uString * s = nullptr; - sal_Int32 i = 0; - rtl_uString_newReplaceFirstUtf16LUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, to.data, - to.size, index == nullptr ? &i : index); - return OUString(s, SAL_NO_ACQUIRE); - } -#endif - /** Returns a new string resulting from replacing all occurrences of a given substring with another substring. @@ -2756,6 +2392,16 @@ public: @since LibreOffice 4.0 */ +#if defined LIBO_INTERNAL_ONLY + [[nodiscard]] OUString replaceAll( + std::u16string_view from, std::u16string_view to, sal_Int32 fromIndex = 0) const + { + rtl_uString * s = nullptr; + rtl_uString_newReplaceAllFromIndexUtf16LUtf16L( + &s, pData, from.data(), from.size(), to.data(), to.size(), fromIndex); + return OUString(s, SAL_NO_ACQUIRE); + } +#else SAL_WARN_UNUSED_RESULT OUString replaceAll( OUString const & from, OUString const & to, sal_Int32 fromIndex = 0) const { @@ -2763,6 +2409,7 @@ public: rtl_uString_newReplaceAllFromIndex(&s, pData, from.pData, to.pData, fromIndex); return OUString(s, SAL_NO_ACQUIRE); } +#endif /** Returns a new string resulting from replacing all occurrences of a given @@ -2777,6 +2424,19 @@ public: @since LibreOffice 3.6 */ +#if defined LIBO_INTERNAL_ONLY + template [[nodiscard]] + typename libreoffice_internal::ConstCharArrayDetector::Type replaceAll( + T & from, std::u16string_view to) const + { + assert(libreoffice_internal::ConstCharArrayDetector::isValid(from)); + rtl_uString * s = nullptr; + rtl_uString_newReplaceAllAsciiLUtf16L( + &s, pData, libreoffice_internal::ConstCharArrayDetector::toPointer(from), + libreoffice_internal::ConstCharArrayDetector::length, to.data(), to.size()); + return OUString(s, SAL_NO_ACQUIRE); + } +#else template< typename T > SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( T& from, OUString const & to) const { @@ -2788,6 +2448,7 @@ public: libreoffice_internal::ConstCharArrayDetector::length, to.pData); return OUString(s, SAL_NO_ACQUIRE); } +#endif /** Returns a new string resulting from replacing all occurrences of a given @@ -2802,6 +2463,20 @@ public: @since LibreOffice 5.1 */ +#if defined LIBO_INTERNAL_ONLY + template [[nodiscard]] + typename libreoffice_internal::ConstCharArrayDetector::Type replaceAll( + std::u16string_view from, T & to) const + { + assert(libreoffice_internal::ConstCharArrayDetector::isValid(to)); + rtl_uString * s = nullptr; + rtl_uString_newReplaceAllUtf16LAsciiL( + &s, pData, from.data(), from.size(), + libreoffice_internal::ConstCharArrayDetector::toPointer(to), + libreoffice_internal::ConstCharArrayDetector::length); + return OUString(s, SAL_NO_ACQUIRE); + } +#else template< typename T > SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( OUString const & from, T& to) const { @@ -2813,6 +2488,7 @@ public: libreoffice_internal::ConstCharArrayDetector::length); return OUString(s, SAL_NO_ACQUIRE); } +#endif /** Returns a new string resulting from replacing all occurrences of a given @@ -2843,188 +2519,6 @@ public: return OUString(s, SAL_NO_ACQUIRE); } -#if defined LIBO_INTERNAL_ONLY - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - replaceAll(T & from, OUString const & to) const { - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, - to.pData->buffer, to.pData->length); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - replaceAll(OUString const & from, T & to) const { - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LUtf16L( - &s, pData, from.pData->buffer, from.pData->length, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector< - T1, - typename libreoffice_internal::ConstCharArrayDetector< - T2, OUString>::TypeUtf16 - >::TypeUtf16 - replaceAll(T1 & from, T2 & to) const { - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector< - T1, - typename libreoffice_internal::ConstCharArrayDetector< - T2, OUString>::Type - >::TypeUtf16 - replaceAll(T1 & from, T2 & to) const { - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LAsciiL( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.3 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector< - T1, - typename libreoffice_internal::ConstCharArrayDetector< - T2, OUString>::TypeUtf16 - >::Type - replaceAll(T1 & from, T2 & to) const { - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllAsciiLUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length); - if (s == nullptr) { - throw std::bad_alloc(); - // should be std::length_error if resulting would be too large - } - return OUString(s, SAL_NO_ACQUIRE); - } - - /** @overload @since LibreOffice 5.4 */ - [[nodiscard]] OUString replaceAll( - OUStringLiteral const & from, OUString const & to) const - { - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LUtf16L( - &s, pData, from.data, from.size, to.pData->buffer, to.pData->length); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - [[nodiscard]] OUString replaceAll( - OUString const & from, OUStringLiteral const & to) const - { - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LUtf16L( - &s, pData, from.pData->buffer, from.pData->length, to.data, to.size); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - [[nodiscard]] OUString replaceAll( - OUStringLiteral const & from, OUStringLiteral const & to) const - { - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LUtf16L( - &s, pData, from.data, from.size, to.data, to.size); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - template [[nodiscard]] - typename libreoffice_internal::ConstCharArrayDetector::Type - replaceAll(OUStringLiteral const & from, T & to) const { - assert(libreoffice_internal::ConstCharArrayDetector::isValid(to)); - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LAsciiL( - &s, pData, from.data, from.size, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - template [[nodiscard]] - typename libreoffice_internal::ConstCharArrayDetector::Type - replaceAll(T & from, OUStringLiteral const & to) const { - assert(libreoffice_internal::ConstCharArrayDetector::isValid(from)); - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllAsciiLUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, to.data, - to.size); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - replaceAll(OUStringLiteral const & from, T & to) const { - assert(libreoffice_internal::ConstCharArrayDetector::isValid(to)); - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LUtf16L( - &s, pData, from.data, from.size, - libreoffice_internal::ConstCharArrayDetector::toPointer(to), - libreoffice_internal::ConstCharArrayDetector::length); - return OUString(s, SAL_NO_ACQUIRE); - } - /** @overload @since LibreOffice 5.4 */ - template [[nodiscard]] - typename - libreoffice_internal::ConstCharArrayDetector::TypeUtf16 - replaceAll(T & from, OUStringLiteral const & to) const { - assert(libreoffice_internal::ConstCharArrayDetector::isValid(from)); - rtl_uString * s = nullptr; - rtl_uString_newReplaceAllUtf16LUtf16L( - &s, pData, - libreoffice_internal::ConstCharArrayDetector::toPointer(from), - libreoffice_internal::ConstCharArrayDetector::length, to.data, - to.size); - return OUString(s, SAL_NO_ACQUIRE); - } -#endif - /** Converts from this string all ASCII uppercase characters (65-90) to ASCII lowercase characters (97-122). diff --git a/sal/CompilerTest_sal_rtl_oustring.mk b/sal/CompilerTest_sal_rtl_oustring.mk new file mode 100644 index 000000000000..fb77d89048a6 --- /dev/null +++ b/sal/CompilerTest_sal_rtl_oustring.mk @@ -0,0 +1,16 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*- +# +# 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/. +# + +$(eval $(call gb_CompilerTest_CompilerTest,sal_rtl_oustring)) + +$(eval $(call gb_CompilerTest_add_exception_objects,sal_rtl_oustring, \ + sal/qa/rtl/strings/compile-oustring \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/sal/Module_sal.mk b/sal/Module_sal.mk index 4d7a84ee4e61..7611bc950f07 100644 --- a/sal/Module_sal.mk +++ b/sal/Module_sal.mk @@ -30,6 +30,8 @@ $(eval $(call gb_Module_add_check_targets,sal,\ CppunitTest_sal_osl \ CppunitTest_sal_rtl \ CppunitTest_sal_types \ + $(if $(COM_IS_CLANG),$(if $(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),, \ + CompilerTest_sal_rtl_oustring)) \ )) endif diff --git a/sal/qa/rtl/strings/compile-oustring.cxx b/sal/qa/rtl/strings/compile-oustring.cxx new file mode 100644 index 000000000000..667a52324e4e --- /dev/null +++ b/sal/qa/rtl/strings/compile-oustring.cxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include + +#include +#include + +// expected-note@rtl/ustring.hxx:* 1+ {{}} + +void checkExtraIntArgument() +{ + // This makes sure that using by mistake RTL_CONSTASCII_STRINGPARAM does not trigger a different + // overload, i.e. the second argument to match() in this case is the indexFrom argument, + // but with the macro it would contain the length of the string. Therefore + // match( RTL_CONSTASCII_STRINGPARAM( "bar" )) would be match( "bar", 3 ), which would be + // true when called for OUString( "foobar" ). But this should not happen because of the + // &foo[0] trick in the RTL_CONSTASCII_STRINGPARAM macro. + // expected-error@+1 {{}} + OUString("foobar").match(RTL_CONSTASCII_STRINGPARAM("bar")); +} + +void checkNonconstChar() +{ + // check that non-const char[] data do not trigger string literal overloads + char test[] = "test"; + char bar[] = "bar"; + const char consttest[] = "test"; + const char constbar[] = "bar"; + // expected-error@+1 {{}} + (void)OUString("footest").replaceAll(test, bar); + // expected-error@+1 {{}} + (void)OUString("footest").replaceAll(consttest, bar); + // expected-error@+1 {{}} + (void)OUString("footest").replaceAll(test, constbar); + (void)OUString("footest").replaceAll(consttest, constbar); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sal/qa/rtl/strings/test_oustring_compare.cxx b/sal/qa/rtl/strings/test_oustring_compare.cxx index c06d40c4d653..6316f09b1d58 100644 --- a/sal/qa/rtl/strings/test_oustring_compare.cxx +++ b/sal/qa/rtl/strings/test_oustring_compare.cxx @@ -67,12 +67,12 @@ void test::oustring::Compare::compareToIgnoreAsciiCase() { CPPUNIT_ASSERT_EQUAL( sal_Int32(0), - OUString("abc").compareToIgnoreAsciiCase("ABC")); + OUString("abc").compareToIgnoreAsciiCase(u"ABC")); CPPUNIT_ASSERT( - OUString("ABC").compareToIgnoreAsciiCase("abcdef") + OUString("ABC").compareToIgnoreAsciiCase(u"abcdef") < 0); CPPUNIT_ASSERT( - OUString("A").compareToIgnoreAsciiCase("_") > 0); + OUString("A").compareToIgnoreAsciiCase(u"_") > 0); } void test::oustring::Compare::compareTo() diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx index 4ba1b04067d4..a1c79f8cc9e5 100644 --- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx +++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx @@ -12,6 +12,8 @@ #include +#include +#include #include #include @@ -33,12 +35,11 @@ class StringLiterals: public CppUnit::TestFixture private: void checkCtors(); void checkUsage(); - void checkExtraIntArgument(); - void checkNonconstChar(); void checkBuffer(); void checkOUStringLiteral(); void checkOUStringChar(); void checkUtf16(); + void checkEmbeddedNul(); void testcall( const char str[] ); @@ -48,12 +49,11 @@ private: CPPUNIT_TEST_SUITE(StringLiterals); CPPUNIT_TEST(checkCtors); CPPUNIT_TEST(checkUsage); -CPPUNIT_TEST(checkExtraIntArgument); -CPPUNIT_TEST(checkNonconstChar); CPPUNIT_TEST(checkBuffer); CPPUNIT_TEST(checkOUStringLiteral); CPPUNIT_TEST(checkOUStringChar); CPPUNIT_TEST(checkUtf16); +CPPUNIT_TEST(checkEmbeddedNul); CPPUNIT_TEST_SUITE_END(); }; @@ -157,40 +157,6 @@ void test::oustring::StringLiterals::checkUsage() CPPUNIT_ASSERT( !rtl_string_unittest_const_literal ); } -void test::oustring::StringLiterals::checkExtraIntArgument() -{ - // This makes sure that using by mistake RTL_CONSTASCII_STRINGPARAM does not trigger a different - // overload, i.e. the second argument to match() in this case is the indexFrom argument, - // but with the macro it would contain the length of the string. Therefore - // match( RTL_CONSTASCII_STRINGPARAM( "bar" )) would be match( "bar", 3 ), which would be - // true when called for OUString( "foobar" ). But this should not happen because of the - // &foo[0] trick in the RTL_CONSTASCII_STRINGPARAM macro. - CPPUNIT_ASSERT( !rtl::OUString("foobar").match( "bar" )); - CPPUNIT_ASSERT( !rtl::OUString("foobar").match( RTL_CONSTASCII_STRINGPARAM( "bar" ))); -} - -void test::oustring::StringLiterals::checkNonconstChar() -{ // check that non-const char[] data do not trigger string literal overloads - CPPUNIT_ASSERT_EQUAL( rtl::OUString( "foobar" ), rtl::OUString( "footest" ).replaceAll( "test", "bar" )); - char test[] = "test"; - char bar[] = "bar"; - const char consttest[] = "test"; - const char constbar[] = "bar"; - CPPUNIT_ASSERT( - !VALID_CONVERSION_CALL( - [&test, &bar]() { - return rtl::OUString("footest").replaceAll(test, bar); })); - CPPUNIT_ASSERT( - !VALID_CONVERSION_CALL( - [&consttest, &bar]() { - return rtl::OUString("footest").replaceAll(consttest, bar); })); - CPPUNIT_ASSERT( - !VALID_CONVERSION_CALL( - [&test, &constbar]() { - return rtl::OUString("footest").replaceAll(test, constbar); })); - CPPUNIT_ASSERT_EQUAL( rtl::OUString( "foobar" ), rtl::OUString( "footest" ).replaceAll( consttest, constbar )); -} - void test::oustring::StringLiterals::checkBuffer() { rtl::OUStringBuffer buf; @@ -424,6 +390,20 @@ void test::oustring::StringLiterals::checkUtf16() { CPPUNIT_ASSERT_EQUAL(sal_Int32(5), b.lastIndexOf(u"ab")); } +void test::oustring::StringLiterals::checkEmbeddedNul() { + using namespace std::literals; + rtl::OUString const s("foobar"); + constexpr char16_t const a[] = u"foo\0hidden"; + char16_t const * const p = a; + CPPUNIT_ASSERT(s.startsWith(a)); + CPPUNIT_ASSERT(s.startsWith(p)); + CPPUNIT_ASSERT(s.startsWith(u"foo\0hidden")); + CPPUNIT_ASSERT(!s.startsWith(u"foo\0hidden"s)); + CPPUNIT_ASSERT(!s.startsWith(u"foo\0hidden"sv)); + CPPUNIT_ASSERT(!s.startsWith(rtlunittest::OUStringLiteral(a))); + CPPUNIT_ASSERT(!s.startsWith(rtlunittest::OUStringLiteral(u"foo\0hidden"))); +} + } // namespace CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::StringLiterals); diff --git a/sal/qa/rtl/strings/test_strings_replace.cxx b/sal/qa/rtl/strings/test_strings_replace.cxx index a27f5f14286b..3be6e176ad41 100644 --- a/sal/qa/rtl/strings/test_strings_replace.cxx +++ b/sal/qa/rtl/strings/test_strings_replace.cxx @@ -273,6 +273,9 @@ void Test::ustringReplaceAll() { CPPUNIT_ASSERT_EQUAL( OUString("xxa"), OUString("xaa").replaceAll(s_xa, s_xx)); + + CPPUNIT_ASSERT_EQUAL( + OUString("foobarbaz"), OUString("foobarfoo").replaceAll(u"foo", u"baz", 1)); } void Test::ustringReplaceAllAsciiL() { diff --git a/sal/rtl/ustring.cxx b/sal/rtl/ustring.cxx index d3bf1daedc78..cbadddc6a98e 100644 --- a/sal/rtl/ustring.cxx +++ b/sal/rtl/ustring.cxx @@ -1547,10 +1547,19 @@ void rtl_uString_newReplaceAllUtf16LUtf16L( rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from, sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength) SAL_THROW_EXTERN_C() +{ + rtl_uString_newReplaceAllFromIndexUtf16LUtf16L(newStr, str, from, fromLength, to, toLength, 0); +} + +void rtl_uString_newReplaceAllFromIndexUtf16LUtf16L( + rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from, + sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength, sal_Int32 fromIndex) + SAL_THROW_EXTERN_C() { assert(toLength >= 0); + assert(fromIndex >= 0 && fromIndex <= str->length); rtl_uString_assign(newStr, str); - for (sal_Int32 i = 0;; i += toLength) { + for (sal_Int32 i = fromIndex;; i += toLength) { rtl_uString_newReplaceFirstUtf16LUtf16L( newStr, *newStr, from, fromLength, to, toLength, &i); if (i == -1 || *newStr == nullptr) { diff --git a/sal/util/sal.map b/sal/util/sal.map index 48d76b1a3802..dbd22c36ee16 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -749,6 +749,11 @@ PRIVATE_1.6 { # LibreOffice 6.4 rtl_ustr_toInt64_WithLength; } PRIVATE_1.5; +PRIVATE_1.7 { # LibreOffice 7.1 + global: + rtl_uString_newReplaceAllFromIndexUtf16LUtf16L; +} PRIVATE_1.5; + PRIVATE_textenc.1 { # LibreOffice 3.6 global: _ZN3sal6detail7textenc20convertCharToUnicode*; diff --git a/sc/source/filter/excel/xecontent.cxx b/sc/source/filter/excel/xecontent.cxx index 3fdd33784ede..d73683deadd1 100644 --- a/sc/source/filter/excel/xecontent.cxx +++ b/sc/source/filter/excel/xecontent.cxx @@ -452,7 +452,7 @@ XclExpHyperlink::XclExpHyperlink( const XclExpRoot& rRoot, const SvxURLField& rU mnFlags |= EXC_HLINK_MARK; OUString location = XclXmlUtils::ToOUString(*mxTextMark); - if (!location.isEmpty() && msTarget.endsWith("#" + location)) + if (!location.isEmpty() && msTarget.endsWith(OUString("#" + location))) msTarget = msTarget.copy(0, msTarget.getLength() - location.getLength() - 1); } diff --git a/stoc/source/typeconv/convert.cxx b/stoc/source/typeconv/convert.cxx index 554c13400fdd..e8fe65830a99 100644 --- a/stoc/source/typeconv/convert.cxx +++ b/stoc/source/typeconv/convert.cxx @@ -589,7 +589,7 @@ Any SAL_CALL TypeConverter_Impl::convertTo( const Any& rVal, const Type& aDestTy for ( nPos = reinterpret_cast(aEnumTD.get())->nEnumValues; nPos--; ) { if (o3tl::forceAccess(rVal)->equalsIgnoreAsciiCase( - reinterpret_cast(aEnumTD.get())->ppEnumNames[nPos] )) + OUString::unacquired(&reinterpret_cast(aEnumTD.get())->ppEnumNames[nPos]) )) break; } } diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx index b0e90b4916f6..03fe0f68c041 100644 --- a/svl/source/numbers/zformat.cxx +++ b/svl/source/numbers/zformat.cxx @@ -5558,7 +5558,7 @@ OUString SvNumberformat::impTransliterateImpl(const OUString& rStr, sal_Int32 nField = -1; do { - nField = rNum.GetParams().indexOf(rKeywords[nDateKey] + "=", ++nField); + nField = rNum.GetParams().indexOf(OUString(rKeywords[nDateKey] + "="), ++nField); } while (nField != -1 && nField != 0 && (rNum.GetParams()[nField - 1] != ',' && diff --git a/svtools/source/dialogs/PlaceEditDialog.cxx b/svtools/source/dialogs/PlaceEditDialog.cxx index b41f16072d71..80df9d61c87c 100644 --- a/svtools/source/dialogs/PlaceEditDialog.cxx +++ b/svtools/source/dialogs/PlaceEditDialog.cxx @@ -194,7 +194,7 @@ void PlaceEditDialog::InitDetails( ) auto nSize = std::min(aTypesUrlsList.getLength(), aTypesNamesList.getLength()); for ( sal_Int32 i = 0; i < nSize; ++i ) { - OUString sUrl = aTypesUrlsList[i].replaceFirst("", SvtResId(STR_SVT_PORT) + ">"); + OUString sUrl = aTypesUrlsList[i].replaceFirst("", OUString(SvtResId(STR_SVT_PORT) + ">")); if ((sUrl == GDRIVE_BASE_URL && bSkipGDrive) || (sUrl.startsWith( ALFRESCO_CLOUD_BASE_URL) && bSkipAlfresco) || diff --git a/svx/source/gallery2/gallery1.cxx b/svx/source/gallery2/gallery1.cxx index 600b8cc01c95..b732294648c8 100644 --- a/svx/source/gallery2/gallery1.cxx +++ b/svx/source/gallery2/gallery1.cxx @@ -288,7 +288,7 @@ void Gallery::ImplLoadSubDirs( const INetURLObject& rBaseURL, bool& rbDirIsReadO { const char *appBundle = [[[NSBundle mainBundle] bundlePath] UTF8String]; OUString path = rBaseURL.GetURLPath(); - if( path.startsWith( OUString( appBundle, strlen( appBundle ), RTL_TEXTENCODING_UTF8 ) + "/" ) ) + if( path.startsWith( OUString(OUString( appBundle, strlen( appBundle ), RTL_TEXTENCODING_UTF8 ) + "/") ) ) rbDirIsReadOnly = true; } #else diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx index 1897a874582a..2e7546527b73 100644 --- a/sw/source/filter/ww8/ww8par5.cxx +++ b/sw/source/filter/ww8/ww8par5.cxx @@ -98,7 +98,7 @@ namespace // #120879# - helper method to identify a bookmark name to match the internal TOC bookmark naming convention bool IsTOCBookmarkName(const OUString& rName) { - return rName.startsWith("_Toc") || rName.startsWith(IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()+"_Toc"); + return rName.startsWith("_Toc") || rName.startsWith(OUString(IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()+"_Toc")); } OUString EnsureTOCBookmarkName(const OUString& rName) diff --git a/sw/source/ui/dbui/mmaddressblockpage.cxx b/sw/source/ui/dbui/mmaddressblockpage.cxx index f83529d4aaa7..20bcb4fd735a 100644 --- a/sw/source/ui/dbui/mmaddressblockpage.cxx +++ b/sw/source/ui/dbui/mmaddressblockpage.cxx @@ -632,7 +632,7 @@ bool SwCustomizeAddressBlockDialog::HasItem(sal_Int32 nUserData) } } //search for this entry in the content - return m_xDragED->GetText().indexOf("<" + sEntry + ">") >= 0; + return m_xDragED->GetText().indexOf(OUString("<" + sEntry + ">")) >= 0; } IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, SelectionChangedIdleHdl, Timer*, void) diff --git a/xmlsecurity/source/helper/documentsignaturehelper.cxx b/xmlsecurity/source/helper/documentsignaturehelper.cxx index 784a5571d2a9..f1c48daa3a0c 100644 --- a/xmlsecurity/source/helper/documentsignaturehelper.cxx +++ b/xmlsecurity/source/helper/documentsignaturehelper.cxx @@ -314,7 +314,7 @@ void DocumentSignatureHelper::AppendContentTypes(const uno::Reference