[haiku-commits] haiku: hrev43310 - src/system/libroot/posix/glibc/wcsmbs src/system/libroot/posix/locale src/system/libroot/add-ons/icu src/system/libroot/posix/glibc/stdlib headers/private/libroot/locale

  • From: zooey@xxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 23 Nov 2011 20:16:45 +0100 (CET)

hrev43310 adds 18 changesets to branch 'master'
old head: 3a57f54e4de7d31fad88cb8fd36c13807715cefe
new head: c894d1868ef1d23e5536bfdbd8608402cef14607

----------------------------------------------------------------------------

02606f7: Provide BReferenceable in libreferenceable.a, too.
  
  * the upcoming multibyte-implementation in libroot's ICU locale
    backend is going to use this, so it's not good enough to provide
    BReferenceable only in libbe.so

bcadc4c: Start work on multibyte-support in locale backend.
  
  * add ICUThreadLocaleStorageValue, which will be used to maintain
    per-thread ICU converters
  * add ICUConverterManager

bf5ff48: Use TLS and converter manager in locale backend.

fa02fc6: Adjust mbstate_t to what we need.
  
  * we maintain the character count and the ID of the corresponding
    ICU converter in mbstate_t

e0eb1d3: Let MB_CUR_LEN lookup the actual value.
  
  * instead of yielding 1, MB_CUR_LEN now looks up the correct
    value in the ctype data provided by the locale backend

0f21cf0: Define MB_LEN_MAX to 16.
  
  * we follow glibc's example and allow 16 bytes as maximum multibyte
    character length (ICU's data currently shows an actual maximum
    of 8 bytes)

28ae43d: Add multibyte-support to ctype-locale backend.
  
  * add actual converter methods MultibyteToWchar() and WcharToMultibyte()
    to locale backend and implement them in the ctype subpart
  * add management code for maintaining converters referenced by mbstate_t

32a04e8: Formatting cleanup of B_DEFINE_WEAK_ALIAS macro.
  
  * This doesn't necessarily belong here, but we're going to make use
    of it in the next changeset. Additionally, this change to BeBuild.h
    will trigger a rebuild of nearly all files, and applying it during
    the multibyte-related work will skip another full rebuild ...

cc5eca7: Activate our new multibyte implementation.
  
  * add implementations for the following multibyte-related
    functions:
      btwoc()
      mblen()
      mbrlen()
      mbrtowc()
      mbsinit()
      mbtowc()
      wcrtomb()
      wcswidth()
      wctob()
      wctomb()
  * the implementation of the above function live in a symbol
    named __<name>, the above symbol names are defined as a weak
    alias to the internal ones - TODO: we need to make sure to
    only invoked the internal functions (i.e. prepended with __)
    in order to avoid problems with symbol preemption.
  * deactivate the limited mb implementation we provided before,
    as well as respective stuff from glibc

b443555: Drop our old, limited multibyte implementation.

bb79d18: Drop no longer needed multibyte stuff from glibc.

c510147: Adjust required legacy gcc version.

2538952: Touch c-gperf.h before building legacy gcc.

9161a59: Fix build of libroot-addon-icu with gcc4.

cdb7744: Avoid warning about missing math.h.
  
  * Apparently caused by the fact that we no longer run fixincludes,
    math.h is not being generated anymore. I haven't removed the rm
    from the script in order to be compatible with older compilers.

5c112a1: Reset mbstate to initial in wcrtomb() with 0 wchar.

53c09cf: Actually store & use our assigned TLS-key (OOPS!)

c894d18: Bring rewritten multibyte-support into repository.
  
  * update copyrights of locale backend files
  
  Multibyte-support has been rewritten to use ICU as backend.
  While this does not necessarily work properly in every aspect
  (e.g. the shell still has [different] problems with multibyte-
  characters now), it does fix #6263 and #7700.

                                    [ Oliver Tappe <zooey@xxxxxxxxxxxxxxx> ]


----------------------------------------------------------------------------

74 files changed, 1108 insertions(+), 1337 deletions(-)
build/scripts/build_cross_tools                    |    5 +-
configure                                          |    2 +-
headers/build/gcc-2.95.3/limits.h                  |    2 +-
headers/os/BeBuild.h                               |    2 +-
headers/posix/ctype.h                              |    2 +
headers/posix/limits.h                             |    2 +
headers/posix/stdlib.h                             |    8 +-
headers/posix/wchar.h                              |    5 +-
headers/private/libroot/locale/ICUCategoryData.h   |   15 +-
headers/private/libroot/locale/ICUCollateData.h    |    4 +-
.../private/libroot/locale/ICUConverterManager.h   |  106 ++++++++
headers/private/libroot/locale/ICUCtypeData.h      |   15 +-
headers/private/libroot/locale/ICULocaleBackend.h  |   15 +-
headers/private/libroot/locale/ICULocaleconvData.h |    4 +-
headers/private/libroot/locale/ICUMessagesData.h   |    5 +-
headers/private/libroot/locale/ICUMonetaryData.h   |    6 +-
headers/private/libroot/locale/ICUNumericData.h    |    5 +-
.../libroot/locale/ICUThreadLocalStorageValue.h    |   36 +++
headers/private/libroot/locale/ICUTimeConversion.h |    2 +-
headers/private/libroot/locale/ICUTimeData.h       |    5 +-
headers/private/libroot/locale/LocaleBackend.h     |   10 +-
headers/private/libroot/wchar_private.h            |    5 +
src/kits/support/Jamfile                           |    2 +
src/system/libroot/add-ons/icu/ICUCategoryData.cpp |   71 ++++--
src/system/libroot/add-ons/icu/ICUCollateData.cpp  |   19 +-
.../libroot/add-ons/icu/ICUConverterManager.cpp    |  175 +++++++++++++
src/system/libroot/add-ons/icu/ICUCtypeData.cpp    |  158 ++++++++++++-
.../libroot/add-ons/icu/ICULocaleBackend.cpp       |   53 ++++-
.../libroot/add-ons/icu/ICULocaleconvData.cpp      |    8 +-
src/system/libroot/add-ons/icu/ICUMessagesData.cpp |    8 +-
src/system/libroot/add-ons/icu/ICUMonetaryData.cpp |    5 +-
src/system/libroot/add-ons/icu/ICUNumericData.cpp  |    5 +-
.../add-ons/icu/ICUThreadLocalStorageValue.cpp     |   52 ++++
.../libroot/add-ons/icu/ICUTimeConversion.cpp      |    2 +-
src/system/libroot/add-ons/icu/ICUTimeData.cpp     |    5 +-
src/system/libroot/add-ons/icu/Jamfile             |    5 +-
src/system/libroot/posix/glibc/locale/Jamfile      |    1 -
src/system/libroot/posix/glibc/locale/mb_cur_max.c |   33 ---
src/system/libroot/posix/glibc/stdlib/Jamfile      |    3 -
src/system/libroot/posix/glibc/stdlib/mblen.c      |   67 -----
src/system/libroot/posix/glibc/stdlib/mbtowc.c     |   73 ------
src/system/libroot/posix/glibc/stdlib/stdlib.h     |    2 +-
src/system/libroot/posix/glibc/stdlib/wctomb.c     |   54 ----
src/system/libroot/posix/glibc/wcsmbs/Jamfile      |    8 -
src/system/libroot/posix/glibc/wcsmbs/btowc.c      |   73 ------
src/system/libroot/posix/glibc/wcsmbs/mbrlen.c     |   36 ---
src/system/libroot/posix/glibc/wcsmbs/mbrtowc.c    |  107 --------
src/system/libroot/posix/glibc/wcsmbs/mbsinit.c    |   37 ---
src/system/libroot/posix/glibc/wcsmbs/wcrtomb.c    |  110 ---------
src/system/libroot/posix/glibc/wcsmbs/wcswidth.c   |   39 ---
src/system/libroot/posix/glibc/wcsmbs/wctob.c      |   73 ------
src/system/libroot/posix/glibc/wcsmbs/wcwidth.c    |   27 --
src/system/libroot/posix/glibc/wcsmbs/wcwidth.h    |   40 ---
src/system/libroot/posix/locale/Jamfile            |    5 -
.../libroot/posix/locale/LocaleDataBridge.cpp      |    6 +
src/system/libroot/posix/locale/ctype.cpp          |   17 ++
src/system/libroot/posix/locale/mb_defs.h          |   49 ----
src/system/libroot/posix/locale/mb_none.c          |  205 ----------------
src/system/libroot/posix/locale/mblen.c            |   50 ----
src/system/libroot/posix/locale/mbrlen.c           |   41 ---
src/system/libroot/posix/locale/mbrtowc.c          |   42 ----
src/system/libroot/posix/locale/mbsinit.c          |   38 ---
src/system/libroot/posix/locale/wcrtomb.c          |   41 ---
src/system/libroot/posix/wchar/Jamfile             |   16 ++-
src/system/libroot/posix/wchar/btowc.c             |   33 +++
src/system/libroot/posix/wchar/mblen.c             |   32 +++
src/system/libroot/posix/wchar/mbrlen.c            |   21 ++
src/system/libroot/posix/wchar/mbrtowc.cpp         |   77 ++++++
src/system/libroot/posix/wchar/mbsinit.c           |   16 ++
src/system/libroot/posix/wchar/mbtowc.c            |   26 ++
src/system/libroot/posix/wchar/wcrtomb.cpp         |   67 +++++
src/system/libroot/posix/wchar/wcswidth.c          |    9 +-
src/system/libroot/posix/wchar/wctob.c             |   24 ++
src/system/libroot/posix/wchar/wctomb.c            |   18 ++

############################################################################

Commit:      02606f712cc94685b775aca04415e794f3ebe84c
URL:         http://cgit.haiku-os.org/haiku/commit/?id=02606f7
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 15:43:53 2011 UTC

Provide BReferenceable in libreferenceable.a, too.

* the upcoming multibyte-implementation in libroot's ICU locale
  backend is going to use this, so it's not good enough to provide
  BReferenceable only in libbe.so

----------------------------------------------------------------------------

diff --git a/src/kits/support/Jamfile b/src/kits/support/Jamfile
index fcdd122..ac78d1d 100644
--- a/src/kits/support/Jamfile
+++ b/src/kits/support/Jamfile
@@ -23,3 +23,5 @@ MergeObject <libbe>support_kit.o :
        String.cpp
        Url.cpp
 ;
+
+StaticLibrary libreferenceable.a : : [ FGristFiles Referenceable.o ] ;

############################################################################

Commit:      bcadc4ca66fd23083d013e8f91a74e191c06df1e
URL:         http://cgit.haiku-os.org/haiku/commit/?id=bcadc4c
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 15:55:39 2011 UTC

Start work on multibyte-support in locale backend.

* add ICUThreadLocaleStorageValue, which will be used to maintain
  per-thread ICU converters
* add ICUConverterManager

----------------------------------------------------------------------------

diff --git a/headers/private/libroot/locale/ICUConverterManager.h 
b/headers/private/libroot/locale/ICUConverterManager.h
new file mode 100644
index 0000000..86fcbf6
--- /dev/null
+++ b/headers/private/libroot/locale/ICUConverterManager.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _ICU_CONVERTER_MANAGER_H
+#define _ICU_CONVERTER_MANAGER_H
+
+
+#include <pthread.h>
+
+#include <map>
+
+#include <unicode/ucnv.h>
+
+#include <SupportDefs.h>
+
+#include <locks.h>
+#include <Referenceable.h>
+#include <util/DoublyLinkedList.h>
+//#include <util/OpenHashTable.h>
+
+#include "ICUThreadLocalStorageValue.h"
+
+
+namespace BPrivate {
+namespace Libroot {
+
+
+class ICUConverterInfo : public BReferenceable {
+public:
+                                                               
ICUConverterInfo(UConverter* converter,
+                                                                       const 
char* charset, ICUConverterID id);
+       virtual                                         ~ICUConverterInfo();
+
+                       UConverter*                     Converter() const
+                                                                       { 
return fConverter; }
+
+                       const char*                     Charset() const
+                                                                       { 
return fCharset; }
+
+                       ICUConverterID          ID() const
+                                                                       { 
return fID; }
+
+private:
+                       UConverter*                     fConverter;
+                       char                            
fCharset[UCNV_MAX_CONVERTER_NAME_LENGTH];
+                       ICUConverterID          fID;
+};
+
+
+typedef BReference<ICUConverterInfo> ICUConverterRef;
+
+
+class ICUConverterManager {
+public:
+                                                               
ICUConverterManager();
+                                                               
~ICUConverterManager();
+
+                       status_t                        CreateConverter(const 
char* charset,
+                                                                       
ICUConverterRef& converterRefOut,
+                                                                       
ICUConverterID& idOut);
+
+                       status_t                        
GetConverter(ICUConverterID id,
+                                                                       
ICUConverterRef& converterRefOut);
+
+                       status_t                        
DropConverter(ICUConverterID id);
+
+       static  ICUConverterManager*    Instance();
+
+private:
+       static  void                            _CreateInstance();
+
+       static  ICUConverterManager*    sInstance;
+
+       static  const size_t            skMaxConvertersPerProcess = 1024;
+
+private:
+                       class LinkedConverterInfo
+                               :
+                               public ICUConverterInfo,
+                               public 
DoublyLinkedListLinkImpl<LinkedConverterInfo>
+                       {
+                       public:
+                               LinkedConverterInfo(UConverter* converter, 
const char* charset,
+                                       ICUConverterID id)
+                                       :
+                                       ICUConverterInfo(converter, charset, id)
+                               {
+                               }
+                       };
+                       typedef std::map<ICUConverterID, LinkedConverterInfo*> 
ConverterMap;
+                       typedef DoublyLinkedList<LinkedConverterInfo> 
ConverterList;
+
+private:
+                       ConverterMap            fConverterMap;
+                       ConverterList           fLRUConverters;
+                       mutex                           fMutex;
+                       ICUConverterID          fNextConverterID;
+};
+
+
+}      // namespace Libroot
+}      // namespace BPrivate
+
+
+#endif // _ICU_CONVERTER_MANAGER_H
diff --git a/headers/private/libroot/locale/ICUThreadLocalStorageValue.h 
b/headers/private/libroot/locale/ICUThreadLocalStorageValue.h
new file mode 100644
index 0000000..5ea3c26
--- /dev/null
+++ b/headers/private/libroot/locale/ICUThreadLocalStorageValue.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _ICU_THREAD_LOCAL_STORAGE_VALUE_H
+#define _ICU_THREAD_LOCAL_STORAGE_VALUE_H
+
+
+#include <pthread.h>
+
+#include <SupportDefs.h>
+
+
+namespace BPrivate {
+namespace Libroot {
+
+
+typedef unsigned int ICUConverterID;
+
+
+struct ICUThreadLocalStorageValue {
+                       ICUConverterID          converterID;
+
+                                                               
ICUThreadLocalStorageValue();
+                                                               
~ICUThreadLocalStorageValue();
+
+       static  status_t                        GetInstanceForKey(pthread_key_t 
tlsKey,
+                                                                       
ICUThreadLocalStorageValue*& instanceOut);
+};
+
+
+}      // namespace Libroot
+}      // namespace BPrivate
+
+
+#endif // _ICU_THREAD_LOCAL_STORAGE_VALUE_H
diff --git a/src/system/libroot/add-ons/icu/ICUConverterManager.cpp 
b/src/system/libroot/add-ons/icu/ICUConverterManager.cpp
new file mode 100644
index 0000000..c4b750c
--- /dev/null
+++ b/src/system/libroot/add-ons/icu/ICUConverterManager.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "ICUConverterManager.h"
+
+#include <pthread.h>
+
+#include <new>
+
+
+namespace BPrivate {
+namespace Libroot {
+
+
+static pthread_once_t sManagerInitOnce = PTHREAD_ONCE_INIT;
+
+
+ICUConverterInfo::ICUConverterInfo(UConverter* converter, const char* charset,
+       ICUConverterID id)
+       :
+       fConverter(converter),
+       fID(id)
+{
+       strlcpy(fCharset, charset, sizeof(fCharset));
+}
+
+
+ICUConverterInfo::~ICUConverterInfo()
+{
+       if (fConverter != NULL)
+               ucnv_close(fConverter);
+}
+
+
+ICUConverterManager* ICUConverterManager::sInstance = NULL;
+
+
+ICUConverterManager::ICUConverterManager()
+       :
+       fNextConverterID(1)
+{
+       mutex_init(&fMutex, "ConverterManagerMutex");
+}
+
+
+ICUConverterManager::~ICUConverterManager()
+{
+       ConverterMap::iterator iter;
+       for (iter = fConverterMap.begin(); iter != fConverterMap.end(); ++iter)
+               iter->second->ReleaseReference();
+
+       mutex_destroy(&fMutex);
+}
+
+
+status_t
+ICUConverterManager::CreateConverter(const char* charset,
+       ICUConverterRef& converterRefOut, ICUConverterID& idOut)
+{
+       MutexLocker lock(fMutex);
+       if (!lock.IsLocked())
+               return B_ERROR;
+
+       UErrorCode icuStatus = U_ZERO_ERROR;
+       UConverter* icuConverter = ucnv_open(charset, &icuStatus);
+       if (icuConverter == NULL)
+               return B_NAME_NOT_FOUND;
+
+       LinkedConverterInfo* converterInfo = new (std::nothrow) 
LinkedConverterInfo(
+               icuConverter, charset, fNextConverterID);
+       if (converterInfo == NULL) {
+               ucnv_close(icuConverter);
+               return B_NO_MEMORY;
+       }
+       ICUConverterRef converterRef(converterInfo, true);
+
+       // setup the new converter to stop upon any errors
+       icuStatus = U_ZERO_ERROR;
+       ucnv_setToUCallBack(icuConverter, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, 
NULL,
+               &icuStatus);
+       if (!U_SUCCESS(icuStatus))
+               return B_ERROR;
+       icuStatus = U_ZERO_ERROR;
+       ucnv_setFromUCallBack(icuConverter, UCNV_FROM_U_CALLBACK_STOP, NULL, 
NULL,
+               NULL, &icuStatus);
+       if (!U_SUCCESS(icuStatus))
+               return B_ERROR;
+
+       // ok, we've got the converter, add it to our map
+       try {
+               if (fConverterMap.size() >= skMaxConvertersPerProcess) {
+                       // make room by dropping the least recently used 
converter
+                       LinkedConverterInfo* leastUsedConverter = 
fLRUConverters.Head();
+                       fLRUConverters.Remove(leastUsedConverter);
+                       fConverterMap.erase(leastUsedConverter->ID());
+                       leastUsedConverter->ReleaseReference();
+               }
+               fConverterMap[fNextConverterID] = converterInfo;
+               fLRUConverters.Insert(converterInfo);
+       } catch (...) {
+               return B_NO_MEMORY;
+       }
+
+       converterRefOut = converterRef;
+       idOut = fNextConverterID++;
+
+       converterRef.Detach();
+
+       return B_OK;
+}
+
+
+status_t
+ICUConverterManager::GetConverter(ICUConverterID id,
+       ICUConverterRef& converterRefOut)
+{
+       MutexLocker lock(fMutex);
+       if (!lock.IsLocked())
+               return B_ERROR;
+
+       ConverterMap::iterator iter = fConverterMap.find(id);
+       if (iter == fConverterMap.end())
+               return B_NAME_NOT_FOUND;
+
+       converterRefOut.SetTo(iter->second);
+
+       return B_OK;
+}
+
+
+status_t
+ICUConverterManager::DropConverter(ICUConverterID id)
+{
+       MutexLocker lock(fMutex);
+       if (!lock.IsLocked())
+               return B_ERROR;
+
+       ConverterMap::iterator iter = fConverterMap.find(id);
+       if (iter == fConverterMap.end())
+               return B_NAME_NOT_FOUND;
+
+       fLRUConverters.Remove(iter->second);
+       fConverterMap.erase(iter);
+       iter->second->ReleaseReference();
+
+       return B_OK;
+}
+
+
+/*static*/ ICUConverterManager*
+ICUConverterManager::Instance()
+{
+       if (sInstance != NULL)
+               return sInstance;
+
+       pthread_once(&sManagerInitOnce,
+               &BPrivate::Libroot::ICUConverterManager::_CreateInstance);
+
+       return sInstance;
+}
+
+
+/*static*/ void
+ICUConverterManager::_CreateInstance()
+{
+       sInstance = new (std::nothrow) ICUConverterManager;
+}
+
+
+}      // namespace Libroot
+}      // namespace BPrivate
diff --git a/src/system/libroot/add-ons/icu/ICUThreadLocalStorageValue.cpp 
b/src/system/libroot/add-ons/icu/ICUThreadLocalStorageValue.cpp
new file mode 100644
index 0000000..d88410b
--- /dev/null
+++ b/src/system/libroot/add-ons/icu/ICUThreadLocalStorageValue.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "ICUThreadLocalStorageValue.h"
+
+#include <new>
+
+#include "ICUConverterManager.h"
+
+
+namespace BPrivate {
+namespace Libroot {
+
+
+ICUThreadLocalStorageValue::ICUThreadLocalStorageValue()
+       : converterID(0)
+{
+}
+
+
+ICUThreadLocalStorageValue::~ICUThreadLocalStorageValue()
+{
+       if (converterID != 0)
+               ICUConverterManager::Instance()->DropConverter(converterID);
+}
+
+
+status_t
+ICUThreadLocalStorageValue::GetInstanceForKey(pthread_key_t tlsKey,
+       ICUThreadLocalStorageValue*& instanceOut)
+{
+       ICUThreadLocalStorageValue* tlsValue = NULL;
+       void* value = pthread_getspecific(tlsKey);
+       if (value == NULL) {
+               tlsValue = new (std::nothrow) ICUThreadLocalStorageValue();
+               if (tlsValue == NULL)
+                       return B_NO_MEMORY;
+               pthread_setspecific(tlsKey, tlsValue);
+       } else
+               tlsValue = static_cast<ICUThreadLocalStorageValue*>(value);
+
+       instanceOut = tlsValue;
+
+       return B_OK;
+}
+
+
+}      // namespace Libroot
+}      // namespace BPrivate
diff --git a/src/system/libroot/add-ons/icu/Jamfile 
b/src/system/libroot/add-ons/icu/Jamfile
index 2ab0ec9..5640a26 100644
--- a/src/system/libroot/add-ons/icu/Jamfile
+++ b/src/system/libroot/add-ons/icu/Jamfile
@@ -1,6 +1,7 @@
 SubDir HAIKU_TOP src system libroot add-ons icu ;
 
 UsePrivateHeaders
+       kernel
        libroot
        [ FDirName libroot locale ]
        [ FDirName libroot time ]
@@ -10,12 +11,14 @@ UsePrivateHeaders
 local sources =
        ICUCategoryData.cpp
        ICUCollateData.cpp
+       ICUConverterManager.cpp
        ICUCtypeData.cpp
        ICULocaleBackend.cpp
        ICULocaleconvData.cpp
        ICUMessagesData.cpp
        ICUMonetaryData.cpp
        ICUNumericData.cpp
+       ICUThreadLocalStorageValue.cpp
        ICUTimeConversion.cpp
        ICUTimeData.cpp
 ;
@@ -28,6 +31,6 @@ Includes [ FGristFiles $(sources) ] : 
$(HAIKU_ICU_HEADERS_DEPENDENCY) ;
 SharedLibrary libroot-addon-icu.so
        : $(sources)
        :
-       $(TARGET_LIBSTDC++) $(HAIKU_ICU_LIBS)
+       libreferenceable.a $(TARGET_LIBSTDC++) $(HAIKU_ICU_LIBS)
 ;
 

############################################################################

Commit:      bf5ff48092a49e5055f86154063d72b695cbe1db
URL:         http://cgit.haiku-os.org/haiku/commit/?id=bf5ff48
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 16:17:18 2011 UTC

Use TLS and converter manager in locale backend.

----------------------------------------------------------------------------

diff --git a/headers/private/libroot/locale/ICUCategoryData.h 
b/headers/private/libroot/locale/ICUCategoryData.h
index 7851511..7da0904 100644
--- a/headers/private/libroot/locale/ICUCategoryData.h
+++ b/headers/private/libroot/locale/ICUCategoryData.h
@@ -5,6 +5,7 @@
 #ifndef _ICU_CATEGORY_DATA_H
 #define _ICU_CATEGORY_DATA_H
 
+#include <pthread.h>
 
 #include <unicode/locid.h>
 #include <unicode/ucnv.h>
@@ -12,6 +13,8 @@
 
 #include <SupportDefs.h>
 
+#include "ICUConverterManager.h"
+
 
 namespace BPrivate {
 namespace Libroot {
@@ -19,14 +22,14 @@ namespace Libroot {
 
 class ICUCategoryData {
 public:
-                                                               
ICUCategoryData();
+                                                               
ICUCategoryData(pthread_key_t tlsKey);
        virtual                                         ~ICUCategoryData();
 
        virtual status_t                        SetTo(const Locale& locale,
                                                                        const 
char* posixLocaleName);
        virtual status_t                        SetToPosix();
 
-                       const char *            PosixLocaleName()
+                       const char*                     PosixLocaleName()
                                                                        { 
return fPosixLocaleName; }
 
 protected:
@@ -35,16 +38,18 @@ protected:
                                                                        char* 
destination, int destinationSize,
                                                                        const 
char* defaultValue = "");
 
+                       status_t                        
_GetConverter(ICUConverterRef& converterRefOut);
+
        static  const uint16            skMaxPosixLocaleNameLen = 128;
        static  const size_t            skLCBufSize = 16;
 
+                       pthread_key_t           fThreadLocalStorageKey;
                        Locale                          fLocale;
-                       UConverter*                     fConverter;
                        char                            
fPosixLocaleName[skMaxPosixLocaleNameLen];
                        char                            
fGivenCharset[UCNV_MAX_CONVERTER_NAME_LENGTH];
 
 private:
-                       status_t                        _SetupConverter();
+                       status_t                        _SetupConverter();
 };
 
 
diff --git a/headers/private/libroot/locale/ICUCollateData.h 
b/headers/private/libroot/locale/ICUCollateData.h
index c22daf6..4d30cc7 100644
--- a/headers/private/libroot/locale/ICUCollateData.h
+++ b/headers/private/libroot/locale/ICUCollateData.h
@@ -19,7 +19,7 @@ class ICUCollateData : public ICUCategoryData {
        typedef ICUCategoryData         inherited;
 
 public:
-                                                               
ICUCollateData();
+                                                               
ICUCollateData(pthread_key_t tlsKey);
        virtual                                         ~ICUCollateData();
 
        virtual status_t                        SetTo(const Locale& locale,
diff --git a/headers/private/libroot/locale/ICUCtypeData.h 
b/headers/private/libroot/locale/ICUCtypeData.h
index e6a74bf..e62db41 100644
--- a/headers/private/libroot/locale/ICUCtypeData.h
+++ b/headers/private/libroot/locale/ICUCtypeData.h
@@ -17,7 +17,7 @@ namespace Libroot {
 class ICUCtypeData : public ICUCategoryData {
        typedef ICUCategoryData         inherited;
 public:
-                                                               ICUCtypeData();
+                                                               
ICUCtypeData(pthread_key_t tlsKey);
        virtual                                         ~ICUCtypeData();
 
                        void                            
Initialize(LocaleCtypeDataBridge* dataBridge);
diff --git a/headers/private/libroot/locale/ICULocaleBackend.h 
b/headers/private/libroot/locale/ICULocaleBackend.h
index a4292ec..de3c1af 100644
--- a/headers/private/libroot/locale/ICULocaleBackend.h
+++ b/headers/private/libroot/locale/ICULocaleBackend.h
@@ -9,6 +9,7 @@
 #include "LocaleBackend.h"
 
 #include <locale.h>
+#include <pthread.h>
 #include <timelocal.h>
 
 #include "ICUCollateData.h"
@@ -57,6 +58,9 @@ private:
                        const char*                     _QueryLocale(int 
category);
                        const char*                     _SetPosixLocale(int 
category);
 
+       static  pthread_key_t           _CreateThreadLocalStorageKey();
+       static  void                            
_DestroyThreadLocalStorageValue(void* value);
+
                        // buffer for locale names (up to one per category)
                        char                            fLocaleDescription[512];
 
@@ -64,6 +68,9 @@ private:
                        struct lconv            fLocaleConv;
                        struct lc_time_t        fLCTimeInfo;
 
+                       //
+                       pthread_key_t           fThreadLocalStorageKey;
+
                        // these work on the data containers above
                        ICUCollateData          fCollateData;
                        ICUCtypeData            fCtypeData;
diff --git a/headers/private/libroot/locale/ICULocaleconvData.h 
b/headers/private/libroot/locale/ICULocaleconvData.h
index 7e86e21..96823a7 100644
--- a/headers/private/libroot/locale/ICULocaleconvData.h
+++ b/headers/private/libroot/locale/ICULocaleconvData.h
@@ -21,6 +21,8 @@ class ICULocaleconvData : public ICUCategoryData {
        typedef ICUCategoryData         inherited;
 
 protected:
+                                                               
ICULocaleconvData(pthread_key_t tlsKey);
+
                        status_t                        _SetLocaleconvEntry(
                                                                        const 
DecimalFormatSymbols* formatSymbols,
                                                                        char* 
destination, FormatSymbol symbol,
diff --git a/headers/private/libroot/locale/ICUMessagesData.h 
b/headers/private/libroot/locale/ICUMessagesData.h
index fe94ded..7790da7 100644
--- a/headers/private/libroot/locale/ICUMessagesData.h
+++ b/headers/private/libroot/locale/ICUMessagesData.h
@@ -16,7 +16,10 @@ namespace Libroot {
 
 class ICUMessagesData : public ICUCategoryData {
        typedef ICUCategoryData         inherited;
+
 public:
+                                                               
ICUMessagesData(pthread_key_t tlsKey);
+
        virtual status_t                        SetTo(const Locale& locale,
                                                                        const 
char* posixLocaleName);
        virtual status_t                        SetToPosix();
diff --git a/headers/private/libroot/locale/ICUMonetaryData.h 
b/headers/private/libroot/locale/ICUMonetaryData.h
index 5d3571e..ca62f54 100644
--- a/headers/private/libroot/locale/ICUMonetaryData.h
+++ b/headers/private/libroot/locale/ICUMonetaryData.h
@@ -18,6 +18,7 @@ namespace Libroot {
 
 class ICUMonetaryData : public ICULocaleconvData {
        typedef ICULocaleconvData       inherited;
+
 public:
        static  const int32                     
kParenthesesAroundCurrencyAndValue = 0;
        static  const int32                     kSignPrecedesCurrencyAndValue   
   = 1;
@@ -25,7 +26,8 @@ public:
        static  const int32                     
kSignImmediatelyPrecedesCurrency   = 3;
        static  const int32                     
kSignImmediatelySucceedsCurrency   = 4;
 
-                                                               
ICUMonetaryData(struct lconv& localeConv);
+                                                               
ICUMonetaryData(pthread_key_t tlsKey,
+                                                                       struct 
lconv& localeConv);
 
                        void                            Initialize(
                                                                        
LocaleMonetaryDataBridge* dataBridge);
diff --git a/headers/private/libroot/locale/ICUNumericData.h 
b/headers/private/libroot/locale/ICUNumericData.h
index c95ad4d..b41d427 100644
--- a/headers/private/libroot/locale/ICUNumericData.h
+++ b/headers/private/libroot/locale/ICUNumericData.h
@@ -18,7 +18,8 @@ class ICUNumericData : public ICULocaleconvData {
        typedef ICULocaleconvData       inherited;
 
 public:
-                                                               
ICUNumericData(struct lconv& localeConv);
+                                                               
ICUNumericData(pthread_key_t tlsKey,
+                                                                       struct 
lconv& localeConv);
 
                        void                            
Initialize(LocaleNumericDataBridge* dataBridge);
 
diff --git a/headers/private/libroot/locale/ICUTimeData.h 
b/headers/private/libroot/locale/ICUTimeData.h
index d3a8384..10b37b9 100644
--- a/headers/private/libroot/locale/ICUTimeData.h
+++ b/headers/private/libroot/locale/ICUTimeData.h
@@ -21,7 +21,8 @@ namespace Libroot {
 class ICUTimeData : public ICUCategoryData {
        typedef ICUCategoryData         inherited;
 public:
-                                                               
ICUTimeData(struct lc_time_t& lcTimeInfo);
+                                                               
ICUTimeData(pthread_key_t tlsKey,
+                                                                       struct 
lc_time_t& lcTimeInfo);
                                                                ~ICUTimeData();
 
                        void                            
Initialize(LocaleTimeDataBridge* dataBridge);
diff --git a/src/system/libroot/add-ons/icu/ICUCategoryData.cpp 
b/src/system/libroot/add-ons/icu/ICUCategoryData.cpp
index 0f7e2ac..17730f8 100644
--- a/src/system/libroot/add-ons/icu/ICUCategoryData.cpp
+++ b/src/system/libroot/add-ons/icu/ICUCategoryData.cpp
@@ -15,9 +15,7 @@ namespace BPrivate {
 namespace Libroot {
 
 
-ICUCategoryData::ICUCategoryData()
-       :
-       fConverter(NULL)
+ICUCategoryData::ICUCategoryData(pthread_key_t tlsKey)
 {
        *fPosixLocaleName = '\0';
        *fGivenCharset = '\0';
@@ -26,32 +24,42 @@ ICUCategoryData::ICUCategoryData()
 
 ICUCategoryData::~ICUCategoryData()
 {
-       if (fConverter)
-               ucnv_close(fConverter);
 }
 
 
 status_t
-ICUCategoryData::_SetupConverter()
+ICUCategoryData::_GetConverter(ICUConverterRef& converterRefOut)
 {
-       if (fConverter != NULL) {
-               ucnv_close(fConverter);
-               fConverter = NULL;
+       // we use different converter-IDs per thread in order to avoid 
converters
+       // being used by more than one thread
+       ICUThreadLocalStorageValue* tlsValue = NULL;
+       status_t result = ICUThreadLocalStorageValue::GetInstanceForKey(
+               fThreadLocalStorageKey, tlsValue);
+       if (result != B_OK)
+               return result;
+
+       ICUConverterRef converterRef;
+       result = ICUConverterManager::Instance()->GetConverter(
+               tlsValue->converterID, converterRef);
+       if (result == B_OK) {
+               if (strcmp(converterRef->Charset(), fGivenCharset) == 0) {
+                       converterRefOut = converterRef;
+                       return B_OK;
+               }
+
+               // charset no longer matches the converter, we need to dump it 
and
+               // create a new one
+               
ICUConverterManager::Instance()->DropConverter(tlsValue->converterID);
+               tlsValue->converterID = 0;
        }
 
-       UErrorCode icuStatus = U_ZERO_ERROR;
-       fConverter = ucnv_open(fGivenCharset, &icuStatus);
-       if (fConverter == NULL)
-               return B_NAME_NOT_FOUND;
-
-       icuStatus = U_ZERO_ERROR;
-       ucnv_setToUCallBack(fConverter, UCNV_TO_U_CALLBACK_STOP, NULL, NULL,
-               NULL, &icuStatus);
-       icuStatus = U_ZERO_ERROR;
-       ucnv_setFromUCallBack(fConverter, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL,
-               NULL, &icuStatus);
-       if (!U_SUCCESS(icuStatus))
-               return B_ERROR;
+       // create a new converter for the current charset
+       result = ICUConverterManager::Instance()->CreateConverter(fGivenCharset,
+               converterRef, tlsValue->converterID);
+       if (result != B_OK)
+               return result;
+
+       converterRefOut = converterRef;
 
        return B_OK;
 }
@@ -105,10 +113,13 @@ ICUCategoryData::_ConvertUnicodeStringToLocaleconvEntry(
        const UnicodeString& string, char* destination, int destinationSize,
        const char* defaultValue)
 {
-       status_t result = B_OK;
-       UErrorCode icuStatus = U_ZERO_ERROR;
+       ICUConverterRef converterRef;
+       status_t result = _GetConverter(converterRef);
+       if (result != B_OK)
+               return result;
 
-       ucnv_fromUChars(fConverter, destination, destinationSize,
+       UErrorCode icuStatus = U_ZERO_ERROR;
+       ucnv_fromUChars(converterRef->Converter(), destination, destinationSize,
                string.getBuffer(), string.length(), &icuStatus);
        if (!U_SUCCESS(icuStatus)) {
                switch (icuStatus) {
@@ -131,5 +142,13 @@ ICUCategoryData::_ConvertUnicodeStringToLocaleconvEntry(
 }
 
 
+status_t
+ICUCategoryData::_SetupConverter()
+{
+       ICUConverterRef converterRef;
+       return _GetConverter(converterRef);
+}
+
+
 }      // namespace Libroot
 }      // namespace BPrivate
diff --git a/src/system/libroot/add-ons/icu/ICUCollateData.cpp 
b/src/system/libroot/add-ons/icu/ICUCollateData.cpp
index c394886..75f7c41 100644
--- a/src/system/libroot/add-ons/icu/ICUCollateData.cpp
+++ b/src/system/libroot/add-ons/icu/ICUCollateData.cpp
@@ -10,13 +10,16 @@
 
 #include <unicode/unistr.h>
 
+#include "ICUConverterManager.h"
+
 
 namespace BPrivate {
 namespace Libroot {
 
 
-ICUCollateData::ICUCollateData()
+ICUCollateData::ICUCollateData(pthread_key_t tlsKey)
        :
+       inherited(tlsKey),
        fCollator(NULL)
 {
 }
@@ -150,8 +153,14 @@ ICUCollateData::_ToUnicodeString(const char* in, 
UnicodeString& out)
        if (inLen == 0)
                return B_OK;
 
+       ICUConverterRef converterRef;
+       status_t result = _GetConverter(converterRef);
+       if (result != B_OK)
+               return result;
+
        UErrorCode icuStatus = U_ZERO_ERROR;
-       int32_t outLen = ucnv_toUChars(fConverter, NULL, 0, in, inLen, 
&icuStatus);
+       int32_t outLen = ucnv_toUChars(converterRef->Converter(), NULL, 0, in,
+               inLen, &icuStatus);
        if (icuStatus != U_BUFFER_OVERFLOW_ERROR)
                return B_BAD_VALUE;
        if (outLen < 0)
@@ -161,8 +170,8 @@ ICUCollateData::_ToUnicodeString(const char* in, 
UnicodeString& out)
 
        UChar* outBuf = out.getBuffer(outLen + 1);
        icuStatus = U_ZERO_ERROR;
-       outLen
-               = ucnv_toUChars(fConverter, outBuf, outLen + 1, in, inLen, 
&icuStatus);
+       outLen = ucnv_toUChars(converterRef->Converter(), outBuf, outLen + 1, 
in,
+               inLen, &icuStatus);
        if (!U_SUCCESS(icuStatus)) {
                out.releaseBuffer(0);
                return B_BAD_VALUE;
diff --git a/src/system/libroot/add-ons/icu/ICUCtypeData.cpp 
b/src/system/libroot/add-ons/icu/ICUCtypeData.cpp
index 4e68605..3a4d64c 100644
--- a/src/system/libroot/add-ons/icu/ICUCtypeData.cpp
+++ b/src/system/libroot/add-ons/icu/ICUCtypeData.cpp
@@ -16,8 +16,9 @@ namespace BPrivate {
 namespace Libroot {
 
 
-ICUCtypeData::ICUCtypeData()
+ICUCtypeData::ICUCtypeData(pthread_key_t tlsKey)
        :
+       inherited(tlsKey),
        fDataBridge(NULL)
 {
 }
@@ -47,7 +48,14 @@ ICUCtypeData::SetTo(const Locale& locale, const char* 
posixLocaleName)
 
        UErrorCode icuStatus = U_ZERO_ERROR;
 
-       ucnv_reset(fConverter);
+       ICUConverterRef converterRef;
+       result = _GetConverter(converterRef);
+       if (result != B_OK)
+               return result;
+
+       UConverter* converter = converterRef->Converter();
+
+       ucnv_reset(converter);
        char buffer[] = { 0, 0 };
        for (int i = 0; i < 256; ++i) {
                const char* source = buffer;
@@ -55,7 +63,7 @@ ICUCtypeData::SetTo(const Locale& locale, const char* 
posixLocaleName)
                buffer[1] = '\0';
                icuStatus = U_ZERO_ERROR;
                UChar32 unicodeChar
-                       = ucnv_getNextUChar(fConverter, &source, source + 1, 
&icuStatus);
+                       = ucnv_getNextUChar(converter, &source, source + 1, 
&icuStatus);
 
                unsigned short classInfo = 0;
                unsigned int toLower = i;
@@ -88,13 +96,13 @@ ICUCtypeData::SetTo(const Locale& locale, const char* 
posixLocaleName)
 
                        UChar lowerChar = u_tolower(unicodeChar);
                        icuStatus = U_ZERO_ERROR;
-                       ucnv_fromUChars(fConverter, buffer, 1, &lowerChar, 1, 
&icuStatus);
+                       ucnv_fromUChars(converter, buffer, 1, &lowerChar, 1, 
&icuStatus);
                        if (U_SUCCESS(icuStatus))
                                toLower = (unsigned char)buffer[0];
 
                        UChar upperChar = u_toupper(unicodeChar);
                        icuStatus = U_ZERO_ERROR;
-                       ucnv_fromUChars(fConverter, buffer, 1, &upperChar, 1, 
&icuStatus);
+                       ucnv_fromUChars(converter, buffer, 1, &upperChar, 1, 
&icuStatus);
                        if (U_SUCCESS(icuStatus))
                                toUpper = (unsigned char)buffer[0];
                }
diff --git a/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp 
b/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
index 52bff29..8733b0f 100644
--- a/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
+++ b/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
@@ -28,9 +28,13 @@ CreateInstance()
 
 ICULocaleBackend::ICULocaleBackend()
        :
-       fMonetaryData(fLocaleConv),
-       fNumericData(fLocaleConv),
-       fTimeData(fLCTimeInfo),
+       fThreadLocalStorageKey(_CreateThreadLocalStorageKey()),
+       fCollateData(fThreadLocalStorageKey),
+       fCtypeData(fThreadLocalStorageKey),
+       fMessagesData(fThreadLocalStorageKey),
+       fMonetaryData(fThreadLocalStorageKey, fLocaleConv),
+       fNumericData(fThreadLocalStorageKey, fLocaleConv),
+       fTimeData(fThreadLocalStorageKey, fLCTimeInfo),
        fTimeConversion(fTimeData)
 {
 }
@@ -38,6 +42,7 @@ ICULocaleBackend::ICULocaleBackend()
 
 ICULocaleBackend::~ICULocaleBackend()
 {
+       pthread_key_delete(fThreadLocalStorageKey);
 }
 
 
@@ -371,5 +376,25 @@ ICULocaleBackend::_SetPosixLocale(int category)
 }
 
 
+pthread_key_t
+ICULocaleBackend::_CreateThreadLocalStorageKey()
+{
+       pthread_key_t key;
+
+       pthread_key_create(&key, 
ICULocaleBackend::_DestroyThreadLocalStorageValue);
+
+       return key;
+}
+
+
+void ICULocaleBackend::_DestroyThreadLocalStorageValue(void* value)
+{
+       ICUThreadLocalStorageValue* tlsValue
+               = static_cast<ICUThreadLocalStorageValue*>(value);
+
+       delete tlsValue;
+}
+
+
 }      // namespace Libroot
 }      // namespace BPrivate
diff --git a/src/system/libroot/add-ons/icu/ICULocaleconvData.cpp 
b/src/system/libroot/add-ons/icu/ICULocaleconvData.cpp
index f59272e..1b64b15 100644
--- a/src/system/libroot/add-ons/icu/ICULocaleconvData.cpp
+++ b/src/system/libroot/add-ons/icu/ICULocaleconvData.cpp
@@ -13,6 +13,12 @@ namespace BPrivate {
 namespace Libroot {
 
 
+ICULocaleconvData::ICULocaleconvData(pthread_key_t tlsKey)
+       : inherited(tlsKey)
+{
+}
+
+
 status_t
 ICULocaleconvData::_SetLocaleconvEntry(const DecimalFormatSymbols* 
formatSymbols,
        char* destination, FormatSymbol symbol, const char* defaultValue)
diff --git a/src/system/libroot/add-ons/icu/ICUMessagesData.cpp 
b/src/system/libroot/add-ons/icu/ICUMessagesData.cpp
index dafcfe4..c2e0fba 100644
--- a/src/system/libroot/add-ons/icu/ICUMessagesData.cpp
+++ b/src/system/libroot/add-ons/icu/ICUMessagesData.cpp
@@ -14,6 +14,12 @@ namespace BPrivate {
 namespace Libroot {
 
 
+ICUMessagesData::ICUMessagesData(pthread_key_t tlsKey)
+       : inherited(tlsKey)
+{
+}
+
+
 void
 ICUMessagesData::Initialize(LocaleMessagesDataBridge* dataBridge)
 {
diff --git a/src/system/libroot/add-ons/icu/ICUMonetaryData.cpp 
b/src/system/libroot/add-ons/icu/ICUMonetaryData.cpp
index a7d470f..597a7f1 100644
--- a/src/system/libroot/add-ons/icu/ICUMonetaryData.cpp
+++ b/src/system/libroot/add-ons/icu/ICUMonetaryData.cpp
@@ -15,8 +15,9 @@ namespace BPrivate {
 namespace Libroot {
 
 
-ICUMonetaryData::ICUMonetaryData(struct lconv& localeConv)
+ICUMonetaryData::ICUMonetaryData(pthread_key_t tlsKey, struct lconv& 
localeConv)
        :
+       inherited(tlsKey),
        fLocaleConv(localeConv),
        fPosixLocaleConv(NULL)
 {
diff --git a/src/system/libroot/add-ons/icu/ICUNumericData.cpp 
b/src/system/libroot/add-ons/icu/ICUNumericData.cpp
index 85bec2d..c21cae0 100644
--- a/src/system/libroot/add-ons/icu/ICUNumericData.cpp
+++ b/src/system/libroot/add-ons/icu/ICUNumericData.cpp
@@ -15,8 +15,9 @@ namespace BPrivate {
 namespace Libroot {
 
 
-ICUNumericData::ICUNumericData(struct lconv& localeConv)
+ICUNumericData::ICUNumericData(pthread_key_t tlsKey, struct lconv& localeConv)
        :
+       inherited(tlsKey),
        fLocaleConv(localeConv),
        fDataBridge(NULL)
 {
diff --git a/src/system/libroot/add-ons/icu/ICUTimeData.cpp 
b/src/system/libroot/add-ons/icu/ICUTimeData.cpp
index 4354150..aeeeca5 100644
--- a/src/system/libroot/add-ons/icu/ICUTimeData.cpp
+++ b/src/system/libroot/add-ons/icu/ICUTimeData.cpp
@@ -20,8 +20,9 @@ namespace BPrivate {
 namespace Libroot {
 
 
-ICUTimeData::ICUTimeData(struct lc_time_t& lcTimeInfo)
+ICUTimeData::ICUTimeData(pthread_key_t tlsKey, struct lc_time_t& lcTimeInfo)
        :
+       inherited(tlsKey),
        fLCTimeInfo(lcTimeInfo),
        fDataBridge(NULL)
 {

############################################################################

Commit:      fa02fc690733b0189f91ba43b5503e986f148ed8
URL:         http://cgit.haiku-os.org/haiku/commit/?id=fa02fc6
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 16:23:04 2011 UTC

Adjust mbstate_t to what we need.

* we maintain the character count and the ID of the corresponding
  ICU converter in mbstate_t

----------------------------------------------------------------------------

diff --git a/headers/posix/wchar.h b/headers/posix/wchar.h
index 81de5cc..773234c 100644
--- a/headers/posix/wchar.h
+++ b/headers/posix/wchar.h
@@ -6,6 +6,7 @@
 #define _WCHAR_H
 
 
+#include <limits.h>
 #include <stddef.h>
 #include <stdio.h>
 
@@ -26,8 +27,8 @@ typedef __WINT_TYPE__ wint_t;
 typedef int wctype_t;
 
 typedef struct {
-       int             __count;
-       wint_t  __value;
+       unsigned int count;
+       unsigned int converterID;
 } mbstate_t;
 
 

############################################################################

Commit:      e0eb1d38c4e11e7d728ea2de0a374a4e30c04278
URL:         http://cgit.haiku-os.org/haiku/commit/?id=e0eb1d3
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 16:32:39 2011 UTC

Let MB_CUR_LEN lookup the actual value.

* instead of yielding 1, MB_CUR_LEN now looks up the correct
  value in the ctype data provided by the locale backend

----------------------------------------------------------------------------

diff --git a/headers/posix/ctype.h b/headers/posix/ctype.h
index 5b0c420..9d75cea 100644
--- a/headers/posix/ctype.h
+++ b/headers/posix/ctype.h
@@ -72,6 +72,8 @@ extern const int *__ctype_toupper;
 #define isupper(c)     __isctype((c), _ISupper)
 #define isxdigit(c)    __isctype((c), _ISxdigit)
 
+extern unsigned short int __ctype_mb_cur_max;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/headers/posix/stdlib.h b/headers/posix/stdlib.h
index 24ebf81..efec906 100644
--- a/headers/posix/stdlib.h
+++ b/headers/posix/stdlib.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2010 Haiku Inc. All Rights Reserved.
+ * Copyright 2002-2011 Haiku Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  */
 #ifndef _STDLIB_H_
@@ -13,9 +13,8 @@
 #include <sys/types.h>
 #include <wchar_t.h>
 
-
 #define RAND_MAX      0x7fffffff
-#define MB_CUR_MAX    1
+#define MB_CUR_MAX    (__ctype_get_mb_cur_max())
 
 #define EXIT_SUCCESS  0
 #define EXIT_FAILURE  1
@@ -180,6 +179,9 @@ extern int          grantpt(int masterFD);
 extern char*   ptsname(int masterFD);
 extern int             unlockpt(int masterFD);
 
+/* internal accessor to value for MB_CUR_MAX */
+extern unsigned short __ctype_get_mb_cur_max(void);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/headers/private/libroot/locale/LocaleBackend.h 
b/headers/private/libroot/locale/LocaleBackend.h
index 3e754e6..4228f84 100644
--- a/headers/private/libroot/locale/LocaleBackend.h
+++ b/headers/private/libroot/locale/LocaleBackend.h
@@ -31,6 +31,8 @@ struct LocaleCtypeDataBridge {
        const int*                              posixToUpperMap;
 
        LocaleCtypeDataBridge();
+
+       void setMbCurMax(unsigned short mbCurMax);
 };
 
 
diff --git a/src/system/libroot/posix/glibc/locale/Jamfile 
b/src/system/libroot/posix/glibc/locale/Jamfile
index 7797505..918a146 100644
--- a/src/system/libroot/posix/glibc/locale/Jamfile
+++ b/src/system/libroot/posix/glibc/locale/Jamfile
@@ -23,6 +23,5 @@ MergeObject posix_gnu_locale.o :
        lc-messages.c
        lc-monetary.c
        lc-numeric.c
-       mb_cur_max.c
        xlocale.c
 ;
diff --git a/src/system/libroot/posix/glibc/stdlib/stdlib.h 
b/src/system/libroot/posix/glibc/stdlib/stdlib.h
index 275f34a..6d175df 100644
--- a/src/system/libroot/posix/glibc/stdlib/stdlib.h
+++ b/src/system/libroot/posix/glibc/stdlib/stdlib.h
@@ -135,7 +135,7 @@ __END_NAMESPACE_C99
 
 /* Maximum length of a multibyte character in the current locale.  */
 #define        MB_CUR_MAX      (__ctype_get_mb_cur_max ())
-extern size_t __ctype_get_mb_cur_max (void) __THROW;
+extern unsigned short __ctype_get_mb_cur_max(void);
 
 
 __BEGIN_NAMESPACE_STD
diff --git a/src/system/libroot/posix/locale/LocaleDataBridge.cpp 
b/src/system/libroot/posix/locale/LocaleDataBridge.cpp
index d2cce87..c8f2631 100644
--- a/src/system/libroot/posix/locale/LocaleDataBridge.cpp
+++ b/src/system/libroot/posix/locale/LocaleDataBridge.cpp
@@ -36,6 +36,12 @@ LocaleCtypeDataBridge::LocaleCtypeDataBridge()
 }
 
 
+void LocaleCtypeDataBridge::setMbCurMax(unsigned short mbCurMax)
+{
+       __ctype_mb_cur_max = mbCurMax;
+}
+
+
 LocaleMessagesDataBridge::LocaleMessagesDataBridge()
        :
        posixLanginfo(gPosixLanginfo)
diff --git a/src/system/libroot/posix/locale/ctype.cpp 
b/src/system/libroot/posix/locale/ctype.cpp
index 156a2aa..08faf6a 100644
--- a/src/system/libroot/posix/locale/ctype.cpp
+++ b/src/system/libroot/posix/locale/ctype.cpp
@@ -26,6 +26,20 @@
 #undef toupper
 
 
+extern "C"
+{
+
+
+unsigned short int __ctype_mb_cur_max = 1;
+
+
+unsigned short
+__ctype_get_mb_cur_max()
+{
+       return __ctype_mb_cur_max;
+}
+
+
 int
 isalnum(int c)
 {
@@ -180,3 +194,6 @@ toupper(int c)
 
        return c;
 }
+
+
+}

############################################################################

Commit:      0f21cf0ca01b3cf4f04545bda253cb1c7da19689
URL:         http://cgit.haiku-os.org/haiku/commit/?id=0f21cf0
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 16:40:45 2011 UTC

Define MB_LEN_MAX to 16.

* we follow glibc's example and allow 16 bytes as maximum multibyte
  character length (ICU's data currently shows an actual maximum
  of 8 bytes)

----------------------------------------------------------------------------

diff --git a/headers/build/gcc-2.95.3/limits.h 
b/headers/build/gcc-2.95.3/limits.h
index 8a24332..20b9c47 100644
--- a/headers/build/gcc-2.95.3/limits.h
+++ b/headers/build/gcc-2.95.3/limits.h
@@ -23,7 +23,7 @@
 
 /* Maximum length of a multibyte character.  */
 #ifndef MB_LEN_MAX
-#define MB_LEN_MAX 1
+#define MB_LEN_MAX 16
 #endif
 
 /* Minimum and maximum values a `signed char' can hold.  */
diff --git a/headers/posix/limits.h b/headers/posix/limits.h
index 8fd8ea1..48b1d98 100644
--- a/headers/posix/limits.h
+++ b/headers/posix/limits.h
@@ -26,6 +26,8 @@
 #define        LLONG_MAX               LONGLONG_MAX
 #define        LLONG_MIN               LONGLONG_MIN
 
+#define MB_LEN_MAX             16
+
 #define OFF_MAX                        LLONG_MAX
 #define OFF_MIN                        LLONG_MIN
 

############################################################################

Commit:      28ae43d0339118e569c3a0ba1443b3befbb40a38
URL:         http://cgit.haiku-os.org/haiku/commit/?id=28ae43d
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 17:17:58 2011 UTC

Add multibyte-support to ctype-locale backend.

* add actual converter methods MultibyteToWchar() and WcharToMultibyte()
  to locale backend and implement them in the ctype subpart
* add management code for maintaining converters referenced by mbstate_t

----------------------------------------------------------------------------

diff --git a/headers/private/libroot/locale/ICUCtypeData.h 
b/headers/private/libroot/locale/ICUCtypeData.h
index e62db41..45b7fb0 100644
--- a/headers/private/libroot/locale/ICUCtypeData.h
+++ b/headers/private/libroot/locale/ICUCtypeData.h
@@ -30,9 +30,20 @@ public:
                        status_t                        ToWCTrans(wint_t wc, 
wctrans_t transition,
                                                                        wint_t& 
result);
 
+                       status_t                        
MultibyteToWchar(wchar_t* wcOut, const char* mb,
+                                                                       size_t 
mbLength, mbstate_t* mbState,
+                                                                       size_t& 
lengthOut);
+                       status_t                        WcharToMultibyte(char* 
mbOut, wchar_t wc,
+                                                                       
mbstate_t* mbState, size_t& lengthOut);
+
                        const char*                     GetLanginfo(int index);
 
 private:
+                       status_t                        
_GetConverterForMbState(mbstate_t* mbState,
+                                                                       
ICUConverterRef& converterRefOut);
+
+                       status_t                        
_DropConverterFromMbState(mbstate_t* mbState);
+
                        /*
                         * The following arrays have 384 elements where the 
elements at
                         * index -128..-2 mirror the elements at index 128..255 
(to protect
diff --git a/headers/private/libroot/locale/ICULocaleBackend.h 
b/headers/private/libroot/locale/ICULocaleBackend.h
index de3c1af..5ead68c 100644
--- a/headers/private/libroot/locale/ICULocaleBackend.h
+++ b/headers/private/libroot/locale/ICULocaleBackend.h
@@ -41,6 +41,12 @@ public:
        virtual status_t                        ToWCTrans(wint_t wc, wctrans_t 
transition,
                                                                        wint_t& 
result);
 
+       virtual status_t                        MultibyteToWchar(wchar_t* 
wcOut, const char* mb,
+                                                                       size_t 
mbLength, mbstate_t* mbState,
+                                                                       size_t& 
lengthOut);
+       virtual status_t                        WcharToMultibyte(char* mbOut, 
wchar_t wc,
+                                                                       
mbstate_t* mbState, size_t& lengthOut);
+
        virtual const char*                     GetLanginfo(int index);
 
        virtual status_t                        Strcoll(const char* a, const 
char* b, int& out);
diff --git a/headers/private/libroot/locale/LocaleBackend.h 
b/headers/private/libroot/locale/LocaleBackend.h
index 4228f84..fb00d43 100644
--- a/headers/private/libroot/locale/LocaleBackend.h
+++ b/headers/private/libroot/locale/LocaleBackend.h
@@ -123,6 +123,12 @@ public:
        virtual status_t                        ToWCTrans(wint_t wc, wctrans_t 
transition,
                                                                        wint_t& 
result) = 0;
 
+       virtual status_t                        MultibyteToWchar(wchar_t* 
wcOut, const char* mb,
+                                                                       size_t 
mbLength, mbstate_t* mbState,
+                                                                       size_t& 
lengthOut) = 0;
+       virtual status_t                        WcharToMultibyte(char* mbOut, 
wchar_t wc,
+                                                                       
mbstate_t* mbState, size_t& lengthOut) = 0;
+
        virtual const char*                     GetLanginfo(int index) = 0;
 
        virtual status_t                        Strcoll(const char* a, const 
char* b,
diff --git a/src/system/libroot/add-ons/icu/ICUCtypeData.cpp 
b/src/system/libroot/add-ons/icu/ICUCtypeData.cpp
index 3a4d64c..8d3213a 100644
--- a/src/system/libroot/add-ons/icu/ICUCtypeData.cpp
+++ b/src/system/libroot/add-ons/icu/ICUCtypeData.cpp
@@ -54,8 +54,10 @@ ICUCtypeData::SetTo(const Locale& locale, const char* 
posixLocaleName)
                return result;
 
        UConverter* converter = converterRef->Converter();
-
        ucnv_reset(converter);
+
+       fDataBridge->setMbCurMax(ucnv_getMaxCharSize(converter));
+
        char buffer[] = { 0, 0 };
        for (int i = 0; i < 256; ++i) {
                const char* source = buffer;
@@ -130,6 +132,8 @@ ICUCtypeData::SetToPosix()
                memcpy(fClassInfo, fDataBridge->posixClassInfo, 
sizeof(fClassInfo));
                memcpy(fToLowerMap, fDataBridge->posixToLowerMap, 
sizeof(fToLowerMap));
                memcpy(fToUpperMap, fDataBridge->posixToUpperMap, 
sizeof(fToUpperMap));
+
+               fDataBridge->setMbCurMax(1);
        }
 
        return result;
@@ -189,6 +193,94 @@ ICUCtypeData::ToWCTrans(wint_t wc, wctrans_t transition, 
wint_t& result)
 }
 
 
+status_t
+ICUCtypeData::MultibyteToWchar(wchar_t* wcOut, const char* mb, size_t mbLen,
+       mbstate_t* mbState, size_t& lengthOut)
+{
+       ICUConverterRef converterRef;
+       status_t result = _GetConverterForMbState(mbState, converterRef);
+       if (result != B_OK)
+               return result;
+
+       UConverter* converter = converterRef->Converter();
+
+       // do the conversion
+       UErrorCode icuStatus = U_ZERO_ERROR;
+
+       const char* buffer = mb;
+       UChar targetBuffer[2];
+       UChar* target = targetBuffer;
+       ucnv_toUnicode(converter, &target, target + 1, &buffer, buffer + mbLen,
+               NULL, FALSE, &icuStatus);
+       size_t sourceLengthUsed = buffer - mb;
+       size_t targetLengthUsed = (size_t)(target - targetBuffer);
+
+       if (icuStatus == U_BUFFER_OVERFLOW_ERROR && targetLengthUsed > 0) {
+               // we've got one character, which is all that we wanted
+               icuStatus = U_ZERO_ERROR;
+       }
+
+       UChar32 unicodeChar = 0xBADBEEF;
+
+       if (!U_SUCCESS(icuStatus)) {
+               // conversion failed because of illegal character sequence
+               result = B_BAD_DATA;
+       } else  if (targetLengthUsed == 0) {
+               mbState->count = sourceLengthUsed;
+               result = B_BAD_INDEX;
+       } else {
+               U16_GET(targetBuffer, 0, 0, 2, unicodeChar);
+
+               if (unicodeChar == 0) {
+                       // reset to initial state
+                       _DropConverterFromMbState(mbState);
+                       memset(mbState, 0, sizeof(mbstate_t));
+                       lengthOut = 0;
+               } else {
+                       mbState->count = 0;
+                       lengthOut = sourceLengthUsed;
+               }
+
+               if (wcOut != NULL)
+                       *wcOut = unicodeChar;
+
+               result = B_OK;
+       }
+
+       return result;
+}
+
+
+status_t
+ICUCtypeData::WcharToMultibyte(char* mbOut, wchar_t wc, mbstate_t* mbState,
+       size_t& lengthOut)
+{
+       ICUConverterRef converterRef;
+       status_t result = _GetConverterForMbState(mbState, converterRef);
+       if (result != B_OK)
+               return result;
+
+       UConverter* converter = converterRef->Converter();
+
+       // do the conversion
+       UErrorCode icuStatus = U_ZERO_ERROR;
+       lengthOut = ucnv_fromUChars(converter, mbOut, MB_LEN_MAX, (UChar*)&wc,
+               1, &icuStatus);
+
+       if (!U_SUCCESS(icuStatus)) {
+               if (icuStatus == U_ILLEGAL_ARGUMENT_ERROR) {
+                       // bad converter (shouldn't really happen)
+                       return B_BAD_VALUE;
+               }
+
+               // conversion failed because of illegal/unmappable character
+               return B_BAD_DATA;
+       }
+
+       return B_OK;
+}
+
+
 const char*
 ICUCtypeData::GetLanginfo(int index)
 {
@@ -201,5 +293,45 @@ ICUCtypeData::GetLanginfo(int index)
 }
 
 
+status_t
+ICUCtypeData::_GetConverterForMbState(mbstate_t* mbState,
+       ICUConverterRef& converterRefOut)
+{
+       ICUConverterRef converterRef;
+       status_t result = ICUConverterManager::Instance()->GetConverter(
+               mbState->converterID, converterRef);
+       if (result == B_OK) {
+               if (strcmp(converterRef->Charset(), fGivenCharset) == 0) {
+                       converterRefOut = converterRef;
+                       return B_OK;
+               }
+
+               // charset no longer matches the converter, we need to dump it 
and
+               // create a new one
+               _DropConverterFromMbState(mbState);
+       }
+
+       // create a new converter for the current charset
+       result = ICUConverterManager::Instance()->CreateConverter(fGivenCharset,
+               converterRef, mbState->converterID);
+       if (result != B_OK)
+               return result;
+
+       converterRefOut = converterRef;
+
+       return B_OK;
+}
+
+
+status_t
+ICUCtypeData::_DropConverterFromMbState(mbstate_t* mbState)
+{
+       ICUConverterManager::Instance()->DropConverter(mbState->converterID);
+       mbState->converterID = 0;
+
+       return B_OK;
+}
+
+
 }      // namespace Libroot
 }      // namespace BPrivate
diff --git a/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp 
b/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
index 8733b0f..d6b0fa1 100644
--- a/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
+++ b/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
@@ -152,6 +152,26 @@ ICULocaleBackend::ToWCTrans(wint_t wc, wctrans_t 
transition, wint_t& result)
 }
 
 
+status_t
+ICULocaleBackend::MultibyteToWchar(wchar_t* wcOut, const char* mb,
+       size_t mbLength, mbstate_t* mbState, size_t& lengthOut)
+{
+       ErrnoMaintainer errnoMaintainer;
+
+       return fCtypeData.MultibyteToWchar(wcOut, mb, mbLength, mbState, 
lengthOut);
+}
+
+
+status_t
+ICULocaleBackend::WcharToMultibyte(char* mbOut, wchar_t wc, mbstate_t* mbState,
+       size_t& lengthOut)
+{
+       ErrnoMaintainer errnoMaintainer;
+
+       return fCtypeData.WcharToMultibyte(mbOut, wc, mbState, lengthOut);
+}
+
+
 const char*
 ICULocaleBackend::GetLanginfo(int index)
 {

############################################################################

Commit:      32a04e872187f81d72bc1611bde8be02083eabc7
URL:         http://cgit.haiku-os.org/haiku/commit/?id=32a04e8
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 17:19:28 2011 UTC

Formatting cleanup of B_DEFINE_WEAK_ALIAS macro.

* This doesn't necessarily belong here, but we're going to make use
  of it in the next changeset. Additionally, this change to BeBuild.h
  will trigger a rebuild of nearly all files, and applying it during
  the multibyte-related work will skip another full rebuild ...

----------------------------------------------------------------------------

diff --git a/headers/os/BeBuild.h b/headers/os/BeBuild.h
index 63fac1f..f2067ab 100644
--- a/headers/os/BeBuild.h
+++ b/headers/os/BeBuild.h
@@ -79,7 +79,7 @@
        __asm__(".symver " function "," versionedSymbol)
 
 #define B_DEFINE_WEAK_ALIAS(name, alias_name)  \
-       __typeof (name) alias_name __attribute__ ((weak, alias (#name)))
+       __typeof(name) alias_name __attribute__((weak, alias(#name)))
 
 
 #endif /* _BE_BUILD_H */

############################################################################

Commit:      cc5eca75540f0750fbc325eab1f82c168564336b
URL:         http://cgit.haiku-os.org/haiku/commit/?id=cc5eca7
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 17:31:27 2011 UTC

Activate our new multibyte implementation.

* add implementations for the following multibyte-related
  functions:
    btwoc()
    mblen()
    mbrlen()
    mbrtowc()
    mbsinit()
    mbtowc()
    wcrtomb()
    wcswidth()
    wctob()
    wctomb()
* the implementation of the above function live in a symbol
  named __<name>, the above symbol names are defined as a weak
  alias to the internal ones - TODO: we need to make sure to
  only invoked the internal functions (i.e. prepended with __)
  in order to avoid problems with symbol preemption.
* deactivate the limited mb implementation we provided before,
  as well as respective stuff from glibc

----------------------------------------------------------------------------

diff --git a/headers/private/libroot/wchar_private.h 
b/headers/private/libroot/wchar_private.h
index 6fc699f..b3dc5fe 100644
--- a/headers/private/libroot/wchar_private.h
+++ b/headers/private/libroot/wchar_private.h
@@ -17,11 +17,14 @@ __BEGIN_DECLS
 
 extern wint_t  __btowc(int);
 
+extern int             __mblen(const char *string, size_t maxSize);
 extern size_t  __mbrlen(const char *s, size_t n, mbstate_t *ps);
 extern size_t  __mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps);
 extern int             __mbsinit(const mbstate_t *);
 extern size_t  __mbsrtowcs(wchar_t *dst, const char **src, size_t len,
                                        mbstate_t *ps);
+extern size_t  __mbstowcs(wchar_t *pwcs, const char *string, size_t maxSize);
+extern int             __mbtowc(wchar_t *pwc, const char *string, size_t 
maxSize);
 
 extern size_t   __wcrtomb(char *, wchar_t, mbstate_t *);
 extern wchar_t *__wcscat(wchar_t *, const wchar_t *);
@@ -51,6 +54,8 @@ extern long double                    __wcstold(const wchar_t 
*, wchar_t **);
 extern long long                       __wcstoll(const wchar_t *, wchar_t **, 
int);
 extern unsigned long           __wcstoul(const wchar_t *, wchar_t **, int);
 extern unsigned long long      __wcstoull(const wchar_t *, wchar_t **, int);
+extern size_t  __wcstombs(char *string, const wchar_t *pwcs, size_t maxSize);
+extern int             __wctomb(char *string, wchar_t wchar);
 extern wchar_t *__wcswcs(const wchar_t *, const wchar_t *);
 extern int             __wcswidth(const wchar_t *, size_t);
 extern size_t  __wcsxfrm(wchar_t *, const wchar_t *, size_t);
diff --git a/src/system/libroot/posix/glibc/stdlib/Jamfile 
b/src/system/libroot/posix/glibc/stdlib/Jamfile
index 94e22c7..acf6be7 100644
--- a/src/system/libroot/posix/glibc/stdlib/Jamfile
+++ b/src/system/libroot/posix/glibc/stdlib/Jamfile
@@ -23,9 +23,7 @@ MergeObject posix_gnu_stdlib.o :
        lcong48_r.c
        lrand48.c
        lrand48_r.c
-       mblen.c
        mbstowcs.c
-       mbtowc.c
        mrand48.c
        mrand48_r.c
        nrand48.c
@@ -39,5 +37,4 @@ MergeObject posix_gnu_stdlib.o :
        strtold.c
        strtof.c
        wcstombs.c
-       wctomb.c
 ;
diff --git a/src/system/libroot/posix/glibc/wcsmbs/Jamfile 
b/src/system/libroot/posix/glibc/wcsmbs/Jamfile
index 54fe9e2..b8c4768 100644
--- a/src/system/libroot/posix/glibc/wcsmbs/Jamfile
+++ b/src/system/libroot/posix/glibc/wcsmbs/Jamfile
@@ -15,16 +15,11 @@ SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc ;
 SubDirCcFlags -D_GNU_SOURCE -DUSE_IN_LIBIO ;
 
 MergeObject posix_gnu_wcsmbs.o :
-       btowc.c
-       mbrlen.c
-       mbrtowc.c
-       mbsinit.c
        mbsnrtowcs.c
        mbsrtowcs.c
 #      mbsrtowcs_l.c
        wcpcpy.c
        wcpncpy.c
-       wcrtomb.c
        wcscasecmp.c
 #      wcscasecmp_l.c
        wcscat.c
@@ -55,10 +50,7 @@ MergeObject posix_gnu_wcsmbs.o :
        wcstold.c
        wcstoul.c
        wcstoull.c
-#      wcswidth.c
        wcsxfrm.c
-       wctob.c
-#      wcwidth.c
        wmemchr.c
        wmemcmp.c
        wmemcpy.c
diff --git a/src/system/libroot/posix/locale/Jamfile 
b/src/system/libroot/posix/locale/Jamfile
index b35c6ee..f65b334 100644
--- a/src/system/libroot/posix/locale/Jamfile
+++ b/src/system/libroot/posix/locale/Jamfile
@@ -13,10 +13,5 @@ MergeObject posix_locale.o :
        localeconv.cpp
        nl_langinfo.cpp
        setlocale.cpp
-       #mb_none.c
-       #mblen.c
-       #mbrtowc.c
-       #mbsinit.c
-       #wcrtomb.c
        wctype.cpp
 ;
diff --git a/src/system/libroot/posix/wchar/Jamfile 
b/src/system/libroot/posix/wchar/Jamfile
index 0c52b81..644a790 100644
--- a/src/system/libroot/posix/wchar/Jamfile
+++ b/src/system/libroot/posix/wchar/Jamfile
@@ -1,6 +1,20 @@
 SubDir HAIKU_TOP src system libroot posix wchar ;
 
+UsePrivateHeaders
+       [ FDirName libroot ]
+       [ FDirName libroot locale ]
+;
+
 MergeObject posix_wchar.o :
-       wcwidth.c
+       btowc.c
+       mblen.c
+       mbrlen.c
+       mbrtowc.cpp
+       mbsinit.c
+       mbtowc.c
+       wcrtomb.cpp
        wcswidth.c
+       wctob.c
+       wctomb.c
+       wcwidth.c
 ;
diff --git a/src/system/libroot/posix/wchar/btowc.c 
b/src/system/libroot/posix/wchar/btowc.c
new file mode 100644
index 0000000..9ba53fa
--- /dev/null
+++ b/src/system/libroot/posix/wchar/btowc.c
@@ -0,0 +1,33 @@
+/*
+** Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx All rights reserved.
+** Distributed under the terms of the Haiku License.
+*/
+
+#include <wchar_private.h>
+
+
+wint_t
+__btowc(int c)
+{
+       static mbstate_t internalMbState;
+       char character = (char)c;
+       wchar_t wc;
+
+       if (c == EOF)
+               return WEOF;
+
+       if (c == '\0')
+               return L'\0';
+
+       {
+               int byteCount = mbrtowc(&wc, &character, 1, &internalMbState);
+
+               if (byteCount != 1)
+                       return WEOF;
+       }
+
+       return wc;
+}
+
+
+B_DEFINE_WEAK_ALIAS(__btowc, btowc);
diff --git a/src/system/libroot/posix/wchar/mblen.c 
b/src/system/libroot/posix/wchar/mblen.c
new file mode 100644
index 0000000..d582e01
--- /dev/null
+++ b/src/system/libroot/posix/wchar/mblen.c
@@ -0,0 +1,32 @@
+/*
+** Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx All rights reserved.
+** Distributed under the terms of the Haiku License.
+*/
+ 
+#include <wchar_private.h>
+ 
+ 
+ int
+__mblen(const char* s, size_t n)
+ {
+       static mbstate_t internalMbState;
+       int rval;
+ 
+       if (s == NULL) {
+               static const mbstate_t initial;
+
+               internalMbState = initial;
+
+               return 0;       // we do not support stateful converters
+       }
+
+       rval = __mbrtowc(NULL, s, n, &internalMbState);
+
+       if (rval == -1 || rval == -2)
+               return -1;
+
+       return rval;
+ }
+
+
+B_DEFINE_WEAK_ALIAS(__mblen, mblen);
diff --git a/src/system/libroot/posix/wchar/mbrlen.c 
b/src/system/libroot/posix/wchar/mbrlen.c
new file mode 100644
index 0000000..03873f2
--- /dev/null
+++ b/src/system/libroot/posix/wchar/mbrlen.c
@@ -0,0 +1,21 @@
+/*
+** Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx All rights reserved.
+** Distributed under the terms of the Haiku License.
+*/
+ 
+#include <wchar_private.h>
+ 
+ 
+ size_t
+__mbrlen(const char* s, size_t n, mbstate_t* ps)
+ {
+       if (ps == NULL) {
+               static mbstate_t internalMbState;
+               ps = &internalMbState;
+       }
+ 
+       return __mbrtowc(NULL, s, n, ps);
+ }
+
+
+B_DEFINE_WEAK_ALIAS(__mbrlen, mbrlen);
diff --git a/src/system/libroot/posix/wchar/mbrtowc.cpp 
b/src/system/libroot/posix/wchar/mbrtowc.cpp
new file mode 100644
index 0000000..edd26a5
--- /dev/null
+++ b/src/system/libroot/posix/wchar/mbrtowc.cpp
@@ -0,0 +1,77 @@
+/*
+** Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx All rights reserved.
+** Distributed under the terms of the Haiku License.
+*/
+
+#include <errno.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "LocaleBackend.h"
+
+
+using BPrivate::Libroot::gLocaleBackend;
+
+
+extern "C" size_t
+__mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps)
+{
+       if (ps == NULL) {
+               static mbstate_t internalMbState;
+               ps = &internalMbState;
+       }
+
+       if (s == NULL)
+               return __mbrtowc(NULL, "", 1, ps);
+
+       if (gLocaleBackend == NULL) {
+               if (*s == '\0') {
+                       memset(ps, 0, sizeof(mbstate_t));
+
+                       if (pwc != NULL)
+                               *pwc = 0;
+
+                       return 0;
+               }
+
+               /*
+                * The POSIX locale is active. Since the POSIX locale only 
contains
+                * chars 0-127 and those ASCII chars are compatible with the 
UTF32
+                * values used in wint_t, we can just return the byte.
+                */
+
+               if (*s < 0) {
+                       // char is non-ASCII
+                       errno = EILSEQ;
+                       return (size_t)-1;
+               }
+
+               if (pwc != NULL)
+                       *pwc = *s;
+
+               return 1;
+       }
+
+       size_t lengthUsed;
+       status_t status
+               = gLocaleBackend->MultibyteToWchar(pwc, s, n, ps, lengthUsed);
+
+       if (status == B_BAD_INDEX)
+               return (size_t)-2;
+
+       if (status == B_BAD_DATA) {
+               errno = EILSEQ;
+               return (size_t)-1;
+       }
+
+       if (status != B_OK) {
+               errno = EINVAL;
+               return (size_t)-1;
+       }
+
+       return lengthUsed;
+}
+
+
+extern "C"
+B_DEFINE_WEAK_ALIAS(__mbrtowc, mbrtowc);
diff --git a/src/system/libroot/posix/wchar/mbsinit.c 
b/src/system/libroot/posix/wchar/mbsinit.c
new file mode 100644
index 0000000..5a17e7a
--- /dev/null
+++ b/src/system/libroot/posix/wchar/mbsinit.c
@@ -0,0 +1,16 @@
+/*
+** Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx All rights reserved.
+** Distributed under the terms of the Haiku License.
+*/
+ 
+#include <wchar_private.h>
+ 
+ 
+ int
+__mbsinit(const mbstate_t* ps)
+ {
+       return ps == NULL || ps->count == 0;
+ }
+
+
+B_DEFINE_WEAK_ALIAS(__mbsinit, mbsinit);
diff --git a/src/system/libroot/posix/wchar/mbtowc.c 
b/src/system/libroot/posix/wchar/mbtowc.c
new file mode 100644
index 0000000..e7f411f
--- /dev/null
+++ b/src/system/libroot/posix/wchar/mbtowc.c
@@ -0,0 +1,26 @@
+/*
+** Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx All rights reserved.
+** Distributed under the terms of the Haiku License.
+*/
+
+#include <errno.h>
+
+#include <wchar_private.h>
+
+
+int
+__mbtowc(wchar_t* pwc, const char* s, size_t n)
+{
+       static mbstate_t internalMbState;
+
+       int result = mbrtowc(pwc, s, n, &internalMbState);
+       if (result == -2) {
+               errno = EILSEQ;
+               result = -1;
+       }
+
+       return result;
+}
+
+
+B_DEFINE_WEAK_ALIAS(__mbtowc, mbtowc);
diff --git a/src/system/libroot/posix/wchar/wcrtomb.cpp 
b/src/system/libroot/posix/wchar/wcrtomb.cpp
new file mode 100644
index 0000000..3ef65e7
--- /dev/null
+++ b/src/system/libroot/posix/wchar/wcrtomb.cpp
@@ -0,0 +1,67 @@
+/*
+** Copyright 2011, Oliver Tappe <zooey@xxxxxxxxxxxxxxx>. All rights reserved.
+** Distributed under the terms of the Haiku License.
+*/
+
+#include <errno.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "LocaleBackend.h"
+
+
+using BPrivate::Libroot::gLocaleBackend;
+
+
+extern "C" size_t
+__wcrtomb(char* s, wchar_t wc, mbstate_t* ps)
+{
+       if (ps == NULL) {
+               static mbstate_t internalMbState;
+               ps = &internalMbState;
+       }
+
+       if (s == NULL) {
+               char internalBuffer[MB_LEN_MAX];
+
+               return __wcrtomb(internalBuffer, L'\0', ps);
+       }
+
+       if (gLocaleBackend == NULL) {
+               /*
+                * The POSIX locale is active. Since the POSIX locale only 
contains
+                * chars 0-127 and those ASCII chars are compatible with the 
UTF32
+                * values used in wint_t, we can just return the byte.
+                */
+
+               if (wc > 127) {
+                       // char is non-ASCII
+                       errno = EILSEQ;
+                       return (size_t)-1;
+               }
+
+               *s = char(wc);
+
+               return 1;
+       }
+
+       size_t lengthUsed;
+       status_t status = gLocaleBackend->WcharToMultibyte(s, wc, ps, 
lengthUsed);
+
+       if (status == B_BAD_INDEX)
+               return (size_t)-2;
+       if (status == B_BAD_DATA) {
+               errno = EILSEQ;
+               return (size_t)-1;
+       }
+       if (status != B_OK) {
+               errno = EINVAL;
+               return (size_t)-1;
+       }
+
+       return lengthUsed;
+}
+
+
+extern "C"
+B_DEFINE_WEAK_ALIAS(__wcrtomb, wcrtomb);
diff --git a/src/system/libroot/posix/wchar/wcswidth.c 
b/src/system/libroot/posix/wchar/wcswidth.c
index bf4f2d6..367a6fb 100644
--- a/src/system/libroot/posix/wchar/wcswidth.c
+++ b/src/system/libroot/posix/wchar/wcswidth.c
@@ -1,13 +1,13 @@
 /*
- * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxx
+ * Copyright 2010-2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxx
  * All rights reserved. Distributed under the terms of the MIT License.
  */
 
-#include <wchar.h>
+#include <wchar_private.h>
 
 
 int
-wcswidth(const wchar_t* wcstring, size_t n)
+__wcswidth(const wchar_t* wcstring, size_t n)
 {
        int width = 0;
 
@@ -21,3 +21,6 @@ wcswidth(const wchar_t* wcstring, size_t n)
 
        return width;
 }
+
+
+B_DEFINE_WEAK_ALIAS(__wcswidth, wcswidth);
diff --git a/src/system/libroot/posix/wchar/wctob.c 
b/src/system/libroot/posix/wchar/wctob.c
new file mode 100644
index 0000000..1537a62
--- /dev/null
+++ b/src/system/libroot/posix/wchar/wctob.c
@@ -0,0 +1,24 @@
+/*
+** Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx All rights reserved.
+** Distributed under the terms of the Haiku License.
+*/
+
+#include <stdint.h>
+
+#include <wchar_private.h>
+
+
+int
+__wctob(wint_t c)
+{
+       char internalBuffer[MB_LEN_MAX];
+
+       int32_t byteCount = wcrtomb(internalBuffer, c, NULL);
+       if (byteCount != 1)
+               return EOF;
+
+       return (int)(unsigned char)internalBuffer[0];
+}
+
+
+B_DEFINE_WEAK_ALIAS(__wctob, wctob);
diff --git a/src/system/libroot/posix/wchar/wctomb.c 
b/src/system/libroot/posix/wchar/wctomb.c
new file mode 100644
index 0000000..fb78bf3
--- /dev/null
+++ b/src/system/libroot/posix/wchar/wctomb.c
@@ -0,0 +1,18 @@
+/*
+** Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx All rights reserved.
+** Distributed under the terms of the Haiku License.
+*/
+
+#include <wchar_private.h>
+
+
+int
+__wctomb(char* s, wchar_t wc)
+{
+       static mbstate_t internalMbState;
+
+       return wcrtomb(s, wc, &internalMbState);
+}
+
+
+B_DEFINE_WEAK_ALIAS(__wctomb, wctomb);

############################################################################

Commit:      b4435552a7d4ae1b9a7055096c189296531c1f35
URL:         http://cgit.haiku-os.org/haiku/commit/?id=b443555
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 17:38:43 2011 UTC

Drop our old, limited multibyte implementation.

----------------------------------------------------------------------------

diff --git a/src/system/libroot/posix/locale/mb_defs.h 
b/src/system/libroot/posix/locale/mb_defs.h
deleted file mode 100755
index be183f2..0000000
--- a/src/system/libroot/posix/locale/mb_defs.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- * Copyright (c) 2004 Tim J. Robbins.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libc/locale/mblocal.h,v 1.5.18.1 2008/11/25 02:59:29 
kensmith Exp $
- */
-
-#ifndef _MB_DEFS_H_
-#define        _MB_DEFS_H_
-
-/*
- * Conversion function pointers for current encoding.
- */
-extern size_t (*__mbrtowc)(wchar_t *, const char *,
-    size_t, mbstate_t *);
-extern int (*__mbsinit)(const mbstate_t *);
-extern size_t (*__mbsnrtowcs)(wchar_t *, const char **,
-    size_t, size_t, mbstate_t *);
-extern size_t (*__wcrtomb)(char *, wchar_t, mbstate_t *);
-extern size_t (*__wcsnrtombs)(char *, const wchar_t **,
-    size_t, size_t, mbstate_t *);
-
-extern size_t __mbsnrtowcs_std(wchar_t * , const char **,
-    size_t, size_t, mbstate_t * );
-extern size_t __wcsnrtombs_std(char * , const wchar_t **,
-    size_t, size_t, mbstate_t * );
-
-#endif /* _MB_DEFS_H_ */
diff --git a/src/system/libroot/posix/locale/mb_none.c 
b/src/system/libroot/posix/locale/mb_none.c
deleted file mode 100755
index c74e1ad..0000000
--- a/src/system/libroot/posix/locale/mb_none.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-** Copyright 2009, Stefano Ceccherini, stefano.ceccherini@xxxxxxxxxx All 
rights reserved.
-** Distributed under the terms of the Haiku License.
-*/
-
-/*-
- * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
- * Copyright (c) 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Paul Borman at Krystal Technologies.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)none.c     8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-/*__FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.14.2.1.4.1 2008/11/25 
02:59:29 kensmith Exp $"); */
-
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wchar.h>
-
-#include "mb_defs.h"
-
-static size_t  _none_mbrtowc(wchar_t * , const char * ,
-                   size_t, mbstate_t * );
-static int     _none_mbsinit(const mbstate_t *);
-static size_t  _none_mbsnrtowcs(wchar_t * dst,
-                   const char ** src, size_t nms, size_t len,
-                   mbstate_t * ps);
-static size_t  _none_wcrtomb(char * , wchar_t,
-                   mbstate_t * );
-static size_t  _none_wcsnrtombs(char * , const wchar_t ** ,
-                   size_t, size_t, mbstate_t * );
-
-/* setup defaults */
-
-int __mb_cur_max = 1;
-int __mb_sb_limit = 256; 
-
-int
-_none_init()
-{
-
-       __mbrtowc = _none_mbrtowc;
-       __mbsinit = _none_mbsinit;
-       __mbsnrtowcs = _none_mbsnrtowcs;
-       __wcrtomb = _none_wcrtomb;
-       __wcsnrtombs = _none_wcsnrtombs;
-       __mb_cur_max = 1;
-       __mb_sb_limit = 256;
-       return(0);
-}
-
-
-static int
-_none_mbsinit(const mbstate_t *ps)
-{
-
-       /*
-        * Encoding is not state dependent - we are always in the
-        * initial state.
-        */
-       return (1);
-}
-
-
-static size_t
-_none_mbrtowc(wchar_t * pwc, const char * s, size_t n,
-    mbstate_t * ps)
-{
-
-       if (s == NULL)
-               /* Reset to initial shift state (no-op) */
-               return (0);
-       if (n == 0)
-               /* Incomplete multibyte sequence */
-               return ((size_t)-2);
-       if (pwc != NULL)
-               *pwc = (unsigned char)*s;
-       return (*s == '\0' ? 0 : 1);
-}
-
-
-static size_t
-_none_wcrtomb(char * s, wchar_t wc,
-    mbstate_t * ps)
-{
-
-       if (s == NULL)
-               /* Reset to initial shift state (no-op) */
-               return (1);
-       if (wc < 0 || wc > UCHAR_MAX) {
-               errno = EILSEQ;
-               return ((size_t)-1);
-       }
-       *s = (unsigned char)wc;
-       return (1);
-}
-
-
-static size_t
-_none_mbsnrtowcs(wchar_t * dst, const char ** src,
-    size_t nms, size_t len, mbstate_t * ps)
-{
-       const char *s;
-       size_t nchr;
-
-       if (dst == NULL) {
-               s = memchr(*src, '\0', nms);
-               return (s != NULL ? s - *src : nms);
-       }
-
-       s = *src;
-       nchr = 0;
-       while (len-- > 0 && nms-- > 0) {
-               if ((*dst++ = (unsigned char)*s++) == L'\0') {
-                       *src = NULL;
-                       return (nchr);
-               }
-               nchr++;
-       }
-       *src = s;
-       return (nchr);
-}
-
-
-static size_t
-_none_wcsnrtombs(char * dst, const wchar_t ** src,
-    size_t nwc, size_t len, mbstate_t * ps)
-{
-       const wchar_t *s;
-       size_t nchr;
-
-       if (dst == NULL) {
-               for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) {
-                       if (*s < 0 || *s > UCHAR_MAX) {
-                               errno = EILSEQ;
-                               return ((size_t)-1);
-                       }
-               }
-               return (s - *src);
-       }
-
-       s = *src;
-       nchr = 0;
-       while (len-- > 0 && nwc-- > 0) {
-               if (*s < 0 || *s > UCHAR_MAX) {
-                       errno = EILSEQ;
-                       return ((size_t)-1);
-               }
-               if ((*dst++ = *s++) == '\0') {
-                       *src = NULL;
-                       return (nchr);
-               }
-               nchr++;
-       }
-       *src = s;
-       return (nchr);
-}
-
-
-/* setup defaults */
-
-size_t (*__mbrtowc)(wchar_t * , const char * , size_t,
-    mbstate_t * ) = _none_mbrtowc;
-int (*__mbsinit)(const mbstate_t *) = _none_mbsinit;
-size_t (*__mbsnrtowcs)(wchar_t * , const char ** ,
-    size_t, size_t, mbstate_t * ) = _none_mbsnrtowcs;
-size_t (*__wcrtomb)(char * , wchar_t, mbstate_t * ) =
-    _none_wcrtomb;
-size_t (*__wcsnrtombs)(char * , const wchar_t ** ,
-    size_t, size_t, mbstate_t * ) = _none_wcsnrtombs;
-
diff --git a/src/system/libroot/posix/locale/mblen.c 
b/src/system/libroot/posix/locale/mblen.c
deleted file mode 100755
index 044c95b..0000000
--- a/src/system/libroot/posix/locale/mblen.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*-
- * Copyright (c) 2002-2004 Tim J. Robbins.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-/*__FBSDID("$FreeBSD: src/lib/libc/locale/mblen.c,v 1.9.26.1 2008/11/25 
02:59:29 kensmith Exp $"); */
-
-#include <stdlib.h>
-#include <wchar.h>
-#include "mb_defs.h"
-
-int
-mblen(const char *s, size_t n)
-{
-       static const mbstate_t initial;
-       static mbstate_t mbs;
-       size_t rval;
-
-       if (s == NULL) {
-               /* No support for state dependent encodings. */
-               mbs = initial;
-               return (0);
-       }
-       rval = __mbrtowc(NULL, s, n, &mbs);
-       if (rval == (size_t)-1 || rval == (size_t)-2)
-               return (-1);
-       return ((int)rval);
-}
diff --git a/src/system/libroot/posix/locale/mbrlen.c 
b/src/system/libroot/posix/locale/mbrlen.c
deleted file mode 100755
index 9a0fff4..0000000
--- a/src/system/libroot/posix/locale/mbrlen.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*-
- * Copyright (c) 2002-2004 Tim J. Robbins.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-/*__FBSDID("$FreeBSD: src/lib/libc/locale/mbrlen.c,v 1.4.26.1 2008/11/25 
02:59:29 kensmith Exp $"); */
-
-#include <wchar.h>
-#include "mb_defs.h"
-
-size_t
-mbrlen(const char *s, size_t n, mbstate_t *ps)
-{
-       static mbstate_t mbs;
-
-       if (ps == NULL)
-               ps = &mbs;
-       return (__mbrtowc(NULL, s, n, ps));
-}
diff --git a/src/system/libroot/posix/locale/mbrtowc.c 
b/src/system/libroot/posix/locale/mbrtowc.c
deleted file mode 100755
index c3b569c..0000000
--- a/src/system/libroot/posix/locale/mbrtowc.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * Copyright (c) 2002-2004 Tim J. Robbins.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-/*__FBSDID("$FreeBSD: src/lib/libc/locale/mbrtowc.c,v 1.7.26.1 2008/11/25 
02:59:29 kensmith Exp $"); */
-
-#include <wchar.h>
-#include "mb_defs.h"
-
-size_t
-mbrtowc(wchar_t *pwc, const char *s,
-    size_t n, mbstate_t *ps)
-{
-       static mbstate_t mbs;
-
-       if (ps == NULL)
-               ps = &mbs;
-       return (__mbrtowc(pwc, s, n, ps));
-}
diff --git a/src/system/libroot/posix/locale/mbsinit.c 
b/src/system/libroot/posix/locale/mbsinit.c
deleted file mode 100755
index 4a50583..0000000
--- a/src/system/libroot/posix/locale/mbsinit.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*-
- * Copyright (c) 2002-2004 Tim J. Robbins.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-/*__FBSDID("$FreeBSD: src/lib/libc/locale/mbsinit.c,v 1.3.26.1 2008/11/25 
02:59:29 kensmith Exp $"); */
-
-#include <wchar.h>
-#include "mb_defs.h"
-
-int
-mbsinit(const mbstate_t *ps)
-{
-
-       return (__mbsinit(ps));
-}
diff --git a/src/system/libroot/posix/locale/wcrtomb.c 
b/src/system/libroot/posix/locale/wcrtomb.c
deleted file mode 100755
index d1318d4..0000000
--- a/src/system/libroot/posix/locale/wcrtomb.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*-
- * Copyright (c) 2002-2004 Tim J. Robbins.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-/*__FBSDID("$FreeBSD: src/lib/libc/locale/wcrtomb.c,v 1.8.26.1 2008/11/25 
02:59:29 kensmith Exp $"); */
-
-#include <wchar.h>
-#include "mb_defs.h"
-
-size_t
-wcrtomb(char *s, wchar_t wc, mbstate_t *ps)
-{
-       static mbstate_t mbs;
-
-       if (ps == NULL)
-               ps = &mbs;
-       return (__wcrtomb(s, wc, ps));
-}

############################################################################

Commit:      bb79d18614fa7df3ac83c850e334b00b90d68bbc
URL:         http://cgit.haiku-os.org/haiku/commit/?id=bb79d18
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 17:56:41 2011 UTC

Drop no longer needed multibyte stuff from glibc.

----------------------------------------------------------------------------

diff --git a/src/system/libroot/posix/glibc/locale/mb_cur_max.c 
b/src/system/libroot/posix/glibc/locale/mb_cur_max.c
deleted file mode 100644
index e94ac49..0000000
--- a/src/system/libroot/posix/glibc/locale/mb_cur_max.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Return number of characters in multibyte representation for current
-   character set.
-   Copyright (C) 1996, 1999 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 1996.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <langinfo.h>
-#include <locale.h>
-#include <stdlib.h>
-#include "localeinfo.h"
-
-
-size_t
-weak_function
-__ctype_get_mb_cur_max (void)
-{
-  return _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX);
-}
diff --git a/src/system/libroot/posix/glibc/stdlib/mblen.c 
b/src/system/libroot/posix/glibc/stdlib/mblen.c
deleted file mode 100644
index 782bf51..0000000
--- a/src/system/libroot/posix/glibc/stdlib/mblen.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (C) 1991, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.

[ *** diff truncated: 800 lines dropped *** ]


############################################################################

Commit:      c51014771dbf90a3ab3709566a95d8ce5361ecb4
URL:         http://cgit.haiku-os.org/haiku/commit/?id=c510147
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 18:00:22 2011 UTC

Adjust required legacy gcc version.

----------------------------------------------------------------------------

############################################################################

Commit:      25389523bd7acfae83eb03d912f1f7f71fc387ea
URL:         http://cgit.haiku-os.org/haiku/commit/?id=2538952
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 21:28:09 2011 UTC
Committer: zooey <zooey@xxxxxxxxxxxxxxx>
Commit-Date: Tue Nov 22 21:28:09 2011 UTC

Touch c-gperf.h before building legacy gcc.

----------------------------------------------------------------------------

############################################################################

Commit:      9161a59746534c87e546b2bcade7ba1d484df3a9
URL:         http://cgit.haiku-os.org/haiku/commit/?id=9161a59
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Tue Nov 22 22:27:17 2011 UTC
Committer: zooey <zooey@xxxxxxxxxxxxxxx>
Commit-Date: Tue Nov 22 22:27:17 2011 UTC

Fix build of libroot-addon-icu with gcc4.

----------------------------------------------------------------------------

############################################################################

Commit:      cdb7744bc7a3bb2faf289a96cde1cfef59b4bc7e
URL:         http://cgit.haiku-os.org/haiku/commit/?id=cdb7744
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Wed Nov 23 16:02:23 2011 UTC

Avoid warning about missing math.h.

* Apparently caused by the fact that we no longer run fixincludes,
  math.h is not being generated anymore. I haven't removed the rm
  from the script in order to be compatible with older compilers.

----------------------------------------------------------------------------

############################################################################

Commit:      5c112a16ff77c414eee9014a85ab83e4bc9f57de
URL:         http://cgit.haiku-os.org/haiku/commit/?id=5c112a1
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Wed Nov 23 18:31:13 2011 UTC

Reset mbstate to initial in wcrtomb() with 0 wchar.

----------------------------------------------------------------------------

############################################################################

Commit:      53c09cffcbce38358c811d57b55d662bc99bfcfe
URL:         http://cgit.haiku-os.org/haiku/commit/?id=53c09cf
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Wed Nov 23 18:32:17 2011 UTC

Actually store & use our assigned TLS-key (OOPS!)

----------------------------------------------------------------------------

############################################################################

Revision:    hrev43310
Commit:      c894d1868ef1d23e5536bfdbd8608402cef14607
URL:         http://cgit.haiku-os.org/haiku/commit/?id=c894d18
Author:      Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
Date:        Wed Nov 23 18:55:34 2011 UTC

Ticket:      https://dev.haiku-os.org/ticket/6263
Ticket:      https://dev.haiku-os.org/ticket/7700

Bring rewritten multibyte-support into repository.

* update copyrights of locale backend files

Multibyte-support has been rewritten to use ICU as backend.
While this does not necessarily work properly in every aspect
(e.g. the shell still has [different] problems with multibyte-
characters now), it does fix #6263 and #7700.

----------------------------------------------------------------------------


Other related posts: