Hello, attached is a patch that removes the need to use the RTL_CONSTASCII_STRINGPARAM macro with OString, similar to the patch from the 'Obsoleting RTL_CONSTASCII_USTRINGPARAM' thread.
The difference here is that OString has a const char* ctor, which causes some complications: - having const char* and const char(&)[N] overloads always prefers the first one for string literals, which AFAICS should be of the latter type. Trying to go for const char*(&) does not work e.g. with something explicitly cast to const char*. The solution I've found is to use a template and use SFINAE (Substitution failure is not an error) idiom to in practice limit the template arguments to only char* and const char*. Using the template makes the compiler consider the const char(&)[N] ctor first. I'm not entirely sure why this is so, but the problem and solution are consistently the same with gcc, clang and msvc. - embedded \0's strike again, RTL_CONSTASCII_* macros include them in the string, the OString const char* ctor does not. There's no perfect solution, I've decided to make the string literal ctor include \0's as well, given it's mostly meant as a replacement for RTL_CONSTASCII_*, moreover if the \0 is explicitly present in the literal, pressumably it's there for a reason. This is not backwards compatible for the OString( "\0" ) case, but such code has been up to now pointless anyway, so I do not see a problem with this. This required also fixing unittests which tried to use this for whatever reason. I've checked that I can make a rebuild without this introducing any compilation warnings or errors. I'd like to also point out to people doing changes like - foo == OString( RTL_CONSTASCII_STRINGPARAM( "bar" )) + foo.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "bar" )) that this will be soon obsolete by these changes and easily replaced by plain foo == "bar" (Do we have an Easy Hack asking for the above, so that I change it? I couldn't find one.) -- Lubos Lunak l.lu...@suse.cz
From 95c308df724bc9f7cf42e0e10627bace2c331d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= <l.lu...@suse.cz> Date: Tue, 6 Mar 2012 10:44:52 +0100 Subject: [PATCH 1/3] rtl_uString_newFromLiteral() for string literals Drop the recently introduced rtl_uString_newFromAscii_WithLength() and replace it with this one. The name fits better and it'll be also a distinct function that specifically includes embedded \0's (because that's what OUString supports and if a string literal explicitly includes it, it makes sense to copy it as such). --- sal/inc/rtl/ustring.h | 9 +++-- sal/inc/rtl/ustring.hxx | 4 +- .../rtl/strings/test_oustring_stringliterals.cxx | 7 ++++ sal/rtl/source/ustring.cxx | 37 +++++++++++++++++--- sal/util/sal.map | 2 +- 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/sal/inc/rtl/ustring.h b/sal/inc/rtl/ustring.h index 80703f8..e432d2c 100644 --- a/sal/inc/rtl/ustring.h +++ b/sal/inc/rtl/ustring.h @@ -1243,14 +1243,15 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromStr_WithLength( SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromAscii( rtl_uString ** newStr, const sal_Char * value ) SAL_THROW_EXTERN_C(); -/** Allocate a new string that contains a copy of a character array. +/** Allocate a new string that contains a copy of a string literal. - This is equivalent to rtl_uString_newFromAscii(), except that - length of the character array is explicitly passed to the function. + This is similar to rtl_uString_newFromAscii(), except that + length of the string literal is explicitly passed to the function, + and embedded \0's are included in the string. @since 3.6 */ -SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromAscii_WithLength( +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromLiteral( rtl_uString ** newStr, const sal_Char * value, sal_Int32 len ) SAL_THROW_EXTERN_C(); /** Allocate a new string from an array of Unicode code points. diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx index 151e0a2..bb22619 100644 --- a/sal/inc/rtl/ustring.hxx +++ b/sal/inc/rtl/ustring.hxx @@ -184,7 +184,7 @@ public: OUString( const char (&literal)[ N ] ) { pData = 0; - rtl_uString_newFromAscii_WithLength( &pData, literal, N - 1 ); + rtl_uString_newFromLiteral( &pData, literal, N - 1 ); if (pData == 0) { #if defined EXCEPTIONS_OFF SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF"); @@ -338,7 +338,7 @@ public: template< int N > OUString& operator=( const char (&literal)[ N ] ) { - rtl_uString_newFromAscii_WithLength( &pData, literal, N - 1 ); + rtl_uString_newFromLiteral( &pData, literal, N - 1 ); if (pData == 0) { #if defined EXCEPTIONS_OFF SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF"); diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx index ce2d22a..1170ff7 100644 --- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx +++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx @@ -77,6 +77,13 @@ void test::oustring::StringLiterals::checkCtors() const char bad5[][ 6 ] = { "test", "test2" }; // CPPUNIT_ASSERT( validConversion( rtl::OUString( bad5[ 0 ] ))); CPPUNIT_ASSERT( validConversion( rtl::OUString( bad5[ 1 ] ))); + +// Check that contents are correct and equal to the case when RTL_CONSTASCII_USTRINGPARAM is used. +// Also check that embedded \0 is included. + CPPUNIT_ASSERT( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" )) == rtl::OUString( "" )); + CPPUNIT_ASSERT( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\0" )) == rtl::OUString( "\0" )); + CPPUNIT_ASSERT( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ab" )) == rtl::OUString( "ab" )); + CPPUNIT_ASSERT( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "a\0b" )) == rtl::OUString( "a\0b" )); } void test::oustring::StringLiterals::testcall( const char str[] ) diff --git a/sal/rtl/source/ustring.cxx b/sal/rtl/source/ustring.cxx index 763d9c5..649cb82 100644 --- a/sal/rtl/source/ustring.cxx +++ b/sal/rtl/source/ustring.cxx @@ -471,10 +471,37 @@ void SAL_CALL rtl_uString_newFromAscii( rtl_uString** ppThis, else nLen = 0; - rtl_uString_newFromAscii_WithLength( ppThis, pCharStr, nLen ); + if ( !nLen ) + { + IMPL_RTL_STRINGNAME( new )( ppThis ); + return; + } + + if ( *ppThis ) + IMPL_RTL_STRINGNAME( release )( *ppThis ); + + *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); + OSL_ASSERT(*ppThis != NULL); + if ( (*ppThis) ) + { + IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer; + do + { + /* Check ASCII range */ + SAL_WARN_IF( ((unsigned char)*pCharStr) > 127, "rtl.string", + "rtl_uString_newFromAscii - Found char > 127" ); + + *pBuffer = *pCharStr; + pBuffer++; + pCharStr++; + } + while ( *pCharStr ); + } } -void SAL_CALL rtl_uString_newFromAscii_WithLength( rtl_uString** ppThis, +// Used when creating from string literals. +// Intentionally copies also embedded \0's if present. +void SAL_CALL rtl_uString_newFromLiteral( rtl_uString** ppThis, const sal_Char* pCharStr, sal_Int32 nLen ) SAL_THROW_EXTERN_C() @@ -493,17 +520,17 @@ void SAL_CALL rtl_uString_newFromAscii_WithLength( rtl_uString** ppThis, if ( (*ppThis) ) { IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer; - do + sal_Int32 nCount; + for( nCount = nLen; nCount > 0; --nCount ) { /* Check ASCII range */ SAL_WARN_IF( ((unsigned char)*pCharStr) > 127, "rtl.string", - "rtl_uString_newFromAscii_WithLength - Found char > 127" ); + "rtl_uString_newFromLiteral - Found char > 127" ); *pBuffer = *pCharStr; pBuffer++; pCharStr++; } - while ( *pCharStr ); } } diff --git a/sal/util/sal.map b/sal/util/sal.map index 5ee60b9..a6d9c08 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -305,7 +305,7 @@ UDK_3_0_0 { rtl_uString_newFromStr; rtl_uString_newFromStr_WithLength; rtl_uString_newFromAscii; - rtl_uString_newFromAscii_WithLength; + rtl_uString_newFromLiteral; rtl_uString_newFromString; rtl_uString_newReplace; rtl_uString_newReplaceStrAt; -- 1.7.3.4
From e47b4a5f7b96b83412d067fd9c9612b49eed8699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= <l.lu...@suse.cz> Date: Wed, 7 Mar 2012 15:07:07 +0100 Subject: [PATCH 2/3] OString ctor for string literals without RTL_CONSTASCII stuff --- sal/CppunitTest_sal_rtl_strings.mk | 3 +- sal/inc/rtl/string.h | 5 + sal/inc/rtl/string.hxx | 84 ++++++++++++++- sal/qa/OStringBuffer/rtl_OStringBuffer.cxx | 50 +++++----- sal/qa/rtl/strings/test_ostring_stringliterals.cxx | 112 ++++++++++++++++++++ .../rtl/strings/test_oustring_stringliterals.cxx | 1 + sal/rtl/source/strtmpl.cxx | 38 +++++++ sal/rtl/source/ustring.cxx | 35 ------ sal/util/sal.map | 1 + vcl/generic/fontmanager/parseAFM.cxx | 4 +- 10 files changed, 267 insertions(+), 66 deletions(-) create mode 100644 sal/qa/rtl/strings/test_ostring_stringliterals.cxx diff --git a/sal/CppunitTest_sal_rtl_strings.mk b/sal/CppunitTest_sal_rtl_strings.mk index 8bc5370..8b267f2 100644 --- a/sal/CppunitTest_sal_rtl_strings.mk +++ b/sal/CppunitTest_sal_rtl_strings.mk @@ -28,7 +28,8 @@ $(eval $(call gb_CppunitTest_CppunitTest,sal_rtl_strings)) $(eval $(call gb_CppunitTest_add_exception_objects,sal_rtl_strings,\ - sal/qa/rtl/strings/test_strings_replace \ + sal/qa/rtl/strings/test_strings_replace \ + sal/qa/rtl/strings/test_ostring_stringliterals \ sal/qa/rtl/strings/test_oustring_compare \ sal/qa/rtl/strings/test_oustring_convert \ sal/qa/rtl/strings/test_oustring_endswith \ diff --git a/sal/inc/rtl/string.h b/sal/inc/rtl/string.h index da35693..d9e9489 100644 --- a/sal/inc/rtl/string.h +++ b/sal/inc/rtl/string.h @@ -886,6 +886,11 @@ SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromStr( rtl_String ** newStr, const s */ SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromStr_WithLength( rtl_String ** newStr, const sal_Char * value, sal_Int32 len ) SAL_THROW_EXTERN_C(); +/** + @internal +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromLiteral( rtl_String ** newStr, const sal_Char * value, sal_Int32 len ) SAL_THROW_EXTERN_C(); + /** Assign a new value to a string. First releases any value str might currently hold, then acquires diff --git a/sal/inc/rtl/string.hxx b/sal/inc/rtl/string.hxx index e879f32..6590677 100644 --- a/sal/inc/rtl/string.hxx +++ b/sal/inc/rtl/string.hxx @@ -43,9 +43,22 @@ #include <new> #endif +// The unittest uses slightly different code to help check that the proper +// calls are made. The class is put into a different namespace to make +// sure the compiler generates a different (if generating also non-inline) +// copy of the function and does not merge them together. The class +// is "brought" into the proper rtl namespace by a typedef below. +#ifdef RTL_STRING_UNITTEST +#define rtl rtlunittest +#endif + namespace rtl { +#ifdef RTL_STRING_UNITTEST +#undef rtl +#endif + /* ======================================================================= */ /** @@ -72,6 +85,29 @@ namespace rtl use this class. */ +namespace internal +{ +// This template is used for SFINAE (Substitution failure is not an error), to detect that +// the template types used in the OString ctor actually are only either char* or const char*. +// Using a template appears to be the only way to distinguish char* and char[], since +// using char*(&) does not work with something explicitly cast to char*. +struct Dummy {}; +template< typename T > +struct CharPtrDetector +{ +}; +template<> +struct CharPtrDetector< const char* > +{ + typedef Dummy Type; +}; +template<> +struct CharPtrDetector< char* > +{ + typedef Dummy Type; +}; +} + class OString { public: @@ -143,15 +179,50 @@ public: /** New string from a character buffer array. + Note: The argument type is always either char* or const char*. The template is + used only for technical reasons, as is the second argument. + @param value a NULL-terminated character array. */ - OString( const sal_Char * value ) SAL_THROW(()) + template< typename T > + OString( const T& value, typename internal::CharPtrDetector< T >::Type = internal::Dummy() ) SAL_THROW(()) { pData = 0; rtl_string_newFromStr( &pData, value ); } /** + New string from a string literal. + + Note that embedded \0's are included in the string if explicitly present + in the string literal. + + @param literal a string literal + */ + template< int N > + OString( const char (&literal)[ N ] ) SAL_THROW(()) + { + pData = 0; + rtl_string_newFromLiteral( &pData, literal, N - 1 ); +#ifdef RTL_STRING_UNITTEST + rtl_string_unittest_const_literal = true; +#endif + } + + /** + @overload + New string from a non-const char array. + + @param value non-const char array + */ + template< int N > + OString( char (&value)[ N ] ) SAL_THROW(()) + { // the array is not const, so its size may not match the string length - 1 + pData = 0; + rtl_string_newFromStr( &pData, value ); + } + + /** New string from a character buffer array. @param value a character array. @@ -538,7 +609,7 @@ public: @since LibreOffice 3.6 */ - bool endsWith(rtl::OString const & str) const { + bool endsWith(OString const & str) const { return str.getLength() <= getLength() && match(str, getLength() - str.getLength()); } @@ -1196,7 +1267,7 @@ struct OStringHash a hash code for the string. This hash code should not be stored persistently, as its computation may change in later revisions. */ - size_t operator()( const rtl::OString& rString ) const + size_t operator()( const OString& rString ) const { return (size_t)rString.hashCode(); } }; @@ -1204,6 +1275,13 @@ struct OStringHash } /* Namespace */ +#ifdef RTL_STRING_UNITTEST +namespace rtl +{ +typedef rtlunittest::OString OString; +} +#endif + #endif /* _RTL_STRING_HXX_ */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/qa/OStringBuffer/rtl_OStringBuffer.cxx b/sal/qa/OStringBuffer/rtl_OStringBuffer.cxx index 85705be..e05c293 100644 --- a/sal/qa/OStringBuffer/rtl_OStringBuffer.cxx +++ b/sal/qa/OStringBuffer/rtl_OStringBuffer.cxx @@ -458,11 +458,11 @@ namespace rtl_OStringBuffer void getLength_005() { ::rtl::OStringBuffer aStrBuf( *arrOUS[4] ); - sal_Int32 expVal = 0; + sal_Int32 expVal = 1; CPPUNIT_ASSERT_MESSAGE ( - "length of empty string (string arg = '\\0')", + "length of string with \\0 embedded", aStrBuf.getLength() == expVal ); } @@ -591,11 +591,11 @@ namespace rtl_OStringBuffer void getCapacity_005() { ::rtl::OStringBuffer aStrBuf( *arrOUS[4] ); - sal_Int32 expVal = 0+16; + sal_Int32 expVal = 1+16; CPPUNIT_ASSERT_MESSAGE ( - "capacity of empty string (string arg = '\\0')", + "capacity of string with \\0 embedded", aStrBuf.getCapacity() == expVal ); } @@ -1308,7 +1308,7 @@ namespace rtl_OStringBuffer ::rtl::OStringBuffer aStrBuf( *arrOUS[4] ); sal_Int32 expVal1 = 5; ::rtl::OString expVal2; - sal_Int32 expVal3 = 16; + sal_Int32 expVal3 = 17; sal_Int32 input = 5; aStrBuf.setLength( input ); @@ -1328,7 +1328,7 @@ namespace rtl_OStringBuffer ::rtl::OStringBuffer aStrBuf( *arrOUS[4] ); sal_Int32 expVal1 = 0; ::rtl::OString expVal2; - sal_Int32 expVal3 = 16; + sal_Int32 expVal3 = 17; sal_Int32 input = 0; aStrBuf.setLength( input ); @@ -1573,7 +1573,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -2004,7 +2004,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -2391,7 +2391,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -2777,7 +2777,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -3012,7 +3012,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -3245,7 +3245,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -5231,7 +5231,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -6242,7 +6242,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -8295,7 +8295,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); intVal = 11; @@ -8420,7 +8420,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -8994,7 +8994,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -10980,7 +10980,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -11991,7 +11991,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -14044,7 +14044,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); intVal = 11; @@ -14169,7 +14169,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -14752,7 +14752,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -15488,7 +15488,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -16239,7 +16239,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } @@ -16301,7 +16301,7 @@ namespace rtl_OStringBuffer arrOUS[0] = new OString( kTestStr7 ); arrOUS[1] = new OString( ); arrOUS[2] = new OString( kTestStr25 ); - arrOUS[3] = new OString( "\0" ); + arrOUS[3] = new OString( "" ); arrOUS[4] = new OString( kTestStr28 ); } diff --git a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx new file mode 100644 index 0000000..46da8c8 --- /dev/null +++ b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License or as specified alternatively below. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Major Contributor(s): + * Copyright (C) 2012 Lubos Lunak <l.lu...@suse.cz> (initial developer) + * + * All Rights Reserved. + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +// activate the extra needed ctor +#define RTL_STRING_UNITTEST +bool rtl_string_unittest_const_literal; + +#include "sal/config.h" +#include "sal/precppunit.hxx" + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include "rtl/string.h" +#include "rtl/string.hxx" + +namespace test { namespace ostring { + +class StringLiterals: public CppUnit::TestFixture +{ +private: + void checkCtors(); + + void testcall( const char str[] ); + +CPPUNIT_TEST_SUITE(StringLiterals); +CPPUNIT_TEST(checkCtors); +CPPUNIT_TEST_SUITE_END(); +}; + +// reset the flag, call OString ctor with the given argument and return +// whether the string literal ctor was used +#define CONST_CTOR_USED( argument ) \ + ( \ + rtl_string_unittest_const_literal = false, \ + ( void ) rtl::OString( argument ), \ + rtl_string_unittest_const_literal ) + +void test::ostring::StringLiterals::checkCtors() +{ + CPPUNIT_ASSERT( CONST_CTOR_USED( "test" )); + const char good1[] = "test"; + CPPUNIT_ASSERT( CONST_CTOR_USED( good1 )); + + CPPUNIT_ASSERT( !CONST_CTOR_USED( (const char*) "test" )); + const char* bad1 = good1; + CPPUNIT_ASSERT( !CONST_CTOR_USED( bad1 )); + char bad2[] = "test"; + CPPUNIT_ASSERT( !CONST_CTOR_USED( bad2 )); + char* bad3 = bad2; + CPPUNIT_ASSERT( !CONST_CTOR_USED( bad3 )); + const char* bad4[] = { "test1" }; + CPPUNIT_ASSERT( !CONST_CTOR_USED( bad4[ 0 ] )); + testcall( good1 ); + +// This one is technically broken, since the first element is 6 characters test\0\0, +// but there does not appear a way to detect this by compile time (runtime will complain). +// RTL_CONSTASCII_USTRINGPARAM() has the same flaw. + const char bad5[][ 6 ] = { "test", "test2" }; + CPPUNIT_ASSERT( CONST_CTOR_USED( bad5[ 0 ] )); + CPPUNIT_ASSERT( CONST_CTOR_USED( bad5[ 1 ] )); + +// Check that contents are correct and equal to the case when const char* ctor is used. + CPPUNIT_ASSERT( rtl::OString( (const char*)"" ) == rtl::OString( "" )); + CPPUNIT_ASSERT( rtl::OString( (const char*)"ab" ) == rtl::OString( "ab" )); + +// Check that contents are correct and equal to the case when RTL_CONSTASCII_STRINGPARAM is used. +// Check also that embedded \0 is included (RTL_CONSTASCII_STRINGPARAM does the same, +// const char* ctor does not, but it seems to make more sense to include it when +// it's explicitly mentioned in the string literal). + CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "" )) == rtl::OString( "" )); + CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "\0" )) == rtl::OString( "\0" )); + CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "ab" )) == rtl::OString( "ab" )); + CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "a\0b" )) == rtl::OString( "a\0b" )); +} + +void test::ostring::StringLiterals::testcall( const char str[] ) +{ + CPPUNIT_ASSERT( !CONST_CTOR_USED( str )); +} + +#undef CONST_CTOR_USED + +}} // namespace + +CPPUNIT_TEST_SUITE_REGISTRATION(test::ostring::StringLiterals); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx index 1170ff7..5a1d987 100644 --- a/sal/qa/rtl/strings/test_oustring_stringliterals.cxx +++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx @@ -28,6 +28,7 @@ // activate the extra needed ctor #define RTL_STRING_UNITTEST +extern bool rtl_string_unittest_const_literal; // actually unused here #include "sal/config.h" #include "sal/precppunit.hxx" diff --git a/sal/rtl/source/strtmpl.cxx b/sal/rtl/source/strtmpl.cxx index f8220b2..a3ef1fa 100644 --- a/sal/rtl/source/strtmpl.cxx +++ b/sal/rtl/source/strtmpl.cxx @@ -32,6 +32,7 @@ /* ======================================================================= */ #include <string.h> +#include <sal/log.hxx> /* inline void rtl_str_ImplCopy( IMPL_RTL_STRCODE* pDest, @@ -1187,6 +1188,43 @@ void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA* /* ----------------------------------------------------------------------- */ +// Used when creating from string literals. +// Intentionally copies also embedded \0's if present. +void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral)( IMPL_RTL_STRINGDATA** ppThis, + const sal_Char* pCharStr, + sal_Int32 nLen ) + SAL_THROW_EXTERN_C() +{ + if ( !nLen ) + { + IMPL_RTL_STRINGNAME( new )( ppThis ); + return; + } + + if ( *ppThis ) + IMPL_RTL_STRINGNAME( release )( *ppThis ); + + *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); + OSL_ASSERT(*ppThis != NULL); + if ( (*ppThis) ) + { + IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer; + sal_Int32 nCount; + for( nCount = nLen; nCount > 0; --nCount ) + { + /* Check ASCII range */ + SAL_WARN_IF( ((unsigned char)*pCharStr) > 127, "rtl.string", + "rtl_uString_newFromLiteral - Found char > 127" ); + + *pBuffer = *pCharStr; + pBuffer++; + pCharStr++; + } + } +} + +/* ----------------------------------------------------------------------- */ + void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis, IMPL_RTL_STRINGDATA* pStr ) SAL_THROW_EXTERN_C() diff --git a/sal/rtl/source/ustring.cxx b/sal/rtl/source/ustring.cxx index 649cb82..7c99758 100644 --- a/sal/rtl/source/ustring.cxx +++ b/sal/rtl/source/ustring.cxx @@ -499,41 +499,6 @@ void SAL_CALL rtl_uString_newFromAscii( rtl_uString** ppThis, } } -// Used when creating from string literals. -// Intentionally copies also embedded \0's if present. -void SAL_CALL rtl_uString_newFromLiteral( rtl_uString** ppThis, - const sal_Char* pCharStr, - sal_Int32 nLen ) - SAL_THROW_EXTERN_C() -{ - if ( !nLen ) - { - IMPL_RTL_STRINGNAME( new )( ppThis ); - return; - } - - if ( *ppThis ) - IMPL_RTL_STRINGNAME( release )( *ppThis ); - - *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); - OSL_ASSERT(*ppThis != NULL); - if ( (*ppThis) ) - { - IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer; - sal_Int32 nCount; - for( nCount = nLen; nCount > 0; --nCount ) - { - /* Check ASCII range */ - SAL_WARN_IF( ((unsigned char)*pCharStr) > 127, "rtl.string", - "rtl_uString_newFromLiteral - Found char > 127" ); - - *pBuffer = *pCharStr; - pBuffer++; - pCharStr++; - } - } -} - void SAL_CALL rtl_uString_newFromCodePoints( rtl_uString ** newString, sal_uInt32 const * codePoints, sal_Int32 codePointCount) SAL_THROW_EXTERN_C() diff --git a/sal/util/sal.map b/sal/util/sal.map index a6d9c08..5c79a55 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -239,6 +239,7 @@ UDK_3_0_0 { rtl_string_newConcat; rtl_string_newFromStr; rtl_string_newFromStr_WithLength; + rtl_string_newFromLiteral; rtl_string_newFromString; rtl_string_newReplace; rtl_string_newReplaceStrAt; diff --git a/vcl/generic/fontmanager/parseAFM.cxx b/vcl/generic/fontmanager/parseAFM.cxx index 6297ef8..177469c 100644 --- a/vcl/generic/fontmanager/parseAFM.cxx +++ b/vcl/generic/fontmanager/parseAFM.cxx @@ -366,7 +366,7 @@ static int parseGlobals( FileInputStream* fp, register GlobalFontInfo* gfi ) { bool cont = true, save = (gfi != NULL); int error = ok; - register char *keyword; + char *keyword; int direction = -1; int tokenlen; @@ -883,7 +883,7 @@ static int parseTrackKernData( FileInputStream* fp, register FontInfo* fi) { bool cont = true, save = (fi->tkd != NULL); int pos = 0, error = ok, tcount = 0, tokenlen; - register char *keyword; + char *keyword; while (cont) { -- 1.7.3.4
From 138d4df5a2d3c5c706c427763310d0f581c4e949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= <l.lu...@suse.cz> Date: Wed, 7 Mar 2012 15:07:58 +0100 Subject: [PATCH 3/3] remove usage of RTL_CONSTASCII_STRINGPARAM --- idl/source/objects/slot.cxx | 30 +++++++++++++++--------------- idl/source/objects/types.cxx | 6 +++--- svx/source/gallery2/gallery1.cxx | 18 +++++++++--------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/idl/source/objects/slot.cxx b/idl/source/objects/slot.cxx index cedd9be..f180719 100644 --- a/idl/source/objects/slot.cxx +++ b/idl/source/objects/slot.cxx @@ -702,7 +702,7 @@ void SvMetaSlot::WriteAttributesSvIdl( SvIdlDataBase & rBase, rOutStm << ';' << endl; } - rtl::OString aDel(RTL_CONSTASCII_STRINGPARAM(", ")); + rtl::OString aDel(", "); rtl::OStringBuffer aOut; if( aVolatile ) aOut.append(aVolatile.GetSvIdlString( SvHash_Volatile() )); @@ -715,15 +715,15 @@ void SvMetaSlot::WriteAttributesSvIdl( SvIdlDataBase & rBase, if( aToggle ) { aOut.append(aDel).append(aToggle.GetSvIdlString( SvHash_Toggle() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aAutoUpdate ) { aOut.append(aDel).append(aAutoUpdate.GetSvIdlString( SvHash_AutoUpdate() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } - rtl::OString aDel1(RTL_CONSTASCII_STRINGPARAM(", ")); + rtl::OString aDel1(", "); if( aAsynchron ) aOut.append(aDel).append(aAsynchron.GetSvIdlString( SvHash_Asynchron() )); else if( !aSynchron ) @@ -734,7 +734,7 @@ void SvMetaSlot::WriteAttributesSvIdl( SvIdlDataBase & rBase, else aDel1 = aDel; - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; if( aRecordManual ) aOut.append(aDel1).append(aRecordManual.GetSvIdlString( SvHash_RecordManual() )); else if( aNoRecord ) @@ -750,53 +750,53 @@ void SvMetaSlot::WriteAttributesSvIdl( SvIdlDataBase & rBase, if( aRecordAbsolute ) { aOut.append(aDel).append(aRecordAbsolute.GetSvIdlString( SvHash_RecordAbsolute() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aHasDialog ) { aOut.append(aDel).append(aHasDialog.GetSvIdlString( SvHash_HasDialog() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aMenuConfig ) { aOut.append(aDel).append(aMenuConfig.GetSvIdlString( SvHash_MenuConfig() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aToolBoxConfig ) { aOut.append(aDel).append(aToolBoxConfig.GetSvIdlString( SvHash_ToolBoxConfig() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aStatusBarConfig ) { aOut.append(aDel).append(aStatusBarConfig.GetSvIdlString( SvHash_StatusBarConfig() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aAccelConfig ) { aOut.append(aDel).append(aAccelConfig.GetSvIdlString( SvHash_AccelConfig() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aFastCall ) { aOut.append(aDel).append(aFastCall.GetSvIdlString( SvHash_FastCall() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aContainer ) { aOut.append(aDel).append(aContainer.GetSvIdlString( SvHash_Container() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aImageRotation ) { aOut.append(aDel).append(aImageRotation.GetSvIdlString( SvHash_ImageRotation() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aImageReflection ) { aOut.append(aDel).append(aImageReflection.GetSvIdlString( SvHash_ImageReflection() )); - aDel = rtl::OString(RTL_CONSTASCII_STRINGPARAM(", ")); + aDel = ", "; } if( aOut.getLength() ) diff --git a/idl/source/objects/types.cxx b/idl/source/objects/types.cxx index 5b53d96..9eaf197 100644 --- a/idl/source/objects/types.cxx +++ b/idl/source/objects/types.cxx @@ -869,7 +869,7 @@ void SvMetaType::SetType( int nT ) nType = nT; if( nType == TYPE_ENUM ) { - aOdlName.setString(rtl::OString(RTL_CONSTASCII_STRINGPARAM("short"))); + aOdlName.setString("short"); } else if( nType == TYPE_CLASS ) { @@ -1090,7 +1090,7 @@ sal_Bool SvMetaType::ReadHeaderSvIdl( SvIdlDataBase & rBase, } else { - rtl::OString aStr(RTL_CONSTASCII_STRINGPARAM("wrong typedef: ")); + rtl::OString aStr("wrong typedef: "); rBase.SetError( aStr, rInStm.GetToken() ); rBase.WriteError( rInStm ); } @@ -1806,7 +1806,7 @@ void SvMetaEnumValue::Write( SvIdlDataBase &, SvStream & rOutStm, sal_uInt16, SV_IMPL_META_FACTORY1( SvMetaTypeEnum, SvMetaType ); SvMetaTypeEnum::SvMetaTypeEnum() { - SetBasicName(rtl::OString(RTL_CONSTASCII_STRINGPARAM("Integer"))); + SetBasicName("Integer"); } void SvMetaTypeEnum::Load( SvPersistStream & rStm ) diff --git a/svx/source/gallery2/gallery1.cxx b/svx/source/gallery2/gallery1.cxx index a2d5d05..4ce012c 100644 --- a/svx/source/gallery2/gallery1.cxx +++ b/svx/source/gallery2/gallery1.cxx @@ -578,31 +578,31 @@ rtl::OUString Gallery::GetThemeName( sal_uIntPtr nThemeId ) const switch( nThemeId ) { case( GALLERY_THEME_3D ): - aFallback = rtl::OString(RTL_CONSTASCII_STRINGPARAM("3D")); + aFallback = "3D"; break; case( GALLERY_THEME_BULLETS ): - aFallback = rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bullets")); + aFallback = "Bullets"; break; case( GALLERY_THEME_HOMEPAGE ): - aFallback = rtl::OString(RTL_CONSTASCII_STRINGPARAM("Homepage")); + aFallback = "Homepage"; break; case( GALLERY_THEME_HTMLBUTTONS ): - aFallback = rtl::OString(RTL_CONSTASCII_STRINGPARAM("private://gallery/hidden/HtmlExportButtons")); + aFallback = "private://gallery/hidden/HtmlExportButtons"; break; case( GALLERY_THEME_POWERPOINT ): - aFallback = rtl::OString(RTL_CONSTASCII_STRINGPARAM("private://gallery/hidden/imgppt")); + aFallback = "private://gallery/hidden/imgppt"; break; case( GALLERY_THEME_FONTWORK ): - aFallback = rtl::OString(RTL_CONSTASCII_STRINGPARAM("private://gallery/hidden/fontwork")); + aFallback = "private://gallery/hidden/fontwork"; break; case( GALLERY_THEME_FONTWORK_VERTICAL ): - aFallback = rtl::OString(RTL_CONSTASCII_STRINGPARAM("private://gallery/hidden/fontworkvertical")); + aFallback = "private://gallery/hidden/fontworkvertical"; break; case( GALLERY_THEME_RULERS ): - aFallback = rtl::OString(RTL_CONSTASCII_STRINGPARAM("Rulers")); + aFallback = "Rulers"; break; case( GALLERY_THEME_SOUNDS ): - aFallback = rtl::OString(RTL_CONSTASCII_STRINGPARAM("Sounds")); + aFallback = "Sounds"; break; default: break; -- 1.7.3.4
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice