From e47b4a5f7b96b83412d067fd9c9612b49eed8699 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= <l.lunak@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.lunak@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

