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

Reply via email to