Bug 879792 - Import the STLport source. r=ted
authorMike Hommey <mh+mozilla@glandium.org>
Mon, 15 Jul 2013 18:48:39 +0900
changeset 138459 75ec39054b8a69b05128d2261a3b5a255eb485d4
parent 138458 874daff1487164794f9fa918b14a6b4153540622
child 138460 926141b660e5db51975f2f46e2dfc27e9b6eb228
push id30988
push usermh@glandium.org
push dateMon, 15 Jul 2013 09:51:22 +0000
treeherdermozilla-inbound@5c3ae19d8f6b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs879792
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 879792 - Import the STLport source. r=ted
build/stlport/Android.mk
build/stlport/LICENSE
build/stlport/MODULE_LICENSE_BSD_LIKE
build/stlport/README
build/stlport/README.android
build/stlport/README.mozilla
build/stlport/README.original
build/stlport/src/_stdio_file.h
build/stlport/src/acquire_release.h
build/stlport/src/aligned_buffer.h
build/stlport/src/allocators.cpp
build/stlport/src/bitset.cpp
build/stlport/src/c_locale.c
build/stlport/src/c_locale.h
build/stlport/src/c_locale_dummy/c_locale_dummy.c
build/stlport/src/c_locale_glibc/c_locale_glibc2.c
build/stlport/src/c_locale_win32/c_locale_win32.c
build/stlport/src/c_locale_win32/c_wlocale_win32.c
build/stlport/src/codecvt.cpp
build/stlport/src/collate.cpp
build/stlport/src/complex.cpp
build/stlport/src/complex_io.cpp
build/stlport/src/complex_trig.cpp
build/stlport/src/ctype.cpp
build/stlport/src/cxa.c
build/stlport/src/details/fstream_stdio.cpp
build/stlport/src/details/fstream_unistd.cpp
build/stlport/src/details/fstream_win32io.cpp
build/stlport/src/dll_main.cpp
build/stlport/src/facets_byname.cpp
build/stlport/src/fstream.cpp
build/stlport/src/ios.cpp
build/stlport/src/iostream.cpp
build/stlport/src/istream.cpp
build/stlport/src/locale.cpp
build/stlport/src/locale_catalog.cpp
build/stlport/src/locale_impl.cpp
build/stlport/src/locale_impl.h
build/stlport/src/lock_free_slist.h
build/stlport/src/message_facets.h
build/stlport/src/messages.cpp
build/stlport/src/monetary.cpp
build/stlport/src/num_get.cpp
build/stlport/src/num_get_float.cpp
build/stlport/src/num_put.cpp
build/stlport/src/num_put_float.cpp
build/stlport/src/numpunct.cpp
build/stlport/src/ostream.cpp
build/stlport/src/sparc_atomic.s
build/stlport/src/sparc_atomic64.s
build/stlport/src/sstream.cpp
build/stlport/src/stdio_streambuf.cpp
build/stlport/src/stdio_streambuf.h
build/stlport/src/stlport.rc
build/stlport/src/stlport_prefix.h
build/stlport/src/string.cpp
build/stlport/src/strstream.cpp
build/stlport/src/time_facets.cpp
build/stlport/src/warning_disable.h
build/stlport/stlport/algorithm
build/stlport/stlport/assert.h
build/stlport/stlport/bitset
build/stlport/stlport/cassert
build/stlport/stlport/cctype
build/stlport/stlport/cerrno
build/stlport/stlport/cfloat
build/stlport/stlport/ciso646
build/stlport/stlport/climits
build/stlport/stlport/clocale
build/stlport/stlport/cmath
build/stlport/stlport/complex
build/stlport/stlport/csetjmp
build/stlport/stlport/csignal
build/stlport/stlport/cstdarg
build/stlport/stlport/cstddef
build/stlport/stlport/cstdio
build/stlport/stlport/cstdlib
build/stlport/stlport/cstring
build/stlport/stlport/ctime
build/stlport/stlport/ctype.h
build/stlport/stlport/cwchar
build/stlport/stlport/cwctype
build/stlport/stlport/deque
build/stlport/stlport/errno.h
build/stlport/stlport/exception
build/stlport/stlport/exception.h
build/stlport/stlport/float.h
build/stlport/stlport/fstream
build/stlport/stlport/fstream.h
build/stlport/stlport/functional
build/stlport/stlport/hash_map
build/stlport/stlport/hash_set
build/stlport/stlport/iomanip
build/stlport/stlport/iomanip.h
build/stlport/stlport/ios
build/stlport/stlport/ios.h
build/stlport/stlport/iosfwd
build/stlport/stlport/iostream
build/stlport/stlport/iostream.h
build/stlport/stlport/iso646.h
build/stlport/stlport/istream
build/stlport/stlport/istream.h
build/stlport/stlport/iterator
build/stlport/stlport/limits
build/stlport/stlport/limits.h
build/stlport/stlport/list
build/stlport/stlport/locale
build/stlport/stlport/locale.h
build/stlport/stlport/map
build/stlport/stlport/math.h
build/stlport/stlport/mem.h
build/stlport/stlport/memory
build/stlport/stlport/new
build/stlport/stlport/new.h
build/stlport/stlport/numeric
build/stlport/stlport/ostream
build/stlport/stlport/ostream.h
build/stlport/stlport/pthread.h
build/stlport/stlport/pthread_alloc
build/stlport/stlport/queue
build/stlport/stlport/rlocks.h
build/stlport/stlport/rope
build/stlport/stlport/set
build/stlport/stlport/setjmp.h
build/stlport/stlport/signal.h
build/stlport/stlport/slist
build/stlport/stlport/sstream
build/stlport/stlport/stack
build/stlport/stlport/stdarg.h
build/stlport/stlport/stddef.h
build/stlport/stlport/stdexcept
build/stlport/stlport/stdio.h
build/stlport/stlport/stdiostream.h
build/stlport/stlport/stdlib.h
build/stlport/stlport/stl/_abbrevs.h
build/stlport/stlport/stl/_algo.c
build/stlport/stlport/stl/_algo.h
build/stlport/stlport/stl/_algobase.c
build/stlport/stlport/stl/_algobase.h
build/stlport/stlport/stl/_alloc.c
build/stlport/stlport/stl/_alloc.h
build/stlport/stlport/stl/_auto_ptr.h
build/stlport/stlport/stl/_bitset.c
build/stlport/stlport/stl/_bitset.h
build/stlport/stlport/stl/_bvector.h
build/stlport/stlport/stl/_carray.h
build/stlport/stlport/stl/_cctype.h
build/stlport/stlport/stl/_clocale.h
build/stlport/stlport/stl/_cmath.h
build/stlport/stlport/stl/_codecvt.h
build/stlport/stlport/stl/_collate.h
build/stlport/stlport/stl/_complex.c
build/stlport/stlport/stl/_complex.h
build/stlport/stlport/stl/_config_compat_post.h
build/stlport/stlport/stl/_construct.h
build/stlport/stlport/stl/_cprolog.h
build/stlport/stlport/stl/_csetjmp.h
build/stlport/stlport/stl/_csignal.h
build/stlport/stlport/stl/_cstdarg.h
build/stlport/stlport/stl/_cstddef.h
build/stlport/stlport/stl/_cstdio.h
build/stlport/stlport/stl/_cstdlib.h
build/stlport/stlport/stl/_cstring.h
build/stlport/stlport/stl/_ctime.h
build/stlport/stlport/stl/_ctraits_fns.h
build/stlport/stlport/stl/_ctype.h
build/stlport/stlport/stl/_cwchar.h
build/stlport/stlport/stl/_cwctype.h
build/stlport/stlport/stl/_deque.c
build/stlport/stlport/stl/_deque.h
build/stlport/stlport/stl/_epilog.h
build/stlport/stlport/stl/_exception.h
build/stlport/stlport/stl/_facets_fwd.h
build/stlport/stlport/stl/_fstream.c
build/stlport/stlport/stl/_fstream.h
build/stlport/stlport/stl/_function.h
build/stlport/stlport/stl/_function_adaptors.h
build/stlport/stlport/stl/_function_base.h
build/stlport/stlport/stl/_hash_fun.h
build/stlport/stlport/stl/_hash_map.h
build/stlport/stlport/stl/_hash_set.h
build/stlport/stlport/stl/_hashtable.c
build/stlport/stlport/stl/_hashtable.h
build/stlport/stlport/stl/_heap.c
build/stlport/stlport/stl/_heap.h
build/stlport/stlport/stl/_iomanip.h
build/stlport/stlport/stl/_ios.c
build/stlport/stlport/stl/_ios.h
build/stlport/stlport/stl/_ios_base.h
build/stlport/stlport/stl/_ioserr.h
build/stlport/stlport/stl/_iosfwd.h
build/stlport/stlport/stl/_iostream_string.h
build/stlport/stlport/stl/_istream.c
build/stlport/stlport/stl/_istream.h
build/stlport/stlport/stl/_istreambuf_iterator.h
build/stlport/stlport/stl/_iterator.h
build/stlport/stlport/stl/_iterator_base.h
build/stlport/stlport/stl/_iterator_old.h
build/stlport/stlport/stl/_limits.c
build/stlport/stlport/stl/_limits.h
build/stlport/stlport/stl/_list.c
build/stlport/stlport/stl/_list.h
build/stlport/stlport/stl/_locale.h
build/stlport/stlport/stl/_map.h
build/stlport/stlport/stl/_mbstate_t.h
build/stlport/stlport/stl/_messages_facets.h
build/stlport/stlport/stl/_monetary.c
build/stlport/stlport/stl/_monetary.h
build/stlport/stlport/stl/_move_construct_fwk.h
build/stlport/stlport/stl/_new.h
build/stlport/stlport/stl/_num_get.c
build/stlport/stlport/stl/_num_get.h
build/stlport/stlport/stl/_num_put.c
build/stlport/stlport/stl/_num_put.h
build/stlport/stlport/stl/_numeric.c
build/stlport/stlport/stl/_numeric.h
build/stlport/stlport/stl/_numpunct.h
build/stlport/stlport/stl/_ostream.c
build/stlport/stlport/stl/_ostream.h
build/stlport/stlport/stl/_ostreambuf_iterator.h
build/stlport/stlport/stl/_pair.h
build/stlport/stlport/stl/_prolog.h
build/stlport/stlport/stl/_pthread_alloc.h
build/stlport/stlport/stl/_ptrs_specialize.h
build/stlport/stlport/stl/_queue.h
build/stlport/stlport/stl/_range_errors.c
build/stlport/stlport/stl/_range_errors.h
build/stlport/stlport/stl/_raw_storage_iter.h
build/stlport/stlport/stl/_relops_cont.h
build/stlport/stlport/stl/_relops_hash_cont.h
build/stlport/stlport/stl/_rope.c
build/stlport/stlport/stl/_rope.h
build/stlport/stlport/stl/_set.h
build/stlport/stlport/stl/_slist.c
build/stlport/stlport/stl/_slist.h
build/stlport/stlport/stl/_slist_base.c
build/stlport/stlport/stl/_slist_base.h
build/stlport/stlport/stl/_sparc_atomic.h
build/stlport/stlport/stl/_sstream.c
build/stlport/stlport/stl/_sstream.h
build/stlport/stlport/stl/_stack.h
build/stlport/stlport/stl/_stdexcept.h
build/stlport/stlport/stl/_stdexcept_base.c
build/stlport/stlport/stl/_stdexcept_base.h
build/stlport/stlport/stl/_stlport_version.h
build/stlport/stlport/stl/_stream_iterator.h
build/stlport/stlport/stl/_streambuf.c
build/stlport/stlport/stl/_streambuf.h
build/stlport/stlport/stl/_string.c
build/stlport/stlport/stl/_string.h
build/stlport/stlport/stl/_string_base.h
build/stlport/stlport/stl/_string_fwd.h
build/stlport/stlport/stl/_string_hash.h
build/stlport/stlport/stl/_string_io.c
build/stlport/stlport/stl/_string_io.h
build/stlport/stlport/stl/_string_npos.h
build/stlport/stlport/stl/_string_operators.h
build/stlport/stlport/stl/_string_sum.h
build/stlport/stlport/stl/_string_sum_methods.h
build/stlport/stlport/stl/_string_workaround.h
build/stlport/stlport/stl/_strstream.h
build/stlport/stlport/stl/_tempbuf.c
build/stlport/stlport/stl/_tempbuf.h
build/stlport/stlport/stl/_threads.c
build/stlport/stlport/stl/_threads.h
build/stlport/stlport/stl/_time_facets.c
build/stlport/stlport/stl/_time_facets.h
build/stlport/stlport/stl/_tree.c
build/stlport/stlport/stl/_tree.h
build/stlport/stlport/stl/_typeinfo.h
build/stlport/stlport/stl/_uninitialized.h
build/stlport/stlport/stl/_unordered_map.h
build/stlport/stlport/stl/_unordered_set.h
build/stlport/stlport/stl/_valarray.c
build/stlport/stlport/stl/_valarray.h
build/stlport/stlport/stl/_vector.c
build/stlport/stlport/stl/_vector.h
build/stlport/stlport/stl/boost_type_traits.h
build/stlport/stlport/stl/c_locale.h
build/stlport/stlport/stl/char_traits.h
build/stlport/stlport/stl/concept_checks.h
build/stlport/stlport/stl/config/_aix.h
build/stlport/stlport/stl/config/_android.h
build/stlport/stlport/stl/config/_apcc.h
build/stlport/stlport/stl/config/_apple.h
build/stlport/stlport/stl/config/_as400.h
build/stlport/stlport/stl/config/_auto_link.h
build/stlport/stlport/stl/config/_bc.h
build/stlport/stlport/stl/config/_como.h
build/stlport/stlport/stl/config/_cray.h
build/stlport/stlport/stl/config/_cygwin.h
build/stlport/stlport/stl/config/_dec.h
build/stlport/stlport/stl/config/_dec_vms.h
build/stlport/stlport/stl/config/_detect_dll_or_lib.h
build/stlport/stlport/stl/config/_dm.h
build/stlport/stlport/stl/config/_epilog.h
build/stlport/stlport/stl/config/_evc.h
build/stlport/stlport/stl/config/_feedback.h
build/stlport/stlport/stl/config/_freebsd.h
build/stlport/stlport/stl/config/_fujitsu.h
build/stlport/stlport/stl/config/_gcc.h
build/stlport/stlport/stl/config/_hpacc.h
build/stlport/stlport/stl/config/_hpux.h
build/stlport/stlport/stl/config/_ibm.h
build/stlport/stlport/stl/config/_icc.h
build/stlport/stlport/stl/config/_intel.h
build/stlport/stlport/stl/config/_kai.h
build/stlport/stlport/stl/config/_linux.h
build/stlport/stlport/stl/config/_mac.h
build/stlport/stlport/stl/config/_macosx.h
build/stlport/stlport/stl/config/_mlc.h
build/stlport/stlport/stl/config/_msvc.h
build/stlport/stlport/stl/config/_mwerks.h
build/stlport/stlport/stl/config/_native_headers.h
build/stlport/stlport/stl/config/_openbsd.h
build/stlport/stlport/stl/config/_prolog.h
build/stlport/stlport/stl/config/_sgi.h
build/stlport/stlport/stl/config/_solaris.h
build/stlport/stlport/stl/config/_sunprocc.h
build/stlport/stlport/stl/config/_system.h
build/stlport/stlport/stl/config/_warnings_off.h
build/stlport/stlport/stl/config/_watcom.h
build/stlport/stlport/stl/config/_windows.h
build/stlport/stlport/stl/config/compat.h
build/stlport/stlport/stl/config/features.h
build/stlport/stlport/stl/config/host.h
build/stlport/stlport/stl/config/stl_confix.h
build/stlport/stlport/stl/config/stl_mycomp.h
build/stlport/stlport/stl/config/user_config.h
build/stlport/stlport/stl/debug/_debug.c
build/stlport/stlport/stl/debug/_debug.h
build/stlport/stlport/stl/debug/_deque.h
build/stlport/stlport/stl/debug/_hashtable.h
build/stlport/stlport/stl/debug/_iterator.h
build/stlport/stlport/stl/debug/_list.h
build/stlport/stlport/stl/debug/_slist.h
build/stlport/stlport/stl/debug/_string.h
build/stlport/stlport/stl/debug/_string_sum_methods.h
build/stlport/stlport/stl/debug/_tree.h
build/stlport/stlport/stl/debug/_vector.h
build/stlport/stlport/stl/msl_string.h
build/stlport/stlport/stl/pointers/_deque.h
build/stlport/stlport/stl/pointers/_list.h
build/stlport/stlport/stl/pointers/_set.h
build/stlport/stlport/stl/pointers/_slist.h
build/stlport/stlport/stl/pointers/_tools.h
build/stlport/stlport/stl/pointers/_vector.h
build/stlport/stlport/stl/type_manips.h
build/stlport/stlport/stl/type_traits.h
build/stlport/stlport/streambuf
build/stlport/stlport/streambuf.h
build/stlport/stlport/string
build/stlport/stlport/string.h
build/stlport/stlport/strstream
build/stlport/stlport/strstream.h
build/stlport/stlport/time.h
build/stlport/stlport/type_traits
build/stlport/stlport/typeinfo
build/stlport/stlport/typeinfo.h
build/stlport/stlport/unordered_map
build/stlport/stlport/unordered_set
build/stlport/stlport/using/cstring
build/stlport/stlport/using/export
build/stlport/stlport/using/fstream
build/stlport/stlport/using/h/fstream.h
build/stlport/stlport/using/h/iomanip.h
build/stlport/stlport/using/h/iostream.h
build/stlport/stlport/using/h/ostream.h
build/stlport/stlport/using/h/streambuf.h
build/stlport/stlport/using/h/strstream.h
build/stlport/stlport/using/iomanip
build/stlport/stlport/using/ios
build/stlport/stlport/using/iosfwd
build/stlport/stlport/using/iostream
build/stlport/stlport/using/istream
build/stlport/stlport/using/locale
build/stlport/stlport/using/ostream
build/stlport/stlport/using/sstream
build/stlport/stlport/using/streambuf
build/stlport/stlport/using/strstream
build/stlport/stlport/utility
build/stlport/stlport/valarray
build/stlport/stlport/vector
build/stlport/stlport/wchar.h
build/stlport/stlport/wctype.h
build/stlport/test/.gitignore
new file mode 100644
--- /dev/null
+++ b/build/stlport/Android.mk
@@ -0,0 +1,115 @@
+LOCAL_PATH := $(call my-dir)
+
+# Normally, we distribute the NDK with prebuilt binaries of STLport
+# in $LOCAL_PATH/<abi>/. However,
+#
+
+STLPORT_FORCE_REBUILD := $(strip $(STLPORT_FORCE_REBUILD))
+ifndef STLPORT_FORCE_REBUILD
+  ifeq (,$(strip $(wildcard $(LOCAL_PATH)/libs/$(TARGET_ARCH_ABI)/libstlport_static.a)))
+    $(call __ndk_info,WARNING: Rebuilding STLport libraries from sources!)
+    $(call __ndk_info,You might want to use $$NDK/build/tools/build-stlport.sh)
+    $(call __ndk_info,in order to build prebuilt versions to speed up your builds!)
+    STLPORT_FORCE_REBUILD := true
+  endif
+endif
+
+libstlport_path := $(LOCAL_PATH)
+
+libstlport_src_files := \
+        src/dll_main.cpp \
+        src/fstream.cpp \
+        src/strstream.cpp \
+        src/sstream.cpp \
+        src/ios.cpp \
+        src/stdio_streambuf.cpp \
+        src/istream.cpp \
+        src/ostream.cpp \
+        src/iostream.cpp \
+        src/codecvt.cpp \
+        src/collate.cpp \
+        src/ctype.cpp \
+        src/monetary.cpp \
+        src/num_get.cpp \
+        src/num_put.cpp \
+        src/num_get_float.cpp \
+        src/num_put_float.cpp \
+        src/numpunct.cpp \
+        src/time_facets.cpp \
+        src/messages.cpp \
+        src/locale.cpp \
+        src/locale_impl.cpp \
+        src/locale_catalog.cpp \
+        src/facets_byname.cpp \
+        src/complex.cpp \
+        src/complex_io.cpp \
+        src/complex_trig.cpp \
+        src/string.cpp \
+        src/bitset.cpp \
+        src/allocators.cpp \
+        src/c_locale.c \
+        src/cxa.c \
+
+libstlport_cflags := -D_GNU_SOURCE
+libstlport_cppflags := -fuse-cxa-atexit
+libstlport_c_includes := $(libstlport_path)/stlport
+
+#It is much more practical to include the sources of GAbi++ in our builds
+# of STLport. This is similar to what the GNU libstdc++ does (it includes
+# its own copy of libsupc++)
+#
+# This simplifies usage, since you only have to list a single library
+# as a dependency, instead of two, especially when using the standalone
+# toolchain.
+#
+include $(dir $(LOCAL_PATH))/gabi++/sources.mk
+
+libstlport_c_includes += $(libgabi++_c_includes)
+
+ifneq ($(STLPORT_FORCE_REBUILD),true)
+
+$(call ndk_log,Using prebuilt STLport libraries)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := stlport_static
+LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).a
+LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_CPP_FEATURES := rtti
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := stlport_shared
+LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).so
+LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_CPP_FEATURES := rtti
+include $(PREBUILT_SHARED_LIBRARY)
+
+else # STLPORT_FORCE_REBUILD == true
+
+$(call ndk_log,Rebuilding STLport libraries from sources)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := stlport_static
+LOCAL_CPP_EXTENSION := .cpp .cc
+LOCAL_SRC_FILES := $(libstlport_src_files)
+LOCAL_SRC_FILES += $(libgabi++_src_files:%=../gabi++/%)
+LOCAL_CFLAGS := $(libstlport_cflags)
+LOCAL_CPPFLAGS := $(libstlport_cppflags)
+LOCAL_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_CPP_FEATURES := rtti exceptions
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := stlport_shared
+LOCAL_CPP_EXTENSION := .cpp .cc
+LOCAL_SRC_FILES := $(libstlport_src_files)
+LOCAL_SRC_FILES += $(libgabi++_src_files:%=../gabi++/%)
+LOCAL_CFLAGS := $(libstlport_cflags)
+LOCAL_CPPFLAGS := $(libstlport_cppflags)
+LOCAL_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_CPP_FEATURES := rtti exceptions
+include $(BUILD_SHARED_LIBRARY)
+
+endif # STLPORT_FORCE_REBUILD == true
new file mode 100644
--- /dev/null
+++ b/build/stlport/LICENSE
@@ -0,0 +1,27 @@
+Boris Fomitchev grants Licensee a non-exclusive, non-transferable, royalty-free license to use STLport and its documentation without fee.
+
+By downloading, using, or copying STLport or any portion thereof,  Licensee agrees to abide by the intellectual property laws and all other applicable laws of the United States of America, and to all of the terms and conditions of this Agreement.
+
+Licensee shall maintain the following copyright and permission  notices on STLport sources and its documentation unchanged :
+
+Copyright 1999,2000 Boris Fomitchev
+
+This material is provided "as is", with absolutely no warranty expressed or implied. Any use is at your own risk.
+Permission to use or copy this software for any purpose is hereby granted without fee, provided the above notices are retained on all copies. Permission to modify the code and to distribute modified code is granted, provided the above notices are retained, and a notice that the code was modified is included with the above copyright notice.
+The Licensee may distribute binaries compiled with STLport (whether original or modified) without any royalties or restrictions.
+
+The Licensee may distribute original or modified STLport sources, provided that:
+
+The conditions indicated in the above permission notice are met;
+The following copyright notices are retained when present, and conditions provided in accompanying permission notices are met :
+Copyright 1994 Hewlett-Packard Company
+
+Copyright 1996,97 Silicon Graphics Computer Systems, Inc.
+
+Copyright 1997 Moscow Center for SPARC Technology.
+
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Hewlett-Packard Company makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.
+
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Silicon Graphics makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.
+
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Moscow Center for SPARC Technology  makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/build/stlport/README
@@ -0,0 +1,69 @@
+STLport for Android
+
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+
+     This feature is currently in beta. In case of issue
+     please contact the android-ndk support forum or
+     file bugs at http://b.android.com
+
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+
+This directory contains a port of STLport for Android, which provides
+a simple STL implementation. Note that it currently does not support
+C++ exceptions and RTTI. Support for wchar_t and locales is probably buggy.
+
+You can either use it as a static or shared library.
+
+1/ The static library is recommended if you will only produce
+   one shared library for your project. All necessary STLport functions
+   will be added to it. This option should also generate smaller
+   overall binaries.
+
+2/ The shared library, is recommended if you want to produce
+   several shared libraries in your project, because it avoids copying the
+   same STLport functions to each one of them, and having different instances
+   of the same global variables (which can easily conflict or result in
+   undefined behaviour).
+
+To use the *static* library, define APP_STL in your Application.mk as follows:
+
+    APP_STL := stlport_static
+
+To use the *shared* library, use "stlport_shared" instead:
+
+    APP_STL := stlport_shared
+
+Note that, in this case, you will need, in your application, to explicitely
+load the 'stlport_shared' library before any library that depends on it.
+For example:
+
+    static {
+        System.loadLibrary("stlport_shared");
+        System.loadLibrary("foo");
+        System.loadLibrary("bar");
+    }
+
+If both libfoo.so and libbar.so depend on STLport.
+
+You can build the STLport unit test program by doing the following:
+
+  cd $NDK
+  tests/run-tests.sh --test=test-stlport
+
+If you have an Android device connected to your machine, this will
+automatically try to run the generated test command. Note that for now
+a few tests are still failing (mostly related to wchar_t and locales).
+
+They should be fixed hopefully by a later release of this library.
+
+The NDK comes with prebuilt binaries for this library to speed up development.
+You can however rebuild them from sources in your own application build by
+defining STLPORT_FORCE_REBUILD to 'true' in your Application.mk as in:
+
+    STLPORT_FORCE_REBUILD := true
+
+
+VERSION INFORMATION: This module is based on STLport version 5.2.0
+
new file mode 100644
--- /dev/null
+++ b/build/stlport/README.android
@@ -0,0 +1,9 @@
+Version: 5.2.1
+
+Changes:
+    * Added _android.h included by _system.h
+    * Do not use linux float functions in num_get_float.cpp as Android does not
+      have them.
+    * _mbstate_t.h cannot define its own mbstate_t as bionic already defines
+      it.
+    * _pair.h needs to define bionic's (sgi's) internal pair header guard.
new file mode 100644
--- /dev/null
+++ b/build/stlport/README.mozilla
@@ -0,0 +1,3 @@
+This copy of STLport was taken from the Android NDK r8e.
+Android specific changes are listed in README.android.
+The libs/ directory containing prebuilt static libraries was removed.
new file mode 100644
--- /dev/null
+++ b/build/stlport/README.original
@@ -0,0 +1,64 @@
+**********************************************************************
+* 	README file for STLport 5.0                                    *
+*                                                                    *
+**********************************************************************
+
+This directory contains the STLport-5.0 release.
+
+What's inside :
+
+README           - this file
+INSTALL          - installation instructions
+
+bin              - installation directory for STLport unit tests;
+                   it may contain more subdirs, if you use
+                   crosscompilation
+build/lib        - build directory for STLport library (if you use
+                   STLport iostreams and/or locale only)
+build/test/unit  - build directory for regression (unit) tests
+build/test/eh    - build directory for exception handling tests
+stlport          - main STLport include directory
+src              - source for iostreams implementation and other parts
+                   that aren't pure template code
+lib              - installation directory for STLport library (if you
+                   use STLport iostreams and/or locale only);
+                   it may contain more subdirs, if you use
+                   crosscompilation
+test/unit        - unit (regression) tests
+test/eh          - exception handling test using STLport iostreams
+etc              - miscellanous files (ChangeLog, TODO, scripts, etc.) 
+
+GETTING STLPORT
+
+To download the latest version of STLport, please be sure to visit
+https://sourceforge.net/project/showfiles.php?group_id=146814
+
+LEGALESE
+
+This software is being distributed under the following terms:
+
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Copyright (c) 1996-1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1997
+ * Moscow Center for SPARC Technology
+ *
+ * Copyright (c) 1999-2003
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted 
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+
+**********************************************************************
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/_stdio_file.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#ifndef _STLP_STDIO_FILE_H
+#define _STLP_STDIO_FILE_H
+
+/* This file provides a low-level interface between the internal
+ * representation of struct FILE, from the C stdio library, and
+ * the C++ I/O library. */
+
+#ifndef _STLP_CSTDIO
+#  include <cstdio>
+#endif
+#ifndef _STLP_CSTDDEF
+#  include <cstddef>
+#endif
+
+#if defined (__MSL__)
+#  include <unix.h>  /* get the definition of fileno */
+#endif
+
+_STLP_BEGIN_NAMESPACE
+
+#if defined (_STLP_WCE)
+
+inline int _FILE_fd(const FILE *__f) {
+  /* Check if FILE is one of the three standard streams
+     We do this check first, because invoking _fileno() on one of them
+     causes a terminal window to be created. This also happens if you do
+     any IO on them, but merely retrieving the filedescriptor shouldn't
+     already do that.
+
+     Obviously this is pretty implementation-specific because it requires
+     that indeed the first three FDs are always the same, but that is not
+     only common but almost guaranteed. */
+  for (int __fd = 0; __fd != 3; ++__fd) {
+    if (__f == _getstdfilex(__fd))
+      return __fd;
+  }
+
+  /* Normal files. */
+  return (int)::_fileno((FILE*)__f); 
+}
+
+# elif defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
+
+inline int _FILE_fd(const FILE *__f) { return __f->__file; }
+
+# elif defined (__sun) && defined (_LP64)
+
+inline int _FILE_fd(const FILE *__f) { return (int) __f->__pad[2]; }
+
+#elif defined (__hpux) /* && defined(__hppa) && defined(__HP_aCC)) */ || \
+      defined (__MVS__) || \
+      defined (_STLP_USE_UCLIBC) /* should be before _STLP_USE_GLIBC */
+
+inline int _FILE_fd(const FILE *__f) { return fileno(__CONST_CAST(FILE*, __f)); }
+
+#elif defined (_STLP_USE_GLIBC)
+
+inline int _FILE_fd(const FILE *__f) { return __f->_fileno; }
+
+#elif defined (__BORLANDC__)
+
+inline int _FILE_fd(const FILE *__f) { return __f->fd; }
+
+#elif defined (__MWERKS__)
+
+/* using MWERKS-specific defines here to detect other OS targets
+ * dwa: I'm not sure they provide fileno for all OS's, but this should
+ * work for Win32 and WinCE
+
+ * Hmm, at least for Novell NetWare __dest_os == __mac_os true too..
+ * May be both __dest_os and __mac_os defined and empty?   - ptr */
+#  if __dest_os == __mac_os
+inline int _FILE_fd(const FILE *__f) { return ::fileno(__CONST_CAST(FILE*, __f)); }
+#  else
+inline int _FILE_fd(const FILE *__f) { return ::_fileno(__CONST_CAST(FILE*, __f)); }
+#  endif
+
+#elif defined (__QNXNTO__) || defined (__WATCOMC__) || defined (__EMX__)
+
+inline int _FILE_fd(const FILE *__f) { return __f->_handle; }
+
+#elif defined (__Lynx__)
+
+/* the prototypes are taken from LynxOS patch for STLport 4.0 */
+inline int _FILE_fd(const FILE *__f) { return __f->_fd; }
+
+#else  /* The most common access to file descriptor. */
+
+inline int _FILE_fd(const FILE *__f) { return __f->_file; }
+
+#endif
+
+_STLP_END_NAMESPACE
+
+#endif /* _STLP_STDIO_FILE_H */
+
+/* Local Variables:
+ * mode:C++
+ * End: */
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/acquire_release.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#ifndef ACQUIRE_RELEASE_H
+#define ACQUIRE_RELEASE_H
+
+#include "c_locale.h"
+
+_STLP_BEGIN_NAMESPACE
+_STLP_MOVE_TO_PRIV_NAMESPACE
+
+_Locale_ctype* _STLP_CALL __acquire_ctype(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_codecvt* _STLP_CALL __acquire_codecvt(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_numeric* _STLP_CALL __acquire_numeric(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_collate* _STLP_CALL __acquire_collate(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_monetary* _STLP_CALL __acquire_monetary(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_time* _STLP_CALL __acquire_time(const char* &name, char *buf, _Locale_name_hint*, int *__err_code);
+_Locale_messages* _STLP_CALL __acquire_messages(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+
+void _STLP_CALL __release_ctype(_Locale_ctype* cat);
+void _STLP_CALL __release_codecvt(_Locale_codecvt* cat);
+void _STLP_CALL __release_numeric(_Locale_numeric* cat);
+void _STLP_CALL __release_collate(_Locale_collate* cat);
+void _STLP_CALL __release_monetary(_Locale_monetary* cat);
+void _STLP_CALL __release_time(_Locale_time* __time);
+void _STLP_CALL __release_messages(_Locale_messages* cat);
+
+_STLP_MOVE_TO_STD_NAMESPACE
+_STLP_END_NAMESPACE
+
+#endif /* ACQUIRE_RELEASE_H */
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/aligned_buffer.h
@@ -0,0 +1,21 @@
+#ifndef ALIGNED_BUFFER_H
+#define ALIGNED_BUFFER_H
+
+_STLP_BEGIN_NAMESPACE
+// this is for fake initialization
+template<class T>
+union _Stl_aligned_buffer {
+  char buf[sizeof(T)];
+  struct { double a; double b; } padding;
+
+  T* operator&() {
+    return __REINTERPRET_CAST(T*, this);
+  }
+
+  T const* operator&() const {
+    return __REINTERPRET_CAST(T const*, this);
+  }
+};
+_STLP_END_NAMESPACE
+
+#endif
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/allocators.cpp
@@ -0,0 +1,1121 @@
+/*
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1997
+ * Moscow Center for SPARC Technology
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include "stlport_prefix.h"
+
+#include <memory>
+
+#if defined (__GNUC__) && (defined (__CYGWIN__) || defined (__MINGW32__))
+#  include <malloc.h>
+#endif
+
+#if defined (_STLP_PTHREADS) && !defined (_STLP_NO_THREADS)
+#  include <pthread_alloc>
+#  include <cerrno>
+#endif
+
+#include <stl/_threads.h>
+
+#include "lock_free_slist.h"
+
+#if defined (__WATCOMC__)
+#  pragma warning 13 9
+#  pragma warning 367 9
+#  pragma warning 368 9
+#endif
+
+#if defined (_STLP_SGI_THREADS)
+  // We test whether threads are in use before locking.
+  // Perhaps this should be moved into stl_threads.h, but that
+  // probably makes it harder to avoid the procedure call when
+  // it isn't needed.
+extern "C" {
+  extern int __us_rsthread_malloc;
+}
+#endif
+
+// Specialised debug form of new operator which does not provide "false"
+// memory leaks when run with debug CRT libraries.
+#if defined (_STLP_MSVC) && (_STLP_MSVC >= 1020 && defined (_STLP_DEBUG_ALLOC)) && !defined (_STLP_WCE)
+#  include <crtdbg.h>
+inline char* __stlp_new_chunk(size_t __bytes) {
+  void *__chunk = _STLP_CHECK_NULL_ALLOC(::operator new(__bytes, __FILE__, __LINE__));
+  return __STATIC_CAST(char*, __chunk);
+}
+inline void __stlp_delete_chunck(void* __p) { ::operator delete(__p, __FILE__, __LINE__); }
+#else
+#  ifdef _STLP_NODE_ALLOC_USE_MALLOC
+#    include <cstdlib>
+inline char* __stlp_new_chunk(size_t __bytes) {
+  // do not use _STLP_CHECK_NULL_ALLOC, this macro is dedicated to new operator.
+  void *__chunk = _STLP_VENDOR_CSTD::malloc(__bytes);
+  if (__chunk == 0) {
+    _STLP_THROW_BAD_ALLOC;
+  }
+  return __STATIC_CAST(char*, __chunk);
+}
+inline void __stlp_delete_chunck(void* __p) { _STLP_VENDOR_CSTD::free(__p); }
+#  else
+inline char* __stlp_new_chunk(size_t __bytes)
+{ return __STATIC_CAST(char*, _STLP_STD::__stl_new(__bytes)); }
+inline void __stlp_delete_chunck(void* __p) { _STLP_STD::__stl_delete(__p); }
+#  endif
+#endif
+
+/* This is an additional atomic operations to the ones already defined in
+ * stl/_threads.h, platform should try to support it to improve performance.
+ * __add_atomic_t _STLP_ATOMIC_ADD(volatile __add_atomic_t* __target, __add_atomic_t __val) :
+ * does *__target = *__target + __val and returns the old *__target value */
+typedef long __add_atomic_t;
+typedef unsigned long __uadd_atomic_t;
+
+#if defined (__GNUC__) && defined (__i386__)
+inline long _STLP_atomic_add_gcc_x86(long volatile* p, long addend) {
+  long result;
+  __asm__ __volatile__
+    ("lock; xaddl %1, %0;"
+    :"=m" (*p), "=r" (result)
+    :"m"  (*p), "1"  (addend)
+    :"cc");
+ return result + addend;
+}
+#  define _STLP_ATOMIC_ADD(__dst, __val)  _STLP_atomic_add_gcc_x86(__dst, __val)
+#elif defined (_STLP_WIN32THREADS)
+// The Win32 API function InterlockedExchangeAdd is not available on Windows 95.
+#  if !defined (_STLP_WIN95_LIKE)
+#    if defined (_STLP_NEW_PLATFORM_SDK)
+#      define _STLP_ATOMIC_ADD(__dst, __val) InterlockedExchangeAdd(__dst, __val)
+#    else
+#      define _STLP_ATOMIC_ADD(__dst, __val) InterlockedExchangeAdd(__CONST_CAST(__add_atomic_t*, __dst), __val)
+#    endif
+#  endif
+#endif
+
+#if defined (__OS400__)
+// dums 02/05/2007: is it really necessary ?
+enum { _ALIGN = 16, _ALIGN_SHIFT = 4 };
+#else
+enum { _ALIGN = 2 * sizeof(void*), _ALIGN_SHIFT = 2 + sizeof(void*) / 4 };
+#endif
+
+#define _S_FREELIST_INDEX(__bytes) ((__bytes - size_t(1)) >> (int)_ALIGN_SHIFT)
+
+_STLP_BEGIN_NAMESPACE
+
+// malloc_alloc out-of-memory handling
+static __oom_handler_type __oom_handler = __STATIC_CAST(__oom_handler_type, 0);
+
+#ifdef _STLP_THREADS
+_STLP_mutex __oom_handler_lock;
+#endif
+
+void* _STLP_CALL __malloc_alloc::allocate(size_t __n)
+{
+  void *__result = malloc(__n);
+  if ( 0 == __result ) {
+    __oom_handler_type __my_malloc_handler;
+
+    for (;;) {
+      {
+#ifdef _STLP_THREADS
+        _STLP_auto_lock _l( __oom_handler_lock );
+#endif
+        __my_malloc_handler = __oom_handler;
+      }
+      if ( 0 == __my_malloc_handler) {
+        _STLP_THROW_BAD_ALLOC;
+      }
+      (*__my_malloc_handler)();
+      __result = malloc(__n);
+      if ( __result )
+        return __result;
+    }
+  }
+  return __result;
+}
+
+__oom_handler_type _STLP_CALL __malloc_alloc::set_malloc_handler(__oom_handler_type __f)
+{
+#ifdef _STLP_THREADS
+  _STLP_auto_lock _l( __oom_handler_lock );
+#endif
+  __oom_handler_type __old = __oom_handler;
+  __oom_handler = __f;
+  return __old;
+}
+
+// *******************************************************
+// Default node allocator.
+// With a reasonable compiler, this should be roughly as fast as the
+// original STL class-specific allocators, but with less fragmentation.
+//
+// Important implementation properties:
+// 1. If the client request an object of size > _MAX_BYTES, the resulting
+//    object will be obtained directly from malloc.
+// 2. In all other cases, we allocate an object of size exactly
+//    _S_round_up(requested_size).  Thus the client has enough size
+//    information that we can return the object to the proper free list
+//    without permanently losing part of the object.
+//
+
+#define _STLP_NFREELISTS 16
+
+#if defined (_STLP_LEAKS_PEDANTIC) && defined (_STLP_USE_DYNAMIC_LIB)
+/*
+ * We can only do cleanup of the node allocator memory pool if we are
+ * sure that the STLport library is used as a shared one as it guaranties
+ * the unicity of the node allocator instance. Without that guaranty node
+ * allocator instances might exchange memory blocks making the implementation
+ * of a cleaning process much more complicated.
+ */
+#  define _STLP_DO_CLEAN_NODE_ALLOC
+#endif
+
+/* When STLport is used without multi threaded safety we use the node allocator
+ * implementation with locks as locks becomes no-op. The lock free implementation
+ * always use system specific atomic operations which are slower than 'normal'
+ * ones.
+ */
+#if defined (_STLP_THREADS) && \
+    defined (_STLP_HAS_ATOMIC_FREELIST) && defined (_STLP_ATOMIC_ADD)
+/*
+ * We have an implementation of the atomic freelist (_STLP_atomic_freelist)
+ * for this architecture and compiler.  That means we can use the non-blocking
+ * implementation of the node-allocation engine.*/
+#  define _STLP_USE_LOCK_FREE_IMPLEMENTATION
+#endif
+
+#if !defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+#  if defined (_STLP_THREADS)
+
+class _Node_Alloc_Lock {
+  static _STLP_STATIC_MUTEX& _S_Mutex() {
+    static _STLP_STATIC_MUTEX mutex _STLP_MUTEX_INITIALIZER;
+    return mutex;
+  }
+public:
+  _Node_Alloc_Lock() {
+#    if defined (_STLP_SGI_THREADS)
+    if (__us_rsthread_malloc)
+#    endif
+      _S_Mutex()._M_acquire_lock();
+  }
+
+  ~_Node_Alloc_Lock() {
+#    if defined (_STLP_SGI_THREADS)
+    if (__us_rsthread_malloc)
+#    endif
+      _S_Mutex()._M_release_lock();
+  }
+};
+
+#  else
+
+class _Node_Alloc_Lock {
+public:
+  _Node_Alloc_Lock() { }
+  ~_Node_Alloc_Lock() { }
+};
+
+#  endif
+
+struct _Node_alloc_obj {
+  _Node_alloc_obj * _M_next;
+};
+#endif
+
+class __node_alloc_impl {
+  static inline size_t _STLP_CALL _S_round_up(size_t __bytes)
+  { return (((__bytes) + (size_t)_ALIGN-1) & ~((size_t)_ALIGN - 1)); }
+
+#if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+  typedef _STLP_atomic_freelist::item   _Obj;
+  typedef _STLP_atomic_freelist         _Freelist;
+  typedef _STLP_atomic_freelist         _ChunkList;
+
+  // Header of blocks of memory that have been allocated as part of
+  // a larger chunk but have not yet been chopped up into nodes.
+  struct _FreeBlockHeader : public _STLP_atomic_freelist::item {
+    char* _M_end;     // pointer to end of free memory
+  };
+#else
+  typedef _Node_alloc_obj       _Obj;
+  typedef _Obj* _STLP_VOLATILE  _Freelist;
+  typedef _Obj*                 _ChunkList;
+#endif
+
+private:
+  // Returns an object of size __n, and optionally adds to size __n free list.
+  static _Obj* _S_refill(size_t __n);
+  // Allocates a chunk for nobjs of size __p_size.  nobjs may be reduced
+  // if it is inconvenient to allocate the requested number.
+  static char* _S_chunk_alloc(size_t __p_size, int& __nobjs);
+  // Chunk allocation state.
+  static _Freelist _S_free_list[_STLP_NFREELISTS];
+  // Amount of total allocated memory
+#if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+  static _STLP_VOLATILE __add_atomic_t _S_heap_size;
+#else
+  static size_t _S_heap_size;
+#endif
+
+#if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+  // List of blocks of free memory
+  static _STLP_atomic_freelist  _S_free_mem_blocks;
+#else
+  // Start of the current free memory buffer
+  static char* _S_start_free;
+  // End of the current free memory buffer
+  static char* _S_end_free;
+#endif
+
+#if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+public:
+  // Methods to report alloc/dealloc calls to the counter system.
+#  if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+  typedef _STLP_VOLATILE __stl_atomic_t _AllocCounter;
+#  else
+  typedef __stl_atomic_t _AllocCounter;
+#  endif
+  static _AllocCounter& _STLP_CALL _S_alloc_counter();
+  static void _S_alloc_call();
+  static void _S_dealloc_call();
+
+private:
+  // Free all the allocated chuncks of memory
+  static void _S_chunk_dealloc();
+  // Beginning of the linked list of allocated chunks of memory
+  static _ChunkList _S_chunks;
+#endif /* _STLP_DO_CLEAN_NODE_ALLOC */
+
+public:
+  /* __n must be > 0      */
+  static void* _M_allocate(size_t& __n);
+  /* __p may not be 0 */
+  static void _M_deallocate(void *__p, size_t __n);
+};
+
+#if !defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+void* __node_alloc_impl::_M_allocate(size_t& __n) {
+  __n = _S_round_up(__n);
+  _Obj * _STLP_VOLATILE * __my_free_list = _S_free_list + _S_FREELIST_INDEX(__n);
+  _Obj *__r;
+
+  // Acquire the lock here with a constructor call.
+  // This ensures that it is released in exit or during stack
+  // unwinding.
+  _Node_Alloc_Lock __lock_instance;
+
+  if ( (__r  = *__my_free_list) != 0 ) {
+    *__my_free_list = __r->_M_next;
+  } else {
+    __r = _S_refill(__n);
+  }
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  _S_alloc_call();
+#  endif
+  // lock is released here
+  return __r;
+}
+
+void __node_alloc_impl::_M_deallocate(void *__p, size_t __n) {
+  _Obj * _STLP_VOLATILE * __my_free_list = _S_free_list + _S_FREELIST_INDEX(__n);
+  _Obj * __pobj = __STATIC_CAST(_Obj*, __p);
+
+  // acquire lock
+  _Node_Alloc_Lock __lock_instance;
+  __pobj->_M_next = *__my_free_list;
+  *__my_free_list = __pobj;
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  _S_dealloc_call();
+#  endif
+  // lock is released here
+}
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+#    define _STLP_OFFSET sizeof(_Obj)
+#  else
+#    define _STLP_OFFSET 0
+#  endif
+
+/* We allocate memory in large chunks in order to avoid fragmenting     */
+/* the malloc heap too much.                                            */
+/* We assume that size is properly aligned.                             */
+/* We hold the allocation lock.                                         */
+char* __node_alloc_impl::_S_chunk_alloc(size_t _p_size, int& __nobjs) {
+  char* __result;
+  size_t __total_bytes = _p_size * __nobjs;
+  size_t __bytes_left = _S_end_free - _S_start_free;
+
+  if (__bytes_left > 0) {
+    if (__bytes_left >= __total_bytes) {
+      __result = _S_start_free;
+      _S_start_free += __total_bytes;
+      return __result;
+    }
+
+    if (__bytes_left >= _p_size) {
+      __nobjs = (int)(__bytes_left / _p_size);
+      __total_bytes = _p_size * __nobjs;
+      __result = _S_start_free;
+      _S_start_free += __total_bytes;
+      return __result;
+    }
+
+    // Try to make use of the left-over piece.
+    _Obj* _STLP_VOLATILE* __my_free_list = _S_free_list + _S_FREELIST_INDEX(__bytes_left);
+    __REINTERPRET_CAST(_Obj*, _S_start_free)->_M_next = *__my_free_list;
+    *__my_free_list = __REINTERPRET_CAST(_Obj*, _S_start_free);
+    _S_start_free = _S_end_free = 0;
+  }
+
+  size_t __bytes_to_get = 2 * __total_bytes + _S_round_up(_S_heap_size) + _STLP_OFFSET;
+
+  _STLP_TRY {
+    _S_start_free = __stlp_new_chunk(__bytes_to_get);
+  }
+#if defined (_STLP_USE_EXCEPTIONS)
+  catch (const _STLP_STD::bad_alloc&) {
+    _Obj* _STLP_VOLATILE* __my_free_list;
+    _Obj* __p;
+    // Try to do with what we have.  That can't hurt.
+    // We do not try smaller requests, since that tends
+    // to result in disaster on multi-process machines.
+    for (size_t __i = _p_size; __i <= (size_t)_MAX_BYTES; __i += (size_t)_ALIGN) {
+      __my_free_list = _S_free_list + _S_FREELIST_INDEX(__i);
+      __p = *__my_free_list;
+      if (0 != __p) {
+        *__my_free_list = __p -> _M_next;
+        _S_start_free = __REINTERPRET_CAST(char*, __p);
+        _S_end_free = _S_start_free + __i;
+        return _S_chunk_alloc(_p_size, __nobjs);
+        // Any leftover piece will eventually make it to the
+        // right free list.
+      }
+    }
+    __bytes_to_get = __total_bytes + _STLP_OFFSET;
+    _S_start_free = __stlp_new_chunk(__bytes_to_get);
+  }
+#endif
+
+  _S_heap_size += __bytes_to_get >> 4;
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  __REINTERPRET_CAST(_Obj*, _S_start_free)->_M_next = _S_chunks;
+  _S_chunks = __REINTERPRET_CAST(_Obj*, _S_start_free);
+#  endif
+  _S_end_free = _S_start_free + __bytes_to_get;
+  _S_start_free += _STLP_OFFSET;
+  return _S_chunk_alloc(_p_size, __nobjs);
+}
+
+/* Returns an object of size __n, and optionally adds to size __n free list.*/
+/* We assume that __n is properly aligned.                                  */
+/* We hold the allocation lock.                                             */
+_Node_alloc_obj* __node_alloc_impl::_S_refill(size_t __n) {
+  int __nobjs = 20;
+  char* __chunk = _S_chunk_alloc(__n, __nobjs);
+
+  if (1 == __nobjs) return __REINTERPRET_CAST(_Obj*, __chunk);
+
+  _Obj* _STLP_VOLATILE* __my_free_list = _S_free_list + _S_FREELIST_INDEX(__n);
+  _Obj* __result;
+  _Obj* __current_obj;
+  _Obj* __next_obj;
+
+  /* Build free list in chunk */
+  __result = __REINTERPRET_CAST(_Obj*, __chunk);
+  *__my_free_list = __next_obj = __REINTERPRET_CAST(_Obj*, __chunk + __n);
+  for (--__nobjs; --__nobjs; ) {
+    __current_obj = __next_obj;
+    __next_obj = __REINTERPRET_CAST(_Obj*, __REINTERPRET_CAST(char*, __next_obj) + __n);
+    __current_obj->_M_next = __next_obj;
+  }
+  __next_obj->_M_next = 0;
+  return __result;
+}
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+void __node_alloc_impl::_S_alloc_call()
+{ ++_S_alloc_counter(); }
+
+void __node_alloc_impl::_S_dealloc_call() {
+  __stl_atomic_t &counter = _S_alloc_counter();
+  if (--counter == 0)
+  { _S_chunk_dealloc(); }
+}
+
+/* We deallocate all the memory chunks      */
+void __node_alloc_impl::_S_chunk_dealloc() {
+  _Obj *__pcur = _S_chunks, *__pnext;
+  while (__pcur != 0) {
+    __pnext = __pcur->_M_next;
+    __stlp_delete_chunck(__pcur);
+    __pcur = __pnext;
+  }
+  _S_chunks = 0;
+  _S_start_free = _S_end_free = 0;
+  _S_heap_size = 0;
+  memset(__REINTERPRET_CAST(char*, __CONST_CAST(_Obj**, &_S_free_list[0])), 0, _STLP_NFREELISTS * sizeof(_Obj*));
+}
+#  endif
+
+#else
+
+void* __node_alloc_impl::_M_allocate(size_t& __n) {
+  __n = _S_round_up(__n);
+  _Obj* __r = _S_free_list[_S_FREELIST_INDEX(__n)].pop();
+  if (__r  == 0)
+  { __r = _S_refill(__n); }
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  _S_alloc_call();
+#  endif
+  return __r;
+}
+
+void __node_alloc_impl::_M_deallocate(void *__p, size_t __n) {
+  _S_free_list[_S_FREELIST_INDEX(__n)].push(__STATIC_CAST(_Obj*, __p));
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  _S_dealloc_call();
+#  endif
+}
+
+/* Returns an object of size __n, and optionally adds additional ones to    */
+/* freelist of objects of size __n.                                         */
+/* We assume that __n is properly aligned.                                  */
+__node_alloc_impl::_Obj* __node_alloc_impl::_S_refill(size_t __n) {
+  int __nobjs = 20;
+  char* __chunk = _S_chunk_alloc(__n, __nobjs);
+
+  if (__nobjs <= 1)
+    return __REINTERPRET_CAST(_Obj*, __chunk);
+
+  // Push all new nodes (minus first one) onto freelist
+  _Obj* __result   = __REINTERPRET_CAST(_Obj*, __chunk);
+  _Obj* __cur_item = __result;
+  _Freelist* __my_freelist = _S_free_list + _S_FREELIST_INDEX(__n);
+  for (--__nobjs; __nobjs != 0; --__nobjs) {
+    __cur_item  = __REINTERPRET_CAST(_Obj*, __REINTERPRET_CAST(char*, __cur_item) + __n);
+    __my_freelist->push(__cur_item);
+  }
+  return __result;
+}
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+#    define _STLP_OFFSET _ALIGN
+#  else
+#    define _STLP_OFFSET 0
+#  endif
+
+/* We allocate memory in large chunks in order to avoid fragmenting     */
+/* the malloc heap too much.                                            */
+/* We assume that size is properly aligned.                             */
+char* __node_alloc_impl::_S_chunk_alloc(size_t _p_size, int& __nobjs) {
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  //We are going to add a small memory block to keep all the allocated blocks
+  //address, we need to do so respecting the memory alignment. The following
+  //static assert checks that the reserved block is big enough to store a pointer.
+  _STLP_STATIC_ASSERT(sizeof(_Obj) <= _ALIGN)
+#  endif
+  char*  __result       = 0;
+  __add_atomic_t __total_bytes  = __STATIC_CAST(__add_atomic_t, _p_size) * __nobjs;
+
+  _FreeBlockHeader* __block = __STATIC_CAST(_FreeBlockHeader*, _S_free_mem_blocks.pop());
+  if (__block != 0) {
+    // We checked a block out and can now mess with it with impugnity.
+    // We'll put the remainder back into the list if we're done with it below.
+    char*  __buf_start  = __REINTERPRET_CAST(char*, __block);
+    __add_atomic_t __bytes_left = __block->_M_end - __buf_start;
+
+    if ((__bytes_left < __total_bytes) && (__bytes_left >= __STATIC_CAST(__add_atomic_t, _p_size))) {
+      // There's enough left for at least one object, but not as much as we wanted
+      __result      = __buf_start;
+      __nobjs       = (int)(__bytes_left/_p_size);
+      __total_bytes = __STATIC_CAST(__add_atomic_t, _p_size) * __nobjs;
+      __bytes_left -= __total_bytes;
+      __buf_start  += __total_bytes;
+    }
+    else if (__bytes_left >= __total_bytes) {
+      // The block has enough left to satisfy all that was asked for
+      __result      = __buf_start;
+      __bytes_left -= __total_bytes;
+      __buf_start  += __total_bytes;
+    }
+
+    if (__bytes_left != 0) {
+      // There is still some memory left over in block after we satisfied our request.
+      if ((__result != 0) && (__bytes_left >= (__add_atomic_t)sizeof(_FreeBlockHeader))) {
+        // We were able to allocate at least one object and there is still enough
+        // left to put remainder back into list.
+        _FreeBlockHeader* __newblock = __REINTERPRET_CAST(_FreeBlockHeader*, __buf_start);
+        __newblock->_M_end  = __block->_M_end;
+        _S_free_mem_blocks.push(__newblock);
+      }
+      else {
+        // We were not able to allocate enough for at least one object.
+        // Shove into freelist of nearest (rounded-down!) size.
+        size_t __rounded_down = _S_round_up(__bytes_left + 1) - (size_t)_ALIGN;
+        if (__rounded_down > 0)
+          _S_free_list[_S_FREELIST_INDEX(__rounded_down)].push((_Obj*)__buf_start);
+      }
+    }
+    if (__result != 0)
+      return __result;
+  }
+
+  // We couldn't satisfy it from the list of free blocks, get new memory.
+  __add_atomic_t __bytes_to_get = 2 * __total_bytes +
+                                  __STATIC_CAST(__add_atomic_t,
+                                                _S_round_up(__STATIC_CAST(__uadd_atomic_t, _STLP_ATOMIC_ADD(&_S_heap_size, 0)))) +
+                                  _STLP_OFFSET;
+  _STLP_TRY {
+    __result = __stlp_new_chunk(__bytes_to_get);
+  }
+#if defined (_STLP_USE_EXCEPTIONS)
+  catch (const bad_alloc&) {
+    // Allocation failed; try to canibalize from freelist of a larger object size.
+    for (size_t __i = _p_size; __i <= (size_t)_MAX_BYTES; __i += (size_t)_ALIGN) {
+      _Obj* __p  = _S_free_list[_S_FREELIST_INDEX(__i)].pop();
+      if (0 != __p) {
+        if (__i < sizeof(_FreeBlockHeader)) {
+          // Not enough to put into list of free blocks, divvy it up here.
+          // Use as much as possible for this request and shove remainder into freelist.
+          __nobjs = (int)(__i/_p_size);
+          __total_bytes = __nobjs * __STATIC_CAST(__add_atomic_t, _p_size);
+          size_t __bytes_left = __i - __total_bytes;
+          size_t __rounded_down = _S_round_up(__bytes_left+1) - (size_t)_ALIGN;
+          if (__rounded_down > 0) {
+            _S_free_list[_S_FREELIST_INDEX(__rounded_down)].push(__REINTERPRET_CAST(_Obj*, __REINTERPRET_CAST(char*, __p) + __total_bytes));
+          }
+          return __REINTERPRET_CAST(char*, __p);
+        }
+        else {
+          // Add node to list of available blocks and recursively allocate from it.
+          _FreeBlockHeader* __newblock = (_FreeBlockHeader*)__p;
+          __newblock->_M_end  = __REINTERPRET_CAST(char*, __p) + __i;
+          _S_free_mem_blocks.push(__newblock);
+          return _S_chunk_alloc(_p_size, __nobjs);
+        }
+      }
+    }
+
+    // We were not able to find something in a freelist, try to allocate a smaller amount.
+    __bytes_to_get  = __total_bytes + _STLP_OFFSET;
+    __result = __stlp_new_chunk(__bytes_to_get);
+
+    // This should either throw an exception or remedy the situation.
+    // Thus we assume it succeeded.
+  }
+#endif
+  // Alignment check
+  _STLP_VERBOSE_ASSERT(((__REINTERPRET_CAST(size_t, __result) & __STATIC_CAST(size_t, _ALIGN - 1)) == 0),
+                       _StlMsg_DBA_DELETED_TWICE)
+  _STLP_ATOMIC_ADD(&_S_heap_size, __bytes_to_get >> 4);
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  // We have to track the allocated memory chunks for release on exit.
+  _S_chunks.push(__REINTERPRET_CAST(_Obj*, __result));
+  __result       += _ALIGN;
+  __bytes_to_get -= _ALIGN;
+#  endif
+
+  if (__bytes_to_get > __total_bytes) {
+    // Push excess memory allocated in this chunk into list of free memory blocks
+    _FreeBlockHeader* __freeblock = __REINTERPRET_CAST(_FreeBlockHeader*, __result + __total_bytes);
+    __freeblock->_M_end  = __result + __bytes_to_get;
+    _S_free_mem_blocks.push(__freeblock);
+  }
+  return __result;
+}
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+void __node_alloc_impl::_S_alloc_call()
+{ _STLP_ATOMIC_INCREMENT(&_S_alloc_counter()); }
+
+void __node_alloc_impl::_S_dealloc_call() {
+  _STLP_VOLATILE __stl_atomic_t *pcounter = &_S_alloc_counter();
+  if (_STLP_ATOMIC_DECREMENT(pcounter) == 0)
+    _S_chunk_dealloc();
+}
+
+/* We deallocate all the memory chunks      */
+void __node_alloc_impl::_S_chunk_dealloc() {
+  // Note: The _Node_alloc_helper class ensures that this function
+  // will only be called when the (shared) library is unloaded or the
+  // process is shutdown.  It's thus not possible that another thread
+  // is currently trying to allocate a node (we're not thread-safe here).
+  //
+
+  // Clear the free blocks and all freelistst.  This makes sure that if
+  // for some reason more memory is allocated again during shutdown
+  // (it'd also be really nasty to leave references to deallocated memory).
+  _S_free_mem_blocks.clear();
+  _S_heap_size      = 0;
+
+  for (size_t __i = 0; __i < _STLP_NFREELISTS; ++__i) {
+    _S_free_list[__i].clear();
+  }
+
+  // Detach list of chunks and free them all
+  _Obj* __chunk = _S_chunks.clear();
+  while (__chunk != 0) {
+    _Obj* __next = __chunk->_M_next;
+    __stlp_delete_chunck(__chunk);
+    __chunk  = __next;
+  }
+}
+#  endif
+
+#endif
+
+#if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+struct __node_alloc_cleaner {
+  ~__node_alloc_cleaner()
+  { __node_alloc_impl::_S_dealloc_call(); }
+};
+
+#  if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+_STLP_VOLATILE __stl_atomic_t& _STLP_CALL
+#  else
+__stl_atomic_t& _STLP_CALL
+#  endif
+__node_alloc_impl::_S_alloc_counter() {
+  static _AllocCounter _S_counter = 1;
+  static __node_alloc_cleaner _S_node_alloc_cleaner;
+  return _S_counter;
+}
+#endif
+
+#if !defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+_Node_alloc_obj * _STLP_VOLATILE
+__node_alloc_impl::_S_free_list[_STLP_NFREELISTS]
+= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+// The 16 zeros are necessary to make version 4.1 of the SunPro
+// compiler happy.  Otherwise it appears to allocate too little
+// space for the array.
+#else
+_STLP_atomic_freelist __node_alloc_impl::_S_free_list[_STLP_NFREELISTS];
+_STLP_atomic_freelist __node_alloc_impl::_S_free_mem_blocks;
+#endif
+
+#if !defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+char *__node_alloc_impl::_S_start_free = 0;
+char *__node_alloc_impl::_S_end_free = 0;
+#endif
+
+#if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+_STLP_VOLATILE __add_atomic_t
+#else
+size_t
+#endif
+__node_alloc_impl::_S_heap_size = 0;
+
+#if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+#  if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+_STLP_atomic_freelist __node_alloc_impl::_S_chunks;
+#  else
+_Node_alloc_obj* __node_alloc_impl::_S_chunks  = 0;
+#  endif
+#endif
+
+void * _STLP_CALL __node_alloc::_M_allocate(size_t& __n)
+{ return __node_alloc_impl::_M_allocate(__n); }
+
+void _STLP_CALL __node_alloc::_M_deallocate(void *__p, size_t __n)
+{ __node_alloc_impl::_M_deallocate(__p, __n); }
+
+#if defined (_STLP_PTHREADS) && !defined (_STLP_NO_THREADS)
+
+#  define _STLP_DATA_ALIGNMENT 8
+
+_STLP_MOVE_TO_PRIV_NAMESPACE
+
+// *******************************************************
+// __perthread_alloc implementation
+union _Pthread_alloc_obj {
+  union _Pthread_alloc_obj * __free_list_link;
+  char __client_data[_STLP_DATA_ALIGNMENT];    /* The client sees this.    */
+};
+
+// Pthread allocators don't appear to the client to have meaningful
+// instances.  We do in fact need to associate some state with each
+// thread.  That state is represented by _Pthread_alloc_per_thread_state.
+
+struct _Pthread_alloc_per_thread_state {
+  typedef _Pthread_alloc_obj __obj;
+  enum { _S_NFREELISTS = _MAX_BYTES / _STLP_DATA_ALIGNMENT };
+
+  // Free list link for list of available per thread structures.
+  // When one of these becomes available for reuse due to thread
+  // termination, any objects in its free list remain associated
+  // with it.  The whole structure may then be used by a newly
+  // created thread.
+  _Pthread_alloc_per_thread_state() : __next(0)
+  { memset((void *)__CONST_CAST(_Pthread_alloc_obj**, __free_list), 0, (size_t)_S_NFREELISTS * sizeof(__obj *)); }
+  // Returns an object of size __n, and possibly adds to size n free list.
+  void *_M_refill(size_t __n);
+
+  _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS];
+  _Pthread_alloc_per_thread_state *__next;
+  // this data member is only to be used by per_thread_allocator, which returns memory to the originating thread.
+  _STLP_mutex _M_lock;
+};
+
+// Pthread-specific allocator.
+class _Pthread_alloc_impl {
+public: // but only for internal use:
+  typedef _Pthread_alloc_per_thread_state __state_type;
+  typedef char value_type;
+
+  // Allocates a chunk for nobjs of size size.  nobjs may be reduced
+  // if it is inconvenient to allocate the requested number.
+  static char *_S_chunk_alloc(size_t __size, size_t &__nobjs, __state_type*);
+
+  enum {_S_ALIGN = _STLP_DATA_ALIGNMENT};
+
+  static size_t _S_round_up(size_t __bytes)
+  { return (((__bytes) + (int)_S_ALIGN - 1) & ~((int)_S_ALIGN - 1)); }
+  static size_t _S_freelist_index(size_t __bytes)
+  { return (((__bytes) + (int)_S_ALIGN - 1) / (int)_S_ALIGN - 1); }
+
+private:
+  // Chunk allocation state. And other shared state.
+  // Protected by _S_chunk_allocator_lock.
+  static _STLP_STATIC_MUTEX _S_chunk_allocator_lock;
+  static char *_S_start_free;
+  static char *_S_end_free;
+  static size_t _S_heap_size;
+  static __state_type *_S_free_per_thread_states;
+  static pthread_key_t _S_key;
+  static bool _S_key_initialized;
+  // Pthread key under which per thread state is stored.
+  // Allocator instances that are currently unclaimed by any thread.
+  static void _S_destructor(void *instance);
+  // Function to be called on thread exit to reclaim per thread
+  // state.
+  static __state_type *_S_new_per_thread_state();
+public:
+  // Return a recycled or new per thread state.
+  static __state_type *_S_get_per_thread_state();
+private:
+        // ensure that the current thread has an associated
+        // per thread state.
+  class _M_lock;
+  friend class _M_lock;
+  class _M_lock {
+  public:
+    _M_lock () { _S_chunk_allocator_lock._M_acquire_lock(); }
+    ~_M_lock () { _S_chunk_allocator_lock._M_release_lock(); }
+  };
+
+public:
+
+  /* n must be > 0      */
+  static void * allocate(size_t& __n);
+
+  /* p may not be 0 */
+  static void deallocate(void *__p, size_t __n);
+
+  // boris : versions for per_thread_allocator
+  /* n must be > 0      */
+  static void * allocate(size_t& __n, __state_type* __a);
+
+  /* p may not be 0 */
+  static void deallocate(void *__p, size_t __n, __state_type* __a);
+
+  static void * reallocate(void *__p, size_t __old_sz, size_t& __new_sz);
+};
+
+/* Returns an object of size n, and optionally adds to size n free list.*/
+/* We assume that n is properly aligned.                                */
+/* We hold the allocation lock.                                         */
+void *_Pthread_alloc_per_thread_state::_M_refill(size_t __n) {
+  typedef _Pthread_alloc_obj __obj;
+  size_t __nobjs = 128;
+  char * __chunk = _Pthread_alloc_impl::_S_chunk_alloc(__n, __nobjs, this);
+  __obj * volatile * __my_free_list;
+  __obj * __result;
+  __obj * __current_obj, * __next_obj;
+  size_t __i;
+
+  if (1 == __nobjs)  {
+    return __chunk;
+  }
+
+  __my_free_list = __free_list + _Pthread_alloc_impl::_S_freelist_index(__n);
+
+  /* Build free list in chunk */
+  __result = (__obj *)__chunk;
+  *__my_free_list = __next_obj = (__obj *)(__chunk + __n);
+  for (__i = 1; ; ++__i) {
+    __current_obj = __next_obj;
+    __next_obj = (__obj *)((char *)__next_obj + __n);
+    if (__nobjs - 1 == __i) {
+      __current_obj -> __free_list_link = 0;
+      break;
+    } else {
+      __current_obj -> __free_list_link = __next_obj;
+    }
+  }
+  return __result;
+}
+
+void _Pthread_alloc_impl::_S_destructor(void *__instance) {
+  _M_lock __lock_instance;  // Need to acquire lock here.
+  _Pthread_alloc_per_thread_state* __s = (_Pthread_alloc_per_thread_state*)__instance;
+  __s -> __next = _S_free_per_thread_states;
+  _S_free_per_thread_states = __s;
+}
+
+_Pthread_alloc_per_thread_state* _Pthread_alloc_impl::_S_new_per_thread_state() {
+  /* lock already held here.  */
+  if (0 != _S_free_per_thread_states) {
+    _Pthread_alloc_per_thread_state *__result = _S_free_per_thread_states;
+    _S_free_per_thread_states = _S_free_per_thread_states -> __next;
+    return __result;
+  }
+  else {
+    return new _Pthread_alloc_per_thread_state;
+  }
+}
+
+_Pthread_alloc_per_thread_state* _Pthread_alloc_impl::_S_get_per_thread_state() {
+  int __ret_code;
+  __state_type* __result;
+
+  if (_S_key_initialized && (__result = (__state_type*) pthread_getspecific(_S_key)))
+    return __result;
+
+  /*REFERENCED*/
+  _M_lock __lock_instance;  // Need to acquire lock here.
+  if (!_S_key_initialized) {
+    if (pthread_key_create(&_S_key, _S_destructor)) {
+      _STLP_THROW_BAD_ALLOC;  // failed
+    }
+    _S_key_initialized = true;
+  }
+
+  __result = _S_new_per_thread_state();
+  __ret_code = pthread_setspecific(_S_key, __result);
+  if (__ret_code) {
+    if (__ret_code == ENOMEM) {
+      _STLP_THROW_BAD_ALLOC;
+    } else {
+  // EINVAL
+      _STLP_ABORT();
+    }
+  }
+  return __result;
+}
+
+/* We allocate memory in large chunks in order to avoid fragmenting     */
+/* the malloc heap too much.                                            */
+/* We assume that size is properly aligned.                             */
+char *_Pthread_alloc_impl::_S_chunk_alloc(size_t __p_size, size_t &__nobjs, _Pthread_alloc_per_thread_state *__a) {
+  typedef _Pthread_alloc_obj __obj;
+  {
+    char * __result;
+    size_t __total_bytes;
+    size_t __bytes_left;
+    /*REFERENCED*/
+    _M_lock __lock_instance;         // Acquire lock for this routine
+
+    __total_bytes = __p_size * __nobjs;
+    __bytes_left = _S_end_free - _S_start_free;
+    if (__bytes_left >= __total_bytes) {
+      __result = _S_start_free;
+      _S_start_free += __total_bytes;
+      return __result;
+    } else if (__bytes_left >= __p_size) {
+      __nobjs = __bytes_left/__p_size;
+      __total_bytes = __p_size * __nobjs;
+      __result = _S_start_free;
+      _S_start_free += __total_bytes;
+      return __result;
+    } else {
+      size_t __bytes_to_get = 2 * __total_bytes + _S_round_up(_S_heap_size);
+      // Try to make use of the left-over piece.
+      if (__bytes_left > 0) {
+        __obj * volatile * __my_free_list = __a->__free_list + _S_freelist_index(__bytes_left);
+        ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list;
+        *__my_free_list = (__obj *)_S_start_free;
+      }
+#  ifdef _SGI_SOURCE
+      // Try to get memory that's aligned on something like a
+      // cache line boundary, so as to avoid parceling out
+      // parts of the same line to different threads and thus
+      // possibly different processors.
+      {
+        const int __cache_line_size = 128;  // probable upper bound
+        __bytes_to_get &= ~(__cache_line_size-1);
+        _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get);
+        if (0 == _S_start_free) {
+          _S_start_free = (char *)__malloc_alloc::allocate(__bytes_to_get);
+        }
+      }
+#  else  /* !SGI_SOURCE */
+      _S_start_free = (char *)__malloc_alloc::allocate(__bytes_to_get);
+#  endif
+      _S_heap_size += __bytes_to_get >> 4;
+      _S_end_free = _S_start_free + __bytes_to_get;
+    }
+  }
+  // lock is released here
+  return _S_chunk_alloc(__p_size, __nobjs, __a);
+}
+
+
+/* n must be > 0      */
+void *_Pthread_alloc_impl::allocate(size_t& __n) {
+  typedef _Pthread_alloc_obj __obj;
+  __obj * volatile * __my_free_list;
+  __obj * __result;
+  __state_type* __a;
+
+  if (__n > _MAX_BYTES) {
+    return __malloc_alloc::allocate(__n);
+  }
+
+  __n = _S_round_up(__n);
+  __a = _S_get_per_thread_state();
+
+  __my_free_list = __a->__free_list + _S_freelist_index(__n);
+  __result = *__my_free_list;
+  if (__result == 0) {
+    void *__r = __a->_M_refill(__n);
+    return __r;
+  }
+  *__my_free_list = __result->__free_list_link;
+  return __result;
+};
+
+/* p may not be 0 */
+void _Pthread_alloc_impl::deallocate(void *__p, size_t __n) {
+  typedef _Pthread_alloc_obj __obj;
+  __obj *__q = (__obj *)__p;
+  __obj * volatile * __my_free_list;
+  __state_type* __a;
+
+  if (__n > _MAX_BYTES) {
+      __malloc_alloc::deallocate(__p, __n);
+      return;
+  }
+
+  __a = _S_get_per_thread_state();
+
+  __my_free_list = __a->__free_list + _S_freelist_index(__n);
+  __q -> __free_list_link = *__my_free_list;
+  *__my_free_list = __q;
+}
+
+// boris : versions for per_thread_allocator
+/* n must be > 0      */
+void *_Pthread_alloc_impl::allocate(size_t& __n, __state_type* __a) {
+  typedef _Pthread_alloc_obj __obj;
+  __obj * volatile * __my_free_list;
+  __obj * __result;
+
+  if (__n > _MAX_BYTES) {
+    return __malloc_alloc::allocate(__n);
+  }
+  __n = _S_round_up(__n);
+
+  // boris : here, we have to lock per thread state, as we may be getting memory from
+  // different thread pool.
+  _STLP_auto_lock __lock(__a->_M_lock);
+
+  __my_free_list = __a->__free_list + _S_freelist_index(__n);
+  __result = *__my_free_list;
+  if (__result == 0) {
+    void *__r = __a->_M_refill(__n);
+    return __r;
+  }
+  *__my_free_list = __result->__free_list_link;
+  return __result;
+};
+
+/* p may not be 0 */
+void _Pthread_alloc_impl::deallocate(void *__p, size_t __n, __state_type* __a) {
+  typedef _Pthread_alloc_obj __obj;
+  __obj *__q = (__obj *)__p;
+  __obj * volatile * __my_free_list;
+
+  if (__n > _MAX_BYTES) {
+    __malloc_alloc::deallocate(__p, __n);
+    return;
+  }
+
+  // boris : here, we have to lock per thread state, as we may be returning memory from
+  // different thread.
+  _STLP_auto_lock __lock(__a->_M_lock);
+
+  __my_free_list = __a->__free_list + _S_freelist_index(__n);
+  __q -> __free_list_link = *__my_free_list;
+  *__my_free_list = __q;
+}
+
+void *_Pthread_alloc_impl::reallocate(void *__p, size_t __old_sz, size_t& __new_sz) {
+  void * __result;
+  size_t __copy_sz;
+
+  if (__old_sz > _MAX_BYTES && __new_sz > _MAX_BYTES) {
+    return realloc(__p, __new_sz);
+  }
+
+  if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return __p;
+  __result = allocate(__new_sz);
+  __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
+  memcpy(__result, __p, __copy_sz);
+  deallocate(__p, __old_sz);
+  return __result;
+}
+
+_Pthread_alloc_per_thread_state* _Pthread_alloc_impl::_S_free_per_thread_states = 0;
+pthread_key_t _Pthread_alloc_impl::_S_key = 0;
+_STLP_STATIC_MUTEX _Pthread_alloc_impl::_S_chunk_allocator_lock _STLP_MUTEX_INITIALIZER;
+bool _Pthread_alloc_impl::_S_key_initialized = false;
+char *_Pthread_alloc_impl::_S_start_free = 0;
+char *_Pthread_alloc_impl::_S_end_free = 0;
+size_t _Pthread_alloc_impl::_S_heap_size = 0;
+
+void * _STLP_CALL _Pthread_alloc::allocate(size_t& __n)
+{ return _Pthread_alloc_impl::allocate(__n); }
+void _STLP_CALL _Pthread_alloc::deallocate(void *__p, size_t __n)
+{ _Pthread_alloc_impl::deallocate(__p, __n); }
+void * _STLP_CALL _Pthread_alloc::allocate(size_t& __n, __state_type* __a)
+{ return _Pthread_alloc_impl::allocate(__n, __a); }
+void _STLP_CALL _Pthread_alloc::deallocate(void *__p, size_t __n, __state_type* __a)
+{ _Pthread_alloc_impl::deallocate(__p, __n, __a); }
+void * _STLP_CALL _Pthread_alloc::reallocate(void *__p, size_t __old_sz, size_t& __new_sz)
+{ return _Pthread_alloc_impl::reallocate(__p, __old_sz, __new_sz); }
+_Pthread_alloc_per_thread_state* _STLP_CALL _Pthread_alloc::_S_get_per_thread_state()
+{ return _Pthread_alloc_impl::_S_get_per_thread_state(); }
+
+_STLP_MOVE_TO_STD_NAMESPACE
+
+#endif
+
+_STLP_END_NAMESPACE
+
+#undef _S_FREELIST_INDEX
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/bitset.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1998
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include "stlport_prefix.h"
+
+#include <bitset>
+
+_STLP_BEGIN_NAMESPACE
+
+_STLP_MOVE_TO_PRIV_NAMESPACE
+
+// ------------------------------------------------------------
+// Lookup tables for find and count operations.
+
+size_t _Bs_G::_S_count(const unsigned char *__first,
+                       const unsigned char *__last)
+{
+  static const unsigned char _bit_count[256] = {
+  0, /*   0 */ 1, /*   1 */ 1, /*   2 */ 2, /*   3 */ 1, /*   4 */
+  2, /*   5 */ 2, /*   6 */ 3, /*   7 */ 1, /*   8 */ 2, /*   9 */
+  2, /*  10 */ 3, /*  11 */ 2, /*  12 */ 3, /*  13 */ 3, /*  14 */
+  4, /*  15 */ 1, /*  16 */ 2, /*  17 */ 2, /*  18 */ 3, /*  19 */
+  2, /*  20 */ 3, /*  21 */ 3, /*  22 */ 4, /*  23 */ 2, /*  24 */
+  3, /*  25 */ 3, /*  26 */ 4, /*  27 */ 3, /*  28 */ 4, /*  29 */
+  4, /*  30 */ 5, /*  31 */ 1, /*  32 */ 2, /*  33 */ 2, /*  34 */
+  3, /*  35 */ 2, /*  36 */ 3, /*  37 */ 3, /*  38 */ 4, /*  39 */
+  2, /*  40 */ 3, /*  41 */ 3, /*  42 */ 4, /*  43 */ 3, /*  44 */
+  4, /*  45 */ 4, /*  46 */ 5, /*  47 */ 2, /*  48 */ 3, /*  49 */
+  3, /*  50 */ 4, /*  51 */ 3, /*  52 */ 4, /*  53 */ 4, /*  54 */
+  5, /*  55 */ 3, /*  56 */ 4, /*  57 */ 4, /*  58 */ 5, /*  59 */
+  4, /*  60 */ 5, /*  61 */ 5, /*  62 */ 6, /*  63 */ 1, /*  64 */
+  2, /*  65 */ 2, /*  66 */ 3, /*  67 */ 2, /*  68 */ 3, /*  69 */
+  3, /*  70 */ 4, /*  71 */ 2, /*  72 */ 3, /*  73 */ 3, /*  74 */
+  4, /*  75 */ 3, /*  76 */ 4, /*  77 */ 4, /*  78 */ 5, /*  79 */
+  2, /*  80 */ 3, /*  81 */ 3, /*  82 */ 4, /*  83 */ 3, /*  84 */
+  4, /*  85 */ 4, /*  86 */ 5, /*  87 */ 3, /*  88 */ 4, /*  89 */
+  4, /*  90 */ 5, /*  91 */ 4, /*  92 */ 5, /*  93 */ 5, /*  94 */
+  6, /*  95 */ 2, /*  96 */ 3, /*  97 */ 3, /*  98 */ 4, /*  99 */
+  3, /* 100 */ 4, /* 101 */ 4, /* 102 */ 5, /* 103 */ 3, /* 104 */
+  4, /* 105 */ 4, /* 106 */ 5, /* 107 */ 4, /* 108 */ 5, /* 109 */
+  5, /* 110 */ 6, /* 111 */ 3, /* 112 */ 4, /* 113 */ 4, /* 114 */
+  5, /* 115 */ 4, /* 116 */ 5, /* 117 */ 5, /* 118 */ 6, /* 119 */
+  4, /* 120 */ 5, /* 121 */ 5, /* 122 */ 6, /* 123 */ 5, /* 124 */
+  6, /* 125 */ 6, /* 126 */ 7, /* 127 */ 1, /* 128 */ 2, /* 129 */
+  2, /* 130 */ 3, /* 131 */ 2, /* 132 */ 3, /* 133 */ 3, /* 134 */
+  4, /* 135 */ 2, /* 136 */ 3, /* 137 */ 3, /* 138 */ 4, /* 139 */
+  3, /* 140 */ 4, /* 141 */ 4, /* 142 */ 5, /* 143 */ 2, /* 144 */
+  3, /* 145 */ 3, /* 146 */ 4, /* 147 */ 3, /* 148 */ 4, /* 149 */
+  4, /* 150 */ 5, /* 151 */ 3, /* 152 */ 4, /* 153 */ 4, /* 154 */
+  5, /* 155 */ 4, /* 156 */ 5, /* 157 */ 5, /* 158 */ 6, /* 159 */
+  2, /* 160 */ 3, /* 161 */ 3, /* 162 */ 4, /* 163 */ 3, /* 164 */
+  4, /* 165 */ 4, /* 166 */ 5, /* 167 */ 3, /* 168 */ 4, /* 169 */
+  4, /* 170 */ 5, /* 171 */ 4, /* 172 */ 5, /* 173 */ 5, /* 174 */
+  6, /* 175 */ 3, /* 176 */ 4, /* 177 */ 4, /* 178 */ 5, /* 179 */
+  4, /* 180 */ 5, /* 181 */ 5, /* 182 */ 6, /* 183 */ 4, /* 184 */
+  5, /* 185 */ 5, /* 186 */ 6, /* 187 */ 5, /* 188 */ 6, /* 189 */
+  6, /* 190 */ 7, /* 191 */ 2, /* 192 */ 3, /* 193 */ 3, /* 194 */
+  4, /* 195 */ 3, /* 196 */ 4, /* 197 */ 4, /* 198 */ 5, /* 199 */
+  3, /* 200 */ 4, /* 201 */ 4, /* 202 */ 5, /* 203 */ 4, /* 204 */
+  5, /* 205 */ 5, /* 206 */ 6, /* 207 */ 3, /* 208 */ 4, /* 209 */
+  4, /* 210 */ 5, /* 211 */ 4, /* 212 */ 5, /* 213 */ 5, /* 214 */
+  6, /* 215 */ 4, /* 216 */ 5, /* 217 */ 5, /* 218 */ 6, /* 219 */
+  5, /* 220 */ 6, /* 221 */ 6, /* 222 */ 7, /* 223 */ 3, /* 224 */
+  4, /* 225 */ 4, /* 226 */ 5, /* 227 */ 4, /* 228 */ 5, /* 229 */
+  5, /* 230 */ 6, /* 231 */ 4, /* 232 */ 5, /* 233 */ 5, /* 234 */
+  6, /* 235 */ 5, /* 236 */ 6, /* 237 */ 6, /* 238 */ 7, /* 239 */
+  4, /* 240 */ 5, /* 241 */ 5, /* 242 */ 6, /* 243 */ 5, /* 244 */
+  6, /* 245 */ 6, /* 246 */ 7, /* 247 */ 5, /* 248 */ 6, /* 249 */
+  6, /* 250 */ 7, /* 251 */ 6, /* 252 */ 7, /* 253 */ 7, /* 254 */
+  8  /* 255 */
+  };
+
+  size_t __result(0);
+  while ( __first < __last ) {
+    __result += _bit_count[*(__first++)];
+  }
+  return __result;
+}
+
+unsigned char _Bs_G::_S_first_one(unsigned char __byte)
+{
+  static const unsigned char _first_one[256] = {
+  0, /*   0 */ 0, /*   1 */ 1, /*   2 */ 0, /*   3 */ 2, /*   4 */
+  0, /*   5 */ 1, /*   6 */ 0, /*   7 */ 3, /*   8 */ 0, /*   9 */
+  1, /*  10 */ 0, /*  11 */ 2, /*  12 */ 0, /*  13 */ 1, /*  14 */
+  0, /*  15 */ 4, /*  16 */ 0, /*  17 */ 1, /*  18 */ 0, /*  19 */
+  2, /*  20 */ 0, /*  21 */ 1, /*  22 */ 0, /*  23 */ 3, /*  24 */
+  0, /*  25 */ 1, /*  26 */ 0, /*  27 */ 2, /*  28 */ 0, /*  29 */
+  1, /*  30 */ 0, /*  31 */ 5, /*  32 */ 0, /*  33 */ 1, /*  34 */
+  0, /*  35 */ 2, /*  36 */ 0, /*  37 */ 1, /*  38 */ 0, /*  39 */
+  3, /*  40 */ 0, /*  41 */ 1, /*  42 */ 0, /*  43 */ 2, /*  44 */
+  0, /*  45 */ 1, /*  46 */ 0, /*  47 */ 4, /*  48 */ 0, /*  49 */
+  1, /*  50 */ 0, /*  51 */ 2, /*  52 */ 0, /*  53 */ 1, /*  54 */
+  0, /*  55 */ 3, /*  56 */ 0, /*  57 */ 1, /*  58 */ 0, /*  59 */
+  2, /*  60 */ 0, /*  61 */ 1, /*  62 */ 0, /*  63 */ 6, /*  64 */
+  0, /*  65 */ 1, /*  66 */ 0, /*  67 */ 2, /*  68 */ 0, /*  69 */
+  1, /*  70 */ 0, /*  71 */ 3, /*  72 */ 0, /*  73 */ 1, /*  74 */
+  0, /*  75 */ 2, /*  76 */ 0, /*  77 */ 1, /*  78 */ 0, /*  79 */
+  4, /*  80 */ 0, /*  81 */ 1, /*  82 */ 0, /*  83 */ 2, /*  84 */
+  0, /*  85 */ 1, /*  86 */ 0, /*  87 */ 3, /*  88 */ 0, /*  89 */
+  1, /*  90 */ 0, /*  91 */ 2, /*  92 */ 0, /*  93 */ 1, /*  94 */
+  0, /*  95 */ 5, /*  96 */ 0, /*  97 */ 1, /*  98 */ 0, /*  99 */
+  2, /* 100 */ 0, /* 101 */ 1, /* 102 */ 0, /* 103 */ 3, /* 104 */
+  0, /* 105 */ 1, /* 106 */ 0, /* 107 */ 2, /* 108 */ 0, /* 109 */
+  1, /* 110 */ 0, /* 111 */ 4, /* 112 */ 0, /* 113 */ 1, /* 114 */
+  0, /* 115 */ 2, /* 116 */ 0, /* 117 */ 1, /* 118 */ 0, /* 119 */
+  3, /* 120 */ 0, /* 121 */ 1, /* 122 */ 0, /* 123 */ 2, /* 124 */
+  0, /* 125 */ 1, /* 126 */ 0, /* 127 */ 7, /* 128 */ 0, /* 129 */
+  1, /* 130 */ 0, /* 131 */ 2, /* 132 */ 0, /* 133 */ 1, /* 134 */
+  0, /* 135 */ 3, /* 136 */ 0, /* 137 */ 1, /* 138 */ 0, /* 139 */
+  2, /* 140 */ 0, /* 141 */ 1, /* 142 */ 0, /* 143 */ 4, /* 144 */
+  0, /* 145 */ 1, /* 146 */ 0, /* 147 */ 2, /* 148 */ 0, /* 149 */
+  1, /* 150 */ 0, /* 151 */ 3, /* 152 */ 0, /* 153 */ 1, /* 154 */
+  0, /* 155 */ 2, /* 156 */ 0, /* 157 */ 1, /* 158 */ 0, /* 159 */
+  5, /* 160 */ 0, /* 161 */ 1, /* 162 */ 0, /* 163 */ 2, /* 164 */
+  0, /* 165 */ 1, /* 166 */ 0, /* 167 */ 3, /* 168 */ 0, /* 169 */
+  1, /* 170 */ 0, /* 171 */ 2, /* 172 */ 0, /* 173 */ 1, /* 174 */
+  0, /* 175 */ 4, /* 176 */ 0, /* 177 */ 1, /* 178 */ 0, /* 179 */
+  2, /* 180 */ 0, /* 181 */ 1, /* 182 */ 0, /* 183 */ 3, /* 184 */
+  0, /* 185 */ 1, /* 186 */ 0, /* 187 */ 2, /* 188 */ 0, /* 189 */
+  1, /* 190 */ 0, /* 191 */ 6, /* 192 */ 0, /* 193 */ 1, /* 194 */
+  0, /* 195 */ 2, /* 196 */ 0, /* 197 */ 1, /* 198 */ 0, /* 199 */
+  3, /* 200 */ 0, /* 201 */ 1, /* 202 */ 0, /* 203 */ 2, /* 204 */
+  0, /* 205 */ 1, /* 206 */ 0, /* 207 */ 4, /* 208 */ 0, /* 209 */
+  1, /* 210 */ 0, /* 211 */ 2, /* 212 */ 0, /* 213 */ 1, /* 214 */
+  0, /* 215 */ 3, /* 216 */ 0, /* 217 */ 1, /* 218 */ 0, /* 219 */
+  2, /* 220 */ 0, /* 221 */ 1, /* 222 */ 0, /* 223 */ 5, /* 224 */
+  0, /* 225 */ 1, /* 226 */ 0, /* 227 */ 2, /* 228 */ 0, /* 229 */
+  1, /* 230 */ 0, /* 231 */ 3, /* 232 */ 0, /* 233 */ 1, /* 234 */
+  0, /* 235 */ 2, /* 236 */ 0, /* 237 */ 1, /* 238 */ 0, /* 239 */
+  4, /* 240 */ 0, /* 241 */ 1, /* 242 */ 0, /* 243 */ 2, /* 244 */
+  0, /* 245 */ 1, /* 246 */ 0, /* 247 */ 3, /* 248 */ 0, /* 249 */
+  1, /* 250 */ 0, /* 251 */ 2, /* 252 */ 0, /* 253 */ 1, /* 254 */
+  0, /* 255 */
+  };
+  return _first_one[__byte];
+}
+
+_STLP_MOVE_TO_STD_NAMESPACE
+
+_STLP_END_NAMESPACE
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include "stlport_prefix.h"
+
+#include "c_locale.h"
+
+#if defined (_STLP_WIN32) && !defined (_STLP_WCE)
+#  include "c_locale_win32/c_locale_win32.c"
+#elif defined (_STLP_USE_GLIBC2_LOCALIZATION)
+#  include "c_locale_glibc/c_locale_glibc2.c" /* glibc 2.2 and newer */
+#else
+#  include "c_locale_dummy/c_locale_dummy.c"
+#endif
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale.h
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+/*
+ * It is impossible to write the C++ locale library in terms of locales
+ * as defined in the C standard.  Instead, we write the C++ locale and I/O
+ * library in terms of a low level C-like interface.  This file defines
+ * that interface.
+ *
+ * The low-level locale interface can't be written portably; there
+ * must be a version of it for each platform that the C++ library
+ * is ported to.  On many systems this interface may be a thin wrapper
+ * for existing functionality.
+ */
+
+#ifndef _STLP_C_LOCALE_IMPL_H
+#define _STLP_C_LOCALE_IMPL_H
+
+#include "stlport_prefix.h"
+
+#include <wchar.h> /* for mbstate_t */
+#include <stl/c_locale.h>
+
+struct _Locale_name_hint;
+
+#if defined (_GNU_SOURCE) && defined (__GLIBC__) && \
+    ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2))
+#  define _STLP_USE_GLIBC2_LOCALIZATION
+#  include <nl_types.h>
+typedef nl_catd nl_catd_type;
+#else
+typedef int nl_catd_type;
+#endif
+
+/*
+ * A number: the maximum length of a simple locale name.
+ * (i.e. a name like like en_US, as opposed to a name like
+ * en_US/de_AT/de_AT/es_MX/en_US/en_US) */
+#define _Locale_MAX_SIMPLE_NAME 256
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Typedefs:
+ */
+typedef unsigned short int _Locale_mask_t;
+
+/* Function called during STLport library load phase. Might contain any
+ * code necessary to the platform localization layer.
+ */
+void _Locale_init(void);
+
+/* Function called during STLport library unload. Might contain any
+ * code necessary to the platform localization layer.
+ */
+void _Locale_final(void);
+
+/* Create a category of the locale with the given name.
+ *
+ * The char* argument is a simple (not a composite) locale name, which may
+ * neither be an empty string nor a null pointer.
+ *
+ * These functions return NULL to indicate failure. Failure reason should be reported
+ * using the __err_code pointer.
+ */
+struct _Locale_ctype* _Locale_ctype_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_codecvt* _Locale_codecvt_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_numeric* _Locale_numeric_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_time* _Locale_time_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_collate* _Locale_collate_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_monetary* _Locale_monetary_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_messages* _Locale_messages_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+
+/* Give error reason on failure of one of the _Locale_*_create functions. Available
+ * reasons are:
+ * 0: No specific error reason has been reported.
+ * 1: No platform support for the given facet.
+ * 2: Unknown locale name
+ * 3: No platform API for localization support.
+ * 4: No more memory
+ */
+#define _STLP_LOC_UNDEFINED 0
+#define _STLP_LOC_UNSUPPORTED_FACET_CATEGORY 1
+#define _STLP_LOC_UNKNOWN_NAME 2
+#define _STLP_LOC_NO_PLATFORM_SUPPORT 3
+#define _STLP_LOC_NO_MEMORY 4
+
+/* Release a category of a locale
+ *
+ * These functions are used to release a category acquired with the
+ * according _Locale_*_create() functions.
+ */
+void _Locale_ctype_destroy(struct _Locale_ctype *);
+void _Locale_codecvt_destroy(struct _Locale_codecvt *);
+void _Locale_numeric_destroy(struct _Locale_numeric *);
+void _Locale_time_destroy(struct _Locale_time *);
+void _Locale_collate_destroy(struct _Locale_collate *);
+void _Locale_monetary_destroy(struct _Locale_monetary *);
+void _Locale_messages_destroy(struct _Locale_messages *);
+
+/*
+ * Returns the name of the user's default locale in each
+ * category, as a null-terminated string.  A NULL value
+ * means the default "C" locale.
+ */
+const char * _Locale_ctype_default(char * __buf);
+const char * _Locale_numeric_default(char * __buf);
+const char * _Locale_time_default(char * __buf);
+const char * _Locale_collate_default(char * __buf);
+const char * _Locale_monetary_default(char * __buf);
+const char * _Locale_messages_default(char * __buf);
+
+/* Retrieve the name of the given category
+ *
+ * __buf points to a buffer that can hold at least _Locale_MAX_SIMPLE_NAME
+ * characters.  These functions store the name, as a null-terminated
+ * string, in __buf. This function can't fail, at worst name is truncated.
+ */
+char const* _Locale_ctype_name(const struct _Locale_ctype *, char* __buf);
+char const* _Locale_codecvt_name(const struct _Locale_codecvt *, char* __buf);
+char const* _Locale_numeric_name(const struct _Locale_numeric *, char* __buf);
+char const* _Locale_time_name(const struct _Locale_time *, char* __buf);
+char const* _Locale_collate_name(const struct _Locale_collate *, char*  __buf);
+char const* _Locale_monetary_name(const struct _Locale_monetary *, char* __buf);
+char const* _Locale_messages_name(const struct _Locale_messages *, char* __buf);
+
+/*
+ * cname is a (possibly composite) locale name---i.e. a name that can
+ * be passed to setlocale. __buf points to an array large enough to
+ * store at least _Locale_MAX_SIMPLE_NAME characters, and each of these
+ * functions extracts the name of a single category, stores it in buf
+ * as a null-terminated string, and returns buf.
+ */
+char const* _Locale_extract_ctype_name(const char *cname, char *__buf,
+                                       struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_numeric_name(const char *cname, char *__buf,
+                                         struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_time_name(const char *cname, char *__buf,
+                                      struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_collate_name(const char *cname, char *__buf,
+                                         struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_monetary_name(const char *cname, char *__buf,
+                                          struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_messages_name(const char *cname, char *__buf,
+                                          struct _Locale_name_hint* __hint, int *__err_code);
+
+/* Functions to improve locale creation process. For some locale API (Win32)
+ * you need to find a locale identification from the name which can be a
+ * rather expensive operation especially if you do so for all facets of a
+ * locale. Those functions can be used to extract from a API dependent facet
+ * struct the information necessary to skip this lookup process for other
+ * facets creation. If not supported those function should return NULL.
+ */
+struct _Locale_name_hint* _Locale_get_ctype_hint(struct _Locale_ctype*);
+struct _Locale_name_hint* _Locale_get_numeric_hint(struct _Locale_numeric*);
+struct _Locale_name_hint* _Locale_get_time_hint(struct _Locale_time*);
+struct _Locale_name_hint* _Locale_get_collate_hint(struct _Locale_collate*);
+struct _Locale_name_hint* _Locale_get_monetary_hint(struct _Locale_monetary*);
+struct _Locale_name_hint* _Locale_get_messages_hint(struct _Locale_messages*);
+
+/*
+ * FUNCTIONS THAT USE CTYPE
+ */
+
+/*
+ * Narrow character functions:
+ */
+
+/*
+ * Returns a pointer to the beginning of the ctype table.  The table is
+ * at least 257 bytes long; if p is the pointer returned by this
+ * function, then p[c] is valid if c is EOF or if p is any value of
+ * type unsigned char.
+ */
+const _Locale_mask_t * _Locale_ctype_table(struct _Locale_ctype *);
+
+/*
+ * c is either EOF, or an unsigned char value.
+ */
+int _Locale_toupper(struct _Locale_ctype *, int /* c */);
+int _Locale_tolower(struct _Locale_ctype *, int /* c */);
+
+
+#ifndef _STLP_NO_WCHAR_T
+/*
+ * Wide character functions:
+ */
+_Locale_mask_t _WLocale_ctype(struct _Locale_ctype *, wint_t, _Locale_mask_t);
+wint_t _WLocale_tolower(struct _Locale_ctype *, wint_t);
+wint_t _WLocale_toupper(struct _Locale_ctype *, wint_t);
+
+/*
+ * Multibyte functions:
+ */
+
+/*
+ * Returns the number of bytes of the longest allowed multibyte
+ * character in the current encoding.
+ */
+int _WLocale_mb_cur_max(struct _Locale_codecvt *);
+
+/*
+ * Returns the number of bytes of the shortest allowed multibyte
+ * character in the current encoding.
+ */
+int _WLocale_mb_cur_min(struct _Locale_codecvt *);
+
+/*
+ * Returns 1 if the current multibyte encoding is stateless
+ * and does not require the use of an mbstate_t value.
+ */
+int _WLocale_is_stateless(struct _Locale_codecvt *);
+
+/*
+ * Almost identical to mbrtowc, from 4.6.5.3.2 of NA1.  The only
+ * important difference is that mbrtowc treats null wide characters
+ * as special, and we don't.  Specifically: examines the characters
+ * in [from, from + n), extracts a single wide character, and stores
+ * it in *to.  Modifies shift_state if appropriate.  The return value,
+ * which is always positive, is the number of characters extracted from
+ * the input sequence.  Return value is (size_t) -1 if there was an
+ * encoding error in the input sequence, and (size_t) -2 if
+ * [from, from + n) is correct but not complete.  None of the pointer
+ * arguments may be null pointers.
+ */
+size_t _WLocale_mbtowc(struct _Locale_codecvt *,
+                       wchar_t * /* to */,
+                       const char * /* from */, size_t /* n */,
+                       mbstate_t *);
+
+/*
+ * Again, very similar to wcrtomb.  The differences are that (1) it
+ * doesn't treat null characters as special; and (2) it stores at most
+ * n characters.  Converts c to a multibyte sequence, stores that
+ * sequence in the array 'to', and returns the length of the sequence.
+ * Modifies shift_state if appropriate.  The return value is (size_t) -1
+ * if c is not a valid wide character, and (size_t) -2 if the length of
+ * the multibyte character sequence is greater than n.
+ */
+size_t _WLocale_wctomb(struct _Locale_codecvt *,
+                       char *, size_t,
+                       const wchar_t,
+                       mbstate_t *);
+
+/*
+ * Inserts whatever characters are necessary to restore st to an
+ * initial shift state.  Sets *next to buf + m, where m is the number
+ * of characters inserted.  (0 <= m <= n.)  Returns m to indicate
+ * success, (size_t) -1 to indicate error, (size_t) -2 to indicate
+ * partial success (more than n characters needed).  For success or partial
+ * success, sets *next to buf + m.
+ */
+size_t _WLocale_unshift(struct _Locale_codecvt *,
+                        mbstate_t *,
+                        char *, size_t, char **);
+#endif
+
+/*
+ * FUNCTIONS THAT USE COLLATE
+ */
+
+/*
+ * Compares the two sequences [s1, s1 + n1) and [s2, s2 + n2).  Neither
+ * sequence is assumed to be null-terminated, and null characters
+ * aren't special.  If the two sequences are the same up through
+ * min(n1, n2), then the sequence that compares less is whichever one
+ * is shorter.
+ */
+int _Locale_strcmp(struct _Locale_collate *,
+                   const char * /* s1 */, size_t /* n1 */,
+                   const char * /* s2 */, size_t /* n2 */);
+#ifndef _STLP_NO_WCHAR_T
+int _WLocale_strcmp(struct _Locale_collate *,
+                    const wchar_t * /* s1 */, size_t /* n1 */,
+                    const wchar_t * /* s2 */, size_t /* n2 */);
+#endif
+
+/*
+ * Creates a transformed version of the string [s2, s2 + n2).  The
+ * string may contain embedded null characters; nulls aren't special.
+ * The transformed string begins at s1, and contains at most n1
+ * characters.  The return value is the length of the transformed
+ * string.  If the return value is greater than n1 then this is an
+ * error condition: it indicates that there wasn't enough space.  In
+ * that case, the contents of [s1, s1 + n1) is unspecified.
+*/
+size_t _Locale_strxfrm(struct _Locale_collate *,
+                       char * /* s1 */, size_t /* n1 */,
+                       const char * /* s2 */, size_t /* n2 */);
+
+#ifndef _STLP_NO_WCHAR_T
+size_t _WLocale_strxfrm(struct _Locale_collate *,
+                        wchar_t * /* s1 */, size_t /* n1 */,
+                        const wchar_t * /* s2 */, size_t /* n2 */);
+#endif
+
+
+/*
+ * FUNCTIONS THAT USE NUMERIC
+ */
+
+/*
+ * Equivalent to the first three fields in struct lconv.  (C standard,
+ * section 7.4.)
+ */
+char _Locale_decimal_point(struct _Locale_numeric *);
+char _Locale_thousands_sep(struct _Locale_numeric *);
+const char * _Locale_grouping(struct _Locale_numeric *);
+
+#ifndef _STLP_NO_WCHAR_T
+wchar_t _WLocale_decimal_point(struct _Locale_numeric *);
+wchar_t _WLocale_thousands_sep(struct _Locale_numeric *);
+#endif
+
+/*
+ * Return "true" and "false" in English locales, and something
+ * appropriate in non-English locales.
+ */
+const char * _Locale_true(struct _Locale_numeric *);
+const char * _Locale_false(struct _Locale_numeric *);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_true(struct _Locale_numeric *, wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_false(struct _Locale_numeric *, wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+/*
+ * FUNCTIONS THAT USE MONETARY
+ */
+
+/*
+ * Return the obvious fields of struct lconv.
+ */
+const char * _Locale_int_curr_symbol(struct _Locale_monetary *);
+const char * _Locale_currency_symbol(struct _Locale_monetary *);
+char         _Locale_mon_decimal_point(struct _Locale_monetary *);
+char         _Locale_mon_thousands_sep(struct _Locale_monetary *);
+const char * _Locale_mon_grouping(struct _Locale_monetary *);
+const char * _Locale_positive_sign(struct _Locale_monetary *);
+const char * _Locale_negative_sign(struct _Locale_monetary *);
+char         _Locale_int_frac_digits(struct _Locale_monetary *);
+char         _Locale_frac_digits(struct _Locale_monetary *);
+int          _Locale_p_cs_precedes(struct _Locale_monetary *);
+int          _Locale_p_sep_by_space(struct _Locale_monetary *);
+int          _Locale_p_sign_posn(struct _Locale_monetary *);
+int          _Locale_n_cs_precedes(struct _Locale_monetary *);
+int          _Locale_n_sep_by_space(struct _Locale_monetary *);
+int          _Locale_n_sign_posn(struct _Locale_monetary *);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_int_curr_symbol(struct _Locale_monetary *, wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_currency_symbol(struct _Locale_monetary *, wchar_t* /* buf */, size_t /* bufSize */);
+wchar_t         _WLocale_mon_decimal_point(struct _Locale_monetary *);
+wchar_t         _WLocale_mon_thousands_sep(struct _Locale_monetary *);
+const wchar_t * _WLocale_positive_sign(struct _Locale_monetary *, wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_negative_sign(struct _Locale_monetary *, wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+/*
+ * FUNCTIONS THAT USE TIME
+ */
+
+/*
+ * month is in the range [0, 12).
+ */
+const char * _Locale_full_monthname(struct _Locale_time *, int /* month */);
+const char * _Locale_abbrev_monthname(struct _Locale_time *, int /* month */);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_full_monthname(struct _Locale_time *, int /* month */,
+                                        wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_abbrev_monthname(struct _Locale_time *, int /* month */,
+                                          wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+/*
+ * day is in the range [0, 7).  Sunday is 0.
+ */
+const char * _Locale_full_dayofweek(struct _Locale_time *, int /* day */);
+const char * _Locale_abbrev_dayofweek(struct _Locale_time *, int /* day */);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_full_dayofweek(struct _Locale_time *, int /* day */,
+                                        wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_abbrev_dayofweek(struct _Locale_time *, int /* day */,
+                                          wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+const char * _Locale_d_t_fmt(struct _Locale_time *);
+const char * _Locale_d_fmt(struct _Locale_time *);
+const char * _Locale_t_fmt(struct _Locale_time *);
+const char * _Locale_long_d_t_fmt(struct _Locale_time*);
+const char * _Locale_long_d_fmt(struct _Locale_time*);
+
+const char * _Locale_am_str(struct _Locale_time *);
+const char * _Locale_pm_str(struct _Locale_time *);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_am_str(struct _Locale_time *,
+                                wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_pm_str(struct _Locale_time *,
+                                wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+/*
+ * FUNCTIONS THAT USE MESSAGES
+ */
+
+/*
+ * Very similar to catopen, except that it uses the given message
+ * category to determine which catalog to open.
+ */
+nl_catd_type _Locale_catopen(struct _Locale_messages*, const char*);
+
+/* Complementary to _Locale_catopen.
+ * The catalog must be a value that was returned by a previous call
+ * to _Locale_catopen.
+ */
+void _Locale_catclose(struct _Locale_messages*, nl_catd_type);
+
+/*
+ * Returns a string, identified by a set index and a message index,
+ * from an opened message catalog.  Returns the supplied default if
+ * no such string exists.
+ */
+const char * _Locale_catgets(struct _Locale_messages *, nl_catd_type,
+                             int, int,const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STLP_C_LOCALE_IMPL_H */
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale_dummy/c_locale_dummy.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+/* This is a "stub" implementation of the "c_locale.h" interface,
+   intended for operating systems where we have not yet written
+   a real implementation.  A C++ library using this stub implementation
+   is still standard-conforming, since the C++ standard does not require
+   that any locales other than "C" be supported.
+*/
+
+#include <string.h>
+#include <wchar.h>
+#include <ctype.h>
+#include <wctype.h>
+#include <limits.h>
+
+#if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
+#  define _STLP_STRNCPY(D, DS, S, C) strncpy_s(D, DS, S, C)
+#  if !defined (_STLP_NO_WCHAR_T)
+#    define _STLP_WCSNCPY(D, DS, S, C) wcsncpy_s(D, DS, S, C)
+#  endif
+#else
+#  define _STLP_STRNCPY(D, DS, S, C) strncpy(D, S, C)
+#  if !defined (_STLP_NO_WCHAR_T)
+#    define _STLP_WCSNCPY(D, DS, S, C) wcsncpy(D, S, C)
+#  endif
+#endif
+
+static const char *_C_name = "C";
+static const char *_empty_str = "";
+#ifndef _STLP_NO_WCHAR_T
+#if defined(WCHAR_MAX) && WCHAR_MAX == 255
+static const wchar_t *_empty_wstr = "";
+#else
+static const wchar_t *_empty_wstr = L"";
+#endif
+#endif
+
+static _Locale_mask_t ctable[256];
+
+/* Framework functions */
+
+void _Locale_init(void) {
+  /* Ctype table for the ASCII character set. */
+  char c;
+  /* We might never reach 128 when char is signed. */
+  for (c = 0; /* c != 128 */; ++c) {
+    if (isalpha(c)) ctable[(unsigned char)c] |= _Locale_ALPHA;
+    if (iscntrl(c)) ctable[(unsigned char)c] |= _Locale_CNTRL;
+    if (isdigit(c)) ctable[(unsigned char)c] |= _Locale_DIGIT;
+    if (isprint(c)) ctable[(unsigned char)c] |= _Locale_PRINT;
+    if (ispunct(c)) ctable[(unsigned char)c] |= _Locale_PUNCT;
+    if (isspace(c)) ctable[(unsigned char)c] |= _Locale_SPACE;
+    if (isxdigit(c)) ctable[(unsigned char)c] |= _Locale_XDIGIT;
+    if (isupper(c)) ctable[(unsigned char)c] |= _Locale_UPPER;
+    if (islower(c)) ctable[(unsigned char)c] |= _Locale_LOWER;
+    if (c == 127) break;
+  }
+
+  /* ASCII is a 7-bit code, so everything else is non-ASCII. */
+  memset(&(ctable[128]), 0, 128 * sizeof(_Locale_mask_t));
+}
+
+void _Locale_final(void)
+{}
+
+void* _Locale_create(const char* name, int *__err_code) {
+  if (name[0] == 'C' && name[1] == 0)
+  { return (void*)0x1; }
+  *__err_code = _STLP_LOC_NO_PLATFORM_SUPPORT; return 0;
+}
+
+struct _Locale_ctype* _Locale_ctype_create(const char *name,
+                                           struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_ctype*)_Locale_create(name, __err_code); }
+
+struct _Locale_codecvt* _Locale_codecvt_create(const char *name,
+                                               struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_codecvt*)_Locale_create(name, __err_code); }
+
+struct _Locale_numeric* _Locale_numeric_create(const char *name,
+                                               struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_numeric*)_Locale_create(name, __err_code); }
+
+struct _Locale_time* _Locale_time_create(const char *name,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_time*)_Locale_create(name, __err_code); }
+
+struct _Locale_collate* _Locale_collate_create(const char *name,
+                                               struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_collate*)_Locale_create(name, __err_code); }
+
+struct _Locale_monetary* _Locale_monetary_create(const char *name,
+                                                 struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_monetary*)_Locale_create(name, __err_code); }
+
+struct _Locale_messages* _Locale_messages_create(const char *name,
+                                                 struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_messages*)_Locale_create(name, __err_code); }
+
+const char *_Locale_ctype_default(char* buf)    { return _C_name; }
+const char *_Locale_numeric_default(char * buf) { return _C_name; }
+const char *_Locale_time_default(char* buf)     { return _C_name; }
+const char *_Locale_collate_default(char* buf)  { return _C_name; }
+const char *_Locale_monetary_default(char* buf) { return _C_name; }
+const char *_Locale_messages_default(char* buf) { return _C_name; }
+
+char const* _Locale_ctype_name(const struct _Locale_ctype *lctype, char* buf)
+{ return _C_name; }
+
+char const* _Locale_codecvt_name(const struct _Locale_codecvt *lcodecvt, char* buf)
+{ return _C_name; }
+
+char const* _Locale_numeric_name(const struct _Locale_numeric *lnum, char* buf)
+{ return _C_name; }
+
+char const* _Locale_time_name(const struct _Locale_time *ltime, char* buf)
+{ return _C_name; }
+
+char const* _Locale_collate_name(const struct _Locale_collate *lcol, char* buf)
+{ return _C_name; }
+
+char const* _Locale_monetary_name(const struct _Locale_monetary *lmon, char* buf)
+{ return _C_name; }
+
+char const* _Locale_messages_name(const struct _Locale_messages *lmes, char* buf)
+{ return _C_name; }
+
+void _Locale_ctype_destroy(struct _Locale_ctype *lctype)     {}
+void _Locale_codecvt_destroy(struct _Locale_codecvt *lcodecvt)   {}
+void _Locale_numeric_destroy(struct _Locale_numeric *lnum)   {}
+void _Locale_time_destroy(struct _Locale_time *ltime)        {}
+void _Locale_collate_destroy(struct _Locale_collate *lcol)   {}
+void _Locale_monetary_destroy(struct _Locale_monetary *lmon) {}
+void _Locale_messages_destroy(struct _Locale_messages *lmes) {}
+
+static char const* _Locale_extract_name(const char* name, int *__err_code) {
+  // When the request is the default locale or the "C" locale we answer "C".
+  if (name[0] == 0 ||
+      (name[0] == 'C' && name[1] == 0))
+  {  return _C_name; }
+  *__err_code = _STLP_LOC_NO_PLATFORM_SUPPORT; return 0;
+}
+
+char const* _Locale_extract_ctype_name(const char *name, char *buf,
+                                       struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_numeric_name(const char *name, char *buf,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_time_name(const char*name, char *buf,
+                                      struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_collate_name(const char *name, char *buf,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_monetary_name(const char *name, char *buf,
+                                          struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_messages_name(const char *name, char *buf,
+                                          struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+struct _Locale_name_hint* _Locale_get_ctype_hint(struct _Locale_ctype* ctype)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_numeric_hint(struct _Locale_numeric* numeric)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_time_hint(struct _Locale_time* time)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_collate_hint(struct _Locale_collate* collate)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_monetary_hint(struct _Locale_monetary* monetary)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_messages_hint(struct _Locale_messages* messages)
+{ return 0; }
+
+/* ctype */
+const _Locale_mask_t* _Locale_ctype_table(struct _Locale_ctype* lctype) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lctype)
+  return ctable;
+}
+
+int _Locale_toupper(struct _Locale_ctype*lctype, int c)
+{ return toupper(c); }
+
+int _Locale_tolower(struct _Locale_ctype*lctype, int c)
+{ return tolower(c); }
+
+#ifndef _STLP_NO_WCHAR_T
+_Locale_mask_t _WLocale_ctype(struct _Locale_ctype *lctype, wint_t wc, _Locale_mask_t mask) {
+  _Locale_mask_t ret = 0;
+  if ((mask & _Locale_ALPHA) != 0 && iswalpha(wc))
+    ret |= _Locale_ALPHA;
+
+  if ((mask & _Locale_CNTRL) != 0 && iswcntrl(wc))
+    ret |= _Locale_CNTRL;
+
+  if ((mask & _Locale_DIGIT) != 0 && iswdigit(wc))
+    ret |= _Locale_DIGIT;
+
+  if ((mask & _Locale_PRINT) != 0 && iswprint(wc))
+    ret |= _Locale_PRINT;
+
+  if ((mask & _Locale_PUNCT) != 0 && iswpunct(wc))
+    ret |= _Locale_PUNCT;
+
+  if ((mask & _Locale_SPACE) != 0 && iswspace(wc))
+    ret |= _Locale_SPACE;
+
+  if ((mask & _Locale_XDIGIT) != 0 && iswxdigit(wc))
+    ret |= _Locale_XDIGIT;
+
+  if ((mask & _Locale_UPPER) != 0 && iswupper(wc))
+    ret |= _Locale_UPPER;
+
+  if ((mask & _Locale_LOWER) != 0 && iswlower(wc))
+    ret |= _Locale_LOWER;
+
+  return ret;
+}
+
+wint_t _WLocale_tolower(struct _Locale_ctype *lctype, wint_t wc)
+{ return towlower(wc); }
+
+wint_t _WLocale_toupper(struct _Locale_ctype *lctype, wint_t wc)
+{ return towupper(wc); }
+
+int _WLocale_mb_cur_max (struct _Locale_codecvt *lcodecvt) { return 1; }
+int _WLocale_mb_cur_min (struct _Locale_codecvt *lcodecvt) { return 1; }
+int _WLocale_is_stateless (struct _Locale_codecvt *lcodecvt) { return 1; }
+
+size_t _WLocale_mbtowc(struct _Locale_codecvt *lcodecvt,
+                       wchar_t *to,
+                       const char *from, size_t n,
+                       mbstate_t *st)
+{ *to = *from; return 1; }
+
+size_t _WLocale_wctomb(struct _Locale_codecvt *lcodecvt,
+                       char *to, size_t n,
+                       const wchar_t c,
+                       mbstate_t *st)
+{ *to = (char)c; return 1; }
+
+size_t _WLocale_unshift(struct _Locale_codecvt *lcodecvt,
+                        mbstate_t *st,
+                        char *buf, size_t n, char ** next)
+{ *next = buf; return 0; }
+#endif
+
+/* Collate */
+ int _Locale_strcmp(struct _Locale_collate* lcol,
+                    const char* s1, size_t n1, const char* s2, size_t n2) {
+  int ret = 0;
+  char buf1[64], buf2[64];
+  while (n1 > 0 || n2 > 0) {
+    size_t bufsize1 = n1 < 63 ? n1 : 63;
+    size_t bufsize2 = n2 < 63 ? n2 : 63;
+    _STLP_STRNCPY(buf1, 64, s1, bufsize1); buf1[bufsize1] = 0;
+    _STLP_STRNCPY(buf2, 64, s2, bufsize2); buf2[bufsize2] = 0;
+
+    ret = strcmp(buf1, buf2);
+    if (ret != 0) return ret < 0 ? -1 : 1;
+    s1 += bufsize1; n1 -= bufsize1;
+    s2 += bufsize2; n2 -= bufsize2;
+  }
+  return ret == 0 ? 0 : (ret < 0 ? -1 : 1);
+}
+
+#ifndef _STLP_NO_WCHAR_T
+
+int _WLocale_strcmp(struct _Locale_collate* lcol,
+                    const wchar_t* s1, size_t n1, const wchar_t* s2, size_t n2) {
+  int ret = 0;
+  wchar_t buf1[64], buf2[64];
+  while (n1 > 0 || n2 > 0) {
+    size_t bufsize1 = n1 < 63 ? n1 : 63;
+    size_t bufsize2 = n2 < 63 ? n2 : 63;
+    _STLP_WCSNCPY(buf1, 64, s1, bufsize1); buf1[bufsize1] = 0;
+    _STLP_WCSNCPY(buf2, 64, s2, bufsize2); buf2[bufsize2] = 0;
+
+    ret = wcscmp(buf1, buf2);
+    if (ret != 0) return ret < 0 ? -1 : 1;
+    s1 += bufsize1; n1 -= bufsize1;
+    s2 += bufsize2; n2 -= bufsize2;
+  }
+  return ret == 0 ? 0 : (ret < 0 ? -1 : 1);
+}
+
+#endif
+
+size_t _Locale_strxfrm(struct _Locale_collate* lcol,
+                       char* dest, size_t dest_n,
+                       const char* src, size_t src_n) {
+  if (dest != 0) {
+    _STLP_STRNCPY(dest, dest_n, src, dest_n - 1); dest[dest_n - 1] = 0;
+  }
+  return src_n;
+}
+
+#ifndef _STLP_NO_WCHAR_T
+
+size_t _WLocale_strxfrm(struct _Locale_collate* lcol,
+                        wchar_t* dest, size_t dest_n,
+                        const wchar_t* src, size_t src_n) {
+  if (dest != 0) {
+    _STLP_WCSNCPY(dest, dest_n, src, dest_n - 1); dest[dest_n - 1] = 0;
+  }
+  return src_n;
+}
+
+#endif
+
+/* Numeric */
+
+char _Locale_decimal_point(struct _Locale_numeric* lnum)
+{ return '.'; }
+char _Locale_thousands_sep(struct _Locale_numeric* lnum)
+{ return ','; }
+const char* _Locale_grouping(struct _Locale_numeric * lnum)
+{ return _empty_str; }
+const char * _Locale_true(struct _Locale_numeric * lnum)
+{ return "true"; }
+const char * _Locale_false(struct _Locale_numeric * lnum)
+{ return "false"; }
+
+#ifndef _STLP_NO_WCHAR_T
+wchar_t _WLocale_decimal_point(struct _Locale_numeric* lnum)
+{ return L'.'; }
+wchar_t _WLocale_thousands_sep(struct _Locale_numeric* lnum)
+{ return L','; }
+#if defined(WCHAR_MAX) && WCHAR_MAX == 255
+const wchar_t * _WLocale_true(struct _Locale_numeric* lnum, wchar_t* buf, size_t bufSize)
+{ return "true"; }
+const wchar_t * _WLocale_false(struct _Locale_numeric* lnum, wchar_t* buf, size_t bufSize)
+{ return "false"; }
+#else
+const wchar_t * _WLocale_true(struct _Locale_numeric* lnum, wchar_t* buf, size_t bufSize)
+{ return L"true"; }
+const wchar_t * _WLocale_false(struct _Locale_numeric* lnum, wchar_t* buf, size_t bufSize)
+{ return L"false"; }
+#endif
+#endif
+
+/* Monetary */
+
+const char* _Locale_int_curr_symbol(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+const char* _Locale_currency_symbol(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+char        _Locale_mon_decimal_point(struct _Locale_monetary * lmon)
+{ return '.'; }
+char        _Locale_mon_thousands_sep(struct _Locale_monetary * lmon)
+{ return ','; }
+const char* _Locale_mon_grouping(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+const char* _Locale_positive_sign(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+const char* _Locale_negative_sign(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+char        _Locale_int_frac_digits(struct _Locale_monetary * lmon)
+{ return 0; }
+char        _Locale_frac_digits(struct _Locale_monetary * lmon)
+{ return 0; }
+int         _Locale_p_cs_precedes(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int         _Locale_p_sep_by_space(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int         _Locale_p_sign_posn(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int         _Locale_n_cs_precedes(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int          _Locale_n_sep_by_space(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int          _Locale_n_sign_posn(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t* _WLocale_int_curr_symbol(struct _Locale_monetary * lmon,
+                                        wchar_t* buf, size_t bufSize)
+{ return _empty_wstr; }
+const wchar_t* _WLocale_currency_symbol(struct _Locale_monetary * lmon,
+                                        wchar_t* buf, size_t bufSize)
+{ return _empty_wstr; }
+wchar_t        _WLocale_mon_decimal_point(struct _Locale_monetary * lmon)
+{ return L'.'; }
+wchar_t        _WLocale_mon_thousands_sep(struct _Locale_monetary * lmon)
+{ return L','; }
+const wchar_t* _WLocale_positive_sign(struct _Locale_monetary * lmon,
+                                      wchar_t* buf, size_t bufSize)
+{ return _empty_wstr; }
+const wchar_t* _WLocale_negative_sign(struct _Locale_monetary * lmon,
+                                      wchar_t* buf, size_t bufSize)
+{ return _empty_wstr; }
+#endif
+
+/* Time */
+static const char* full_monthname[] =
+{ "January", "February", "March", "April", "May", "June",
+  "July", "August", "September", "October", "November", "December" };
+const char * _Locale_full_monthname(struct _Locale_time * ltime, int n)
+{ return full_monthname[n]; }
+
+static const char* abbrev_monthname[] =
+{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+const char * _Locale_abbrev_monthname(struct _Locale_time * ltime, int n)
+{ return abbrev_monthname[n]; }
+
+static const char* full_dayname[] =
+{ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
+const char * _Locale_full_dayofweek(struct _Locale_time * ltime, int n)
+{ return full_dayname[n]; }
+
+static const char* abbrev_dayname[] =
+{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+const char * _Locale_abbrev_dayofweek(struct _Locale_time * ltime, int n)
+{ return abbrev_dayname[n]; }
+
+const char* _Locale_d_t_fmt(struct _Locale_time* ltime)
+{ return "%m/%d/%y"; }
+const char* _Locale_d_fmt(struct _Locale_time* ltime)
+{ return "%m/%d/%y"; }
+const char* _Locale_t_fmt(struct _Locale_time* ltime)
+{ return "%H:%M:%S"; }
+const char* _Locale_long_d_t_fmt(struct _Locale_time* ltime)
+{ return _empty_str; }
+const char* _Locale_long_d_fmt(struct _Locale_time* ltime)
+{ return _empty_str; }
+const char* _Locale_am_str(struct _Locale_time* ltime)
+{ return "AM"; }
+const char* _Locale_pm_str(struct _Locale_time* ltime)
+{ return "PM"; }
+
+#ifndef _STLP_NO_WCHAR_T
+#if defined(WCHAR_MAX) && WCHAR_MAX == 255
+static const wchar_t* full_wmonthname[] =
+{ "January", "February", "March", "April", "May", "June",
+  "July", "August", "September", "October", "November", "December" };
+const wchar_t * _WLocale_full_monthname(struct _Locale_time * ltime, int n,
+                                        wchar_t* buf, size_t bufSize)
+{ return full_wmonthname[n]; }
+
+static const wchar_t* abbrev_wmonthname[] =
+{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+const wchar_t * _WLocale_abbrev_monthname(struct _Locale_time * ltime, int n,
+                                          wchar_t* buf, size_t bufSize)
+{ return abbrev_wmonthname[n]; }
+
+static const wchar_t* full_wdayname[] =
+{ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
+const wchar_t * _WLocale_full_dayofweek(struct _Locale_time * ltime, int n,
+                                        wchar_t* buf, size_t bufSize)
+{ return full_wdayname[n]; }
+
+static const wchar_t* abbrev_wdayname[] =
+{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+const wchar_t * _WLocale_abbrev_dayofweek(struct _Locale_time * ltime, int n,
+                                          wchar_t* buf, size_t bufSize)
+{ return abbrev_wdayname[n]; }
+
+const wchar_t* _WLocale_am_str(struct _Locale_time* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ return "AM"; }
+const wchar_t* _WLocale_pm_str(struct _Locale_time* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ return "PM"; }
+#else /* WCHAR_MAX != 255 */
+static const wchar_t* full_wmonthname[] =
+{ L"January", L"February", L"March", L"April", L"May", L"June",
+  L"July", L"August", L"September", L"October", L"November", L"December" };
+const wchar_t * _WLocale_full_monthname(struct _Locale_time * ltime, int n,
+                                        wchar_t* buf, size_t bufSize)
+{ return full_wmonthname[n]; }
+
+static const wchar_t* abbrev_wmonthname[] =
+{ L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun",
+  L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec" };
+const wchar_t * _WLocale_abbrev_monthname(struct _Locale_time * ltime, int n,
+                                          wchar_t* buf, size_t bufSize)
+{ return abbrev_wmonthname[n]; }
+
+static const wchar_t* full_wdayname[] =
+{ L"Sunday", L"Monday", L"Tuesday", L"Wednesday", L"Thursday", L"Friday", L"Saturday" };
+const wchar_t * _WLocale_full_dayofweek(struct _Locale_time * ltime, int n,
+                                        wchar_t* buf, size_t bufSize)
+{ return full_wdayname[n]; }
+
+static const wchar_t* abbrev_wdayname[] =
+{ L"Sun", L"Mon", L"Tue", L"Wed", L"Thu", L"Fri", L"Sat" };
+const wchar_t * _WLocale_abbrev_dayofweek(struct _Locale_time * ltime, int n,
+                                          wchar_t* buf, size_t bufSize)
+{ return abbrev_wdayname[n]; }
+
+const wchar_t* _WLocale_am_str(struct _Locale_time* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ return L"AM"; }
+const wchar_t* _WLocale_pm_str(struct _Locale_time* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ return L"PM"; }
+#endif /* WCHAR_MAX != 255 */
+#endif
+
+/* Messages */
+
+nl_catd_type _Locale_catopen(struct _Locale_messages* lmes, const char* name)
+{ return -1; }
+void _Locale_catclose(struct _Locale_messages* lmes, nl_catd_type cat) {}
+const char* _Locale_catgets(struct _Locale_messages* lmes, nl_catd_type cat,
+                            int setid, int msgid, const char *dfault)
+{ return dfault; }
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale_glibc/c_locale_glibc2.c
@@ -0,0 +1,705 @@
+#include <locale.h>
+#include <langinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wctype.h>
+#include <string.h>
+#include <stdint.h>
+
+static const char *_empty_str = "";
+static const char *_C_name = "C";
+
+static wchar_t* _ToWChar(const char* buf, wchar_t *wbuf, size_t wbufSize) {
+  wchar_t *wcur = wbuf;
+  wchar_t *wend = wbuf + wbufSize - 1;
+  for (; wcur != wend && *buf != 0; ++buf, ++wcur)
+    *wcur = *buf;
+  *wcur = 0;
+  return wbuf;
+}
+
+#if 0
+struct _Locale_ctype
+{
+  locale_t __cloc;
+};
+
+struct _Locale_numeric
+{
+  locale_t __cloc;
+};
+
+struct _Locale_time
+{
+  locale_t __cloc;
+};
+
+struct _Locale_collate
+{
+  locale_t __cloc;
+};
+
+struct _Locale_monetary
+{
+  locale_t __cloc;
+};
+
+struct _Locale_messages
+{
+  locale_t __cloc;
+};
+#endif
+
+void _Locale_init()
+{}
+
+void _Locale_final()
+{}
+
+struct _Locale_ctype *_Locale_ctype_create(const char *nm, struct _Locale_name_hint* hint,
+                                           int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_ctype*)newlocale(LC_CTYPE_MASK, nm, NULL);
+}
+
+struct _Locale_codecvt *_Locale_codecvt_create(const char *nm, struct _Locale_name_hint* hint,
+                                               int *__err_code) {
+  // Glibc do not support multibyte manipulation for the moment, it simply implements "C".
+  if (nm[0] == 'C' && nm[1] == 0)
+  { return (struct _Locale_codecvt*)0x01; }
+  *__err_code = _STLP_LOC_NO_PLATFORM_SUPPORT; return 0;
+}
+
+struct _Locale_numeric *_Locale_numeric_create(const char *nm, struct _Locale_name_hint* hint,
+                                               int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_numeric*)newlocale(LC_NUMERIC_MASK, nm, NULL);
+}
+  
+struct _Locale_time *_Locale_time_create(const char *nm, struct _Locale_name_hint* hint,
+                                         int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_time*)newlocale(LC_TIME_MASK, nm, NULL);
+}
+
+struct _Locale_collate *_Locale_collate_create(const char *nm, struct _Locale_name_hint* hint,
+                                               int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_collate*)newlocale(LC_COLLATE_MASK, nm, NULL);
+}
+
+struct _Locale_monetary *_Locale_monetary_create(const char *nm, struct _Locale_name_hint* hint,
+                                                 int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_monetary*)newlocale(LC_MONETARY_MASK, nm, NULL);
+}
+
+struct _Locale_messages *_Locale_messages_create(const char *nm, struct _Locale_name_hint* hint,
+                                                 int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_messages*)newlocale(LC_MESSAGES_MASK, nm, NULL);
+}
+
+/*
+  try to see locale category LC should be used from environment;
+  according POSIX, the order is
+  1. LC_ALL
+  2. category (LC_CTYPE, LC_NUMERIC, ... )
+  3. LANG
+  If set nothing, return "C" (this really implementation-specific).
+*/
+static const char *_Locale_aux_default( const char *LC, char *nm )
+{
+  char *name = getenv( "LC_ALL" );
+
+  if ( name != NULL && *name != 0 ) {
+    return name;
+  }
+  name = getenv( LC );
+  if ( name != NULL && *name != 0 ) {
+    return name;
+  }
+  name = getenv( "LANG" );
+  if ( name != NULL && *name != 0 ) {
+    return name;
+  }
+
+  return _C_name;
+}
+
+const char *_Locale_ctype_default( char *nm )
+{
+  return _Locale_aux_default( "LC_CTYPE", nm );
+}
+
+const char *_Locale_numeric_default( char *nm )
+{
+  return _Locale_aux_default( "LC_NUMERIC", nm );
+}
+
+const char *_Locale_time_default( char *nm )
+{
+  return _Locale_aux_default( "LC_TIME", nm );
+}
+
+const char *_Locale_collate_default( char *nm )
+{
+  return _Locale_aux_default( "LC_COLLATE", nm );
+}
+
+const char *_Locale_monetary_default( char *nm )
+{
+  return _Locale_aux_default( "LC_MONETARY", nm );
+}
+
+const char *_Locale_messages_default( char *nm )
+{
+  return _Locale_aux_default( "LC_MESSAGES", nm );
+}
+
+char const*_Locale_ctype_name( const struct _Locale_ctype *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_CTYPE];
+}
+
+char const*_Locale_codecvt_name( const struct _Locale_codecvt *__loc, char *buf )
+{
+  return _C_name;
+}
+
+char const*_Locale_numeric_name( const struct _Locale_numeric *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_NUMERIC];
+}
+
+char const*_Locale_time_name( const struct _Locale_time *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_TIME];
+}
+
+char const*_Locale_collate_name( const struct _Locale_collate *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_COLLATE];
+}
+
+char const*_Locale_monetary_name( const struct _Locale_monetary *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_MONETARY];
+}
+
+char const*_Locale_messages_name( const struct _Locale_messages *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_MESSAGES];
+}
+
+void _Locale_ctype_destroy( struct _Locale_ctype *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_codecvt_destroy( struct _Locale_codecvt *__loc )
+{}
+
+void _Locale_numeric_destroy( struct _Locale_numeric *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_time_destroy( struct _Locale_time *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_collate_destroy( struct _Locale_collate *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_monetary_destroy( struct _Locale_monetary *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_messages_destroy( struct _Locale_messages* __loc )
+{ freelocale((locale_t)__loc); }
+
+/*
+ * locale loc expected either locale name indeed (platform-specific)
+ * or string like "LC_CTYPE=LocaleNameForCType;LC_NUMERIC=LocaleNameForNum;"
+ *
+ */
+
+static char const*__Extract_locale_name( const char *loc, const char *category, char *buf )
+{
+  char *expr;
+  size_t len_name;
+
+  if( loc[0]=='L' && loc[1]=='C' && loc[2]=='_') {
+    expr = strstr( (char*)loc, category );
+    if ( expr == NULL )
+      return NULL; /* Category not found. */
+    ++expr;
+    len_name = strcspn( expr, ";" );
+    len_name = len_name >= _Locale_MAX_SIMPLE_NAME ? _Locale_MAX_SIMPLE_NAME - 1 : len_name;
+    strncpy( buf, expr, len_name );
+    buf[len_name] = 0;
+    return buf;
+  }
+  return loc;
+}
+
+char const*_Locale_extract_ctype_name(const char *loc, char *buf,
+                                      struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_CTYPE=", buf ); }
+
+char const*_Locale_extract_numeric_name(const char *loc, char *buf,
+                                        struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_NUMERIC=", buf ); }
+
+char const*_Locale_extract_time_name(const char *loc, char *buf,
+                                     struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_TIME=", buf ); }
+
+char const*_Locale_extract_collate_name(const char *loc, char *buf,
+                                        struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_COLLATE=", buf ); }
+
+char const*_Locale_extract_monetary_name(const char *loc, char *buf,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_MONETARY=", buf ); }
+
+char const*_Locale_extract_messages_name(const char *loc, char *buf,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_MESSAGES=", buf ); }
+
+struct _Locale_name_hint* _Locale_get_ctype_hint(struct _Locale_ctype* ctype)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_numeric_hint(struct _Locale_numeric* numeric)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_time_hint(struct _Locale_time* time)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_collate_hint(struct _Locale_collate* collate)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_monetary_hint(struct _Locale_monetary* monetary)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_messages_hint(struct _Locale_messages* messages)
+{ return 0; }
+
+/* ctype */
+
+const _Locale_mask_t *_Locale_ctype_table( struct _Locale_ctype *__loc )
+{
+  /* return table with masks (upper, lower, alpha, etc.) */
+  _STLP_STATIC_ASSERT( sizeof(_Locale_mask_t) == sizeof(((locale_t)__loc)->__ctype_b[0]) )
+  return ((locale_t)__loc)->__ctype_b;
+}
+
+int _Locale_toupper( struct _Locale_ctype *__loc, int c )
+{ return ((locale_t)__loc)->__ctype_toupper[c]; }
+
+int _Locale_tolower( struct _Locale_ctype *__loc, int c )
+{ return ((locale_t)__loc)->__ctype_tolower[c]; }
+
+#if !defined (_STLP_NO_WCHAR_T)
+_Locale_mask_t _WLocale_ctype( struct _Locale_ctype *__loc, wint_t wc, _Locale_mask_t __mask )
+{
+  _Locale_mask_t ret = 0;
+  if ((__mask & _Locale_ALPHA) != 0 && iswalpha_l(wc, (locale_t)__loc))
+    ret |= _Locale_ALPHA;
+  
+  if ((__mask & _Locale_CNTRL) != 0 && iswcntrl_l(wc, (locale_t)__loc))
+    ret |= _Locale_CNTRL;
+
+  if ((__mask & _Locale_DIGIT) != 0 && iswdigit_l(wc, (locale_t)__loc))
+    ret |= _Locale_DIGIT;
+
+  if ((__mask & _Locale_PRINT) != 0 && iswprint_l(wc, (locale_t)__loc)) 
+    ret |= _Locale_PRINT;
+
+  if ((__mask & _Locale_PUNCT) != 0 && iswpunct_l(wc, (locale_t)__loc))
+    ret |= _Locale_PUNCT;
+
+  if ((__mask & _Locale_SPACE) != 0 && iswspace_l(wc, (locale_t)__loc))
+    ret |= _Locale_SPACE;
+
+  if ((__mask & _Locale_XDIGIT) != 0 && iswxdigit_l(wc, (locale_t)__loc))
+    ret |= _Locale_XDIGIT;
+
+  if ((__mask & _Locale_UPPER) != 0 && iswupper_l(wc, (locale_t)__loc))
+    ret |= _Locale_UPPER;
+
+  if ((__mask & _Locale_LOWER) != 0 && iswlower_l(wc, (locale_t)__loc))
+    ret |= _Locale_LOWER;
+
+  return ret;
+}
+
+wint_t _WLocale_tolower( struct _Locale_ctype *__loc, wint_t c )
+{
+  return towlower_l( c, ((locale_t)__loc) );
+}
+
+wint_t _WLocale_toupper( struct _Locale_ctype *__loc, wint_t c )
+{
+  return towupper_l( c, ((locale_t)__loc) );
+}
+#endif
+
+int _WLocale_mb_cur_max( struct _Locale_codecvt * lcodecvt) { return 1; }
+int _WLocale_mb_cur_min( struct _Locale_codecvt * lcodecvt) { return 1; }
+int _WLocale_is_stateless( struct _Locale_codecvt * lcodecvt) { return 1; }
+
+#if !defined (_STLP_NO_WCHAR_T)
+size_t _WLocale_mbtowc(struct _Locale_codecvt *lcodecvt,
+                       wchar_t *to,
+                       const char *from, size_t n,
+                       mbstate_t *st)
+{ *to = *from; return 1; }
+
+size_t _WLocale_wctomb(struct _Locale_codecvt *lcodecvt,
+                       char *to, size_t n,
+                       const wchar_t c,
+                       mbstate_t *st)
+{ *to = (char)c; return 1; }
+#endif
+
+size_t _WLocale_unshift(struct _Locale_codecvt *lcodecvt,
+                        mbstate_t *st,
+                        char *buf, size_t n, char ** next)
+{ *next = buf; return 0; }
+
+/* Collate */
+int _Locale_strcmp(struct _Locale_collate * __loc,
+                   const char *s1, size_t n1,
+		   const char *s2, size_t n2) {
+  int ret = 0;
+  char buf1[64], buf2[64];
+  while (n1 > 0 || n2 > 0) {
+    size_t bufsize1 = n1 < 63 ? n1 : 63;
+    size_t bufsize2 = n2 < 63 ? n2 : 63;
+    strncpy(buf1, s1, bufsize1); buf1[bufsize1] = 0;
+    strncpy(buf2, s2, bufsize2); buf2[bufsize2] = 0;
+
+    ret = strcoll_l(buf1, buf2, (locale_t)__loc);
+    if (ret != 0) return ret;
+    s1 += bufsize1; n1 -= bufsize1;
+    s2 += bufsize2; n2 -= bufsize2;
+  }
+  return ret;
+}
+
+#if !defined (_STLP_NO_WCHAR_T)
+int _WLocale_strcmp(struct _Locale_collate *__loc,
+                    const wchar_t *s1, size_t n1,
+                    const wchar_t *s2, size_t n2) {
+  int ret = 0;
+  wchar_t buf1[64], buf2[64];
+  while (n1 > 0 || n2 > 0) {
+    size_t bufsize1 = n1 < 63 ? n1 : 63;
+    size_t bufsize2 = n2 < 63 ? n2 : 63;
+    wcsncpy(buf1, s1, bufsize1); buf1[bufsize1] = 0;
+    wcsncpy(buf2, s2, bufsize2); buf2[bufsize2] = 0;
+
+    ret = wcscoll_l(buf1, buf2, (locale_t)__loc);
+    if (ret != 0) return ret;
+    s1 += bufsize1; n1 -= bufsize1;
+    s2 += bufsize2; n2 -= bufsize2;
+  }
+  return ret;
+}
+
+#endif
+
+size_t _Locale_strxfrm(struct _Locale_collate *__loc,
+                       char *dest, size_t dest_n,
+                       const char *src, size_t src_n )
+{
+  const char *real_src;
+  char *buf = NULL;
+  size_t result;
+
+  if (src_n == 0)
+  {
+    if (dest != NULL) dest[0] = 0;
+    return 0;
+  }
+  if (src[src_n] != 0) {
+    buf = malloc(src_n + 1);
+    strncpy(buf, src, src_n);
+    buf[src_n] = 0;
+    real_src = buf;
+  }
+  else
+    real_src = src;
+  result = strxfrm_l(dest, real_src, dest_n, (locale_t)__loc);
+  if (buf != NULL) free(buf);
+  return result;
+}
+
+# ifndef _STLP_NO_WCHAR_T
+
+size_t _WLocale_strxfrm( struct _Locale_collate *__loc,
+                        wchar_t *dest, size_t dest_n,
+                        const wchar_t *src, size_t src_n )
+{
+  const wchar_t *real_src;
+  wchar_t *buf = NULL;
+  size_t result;
+
+  if (src_n == 0)
+  {
+    if (dest != NULL) dest[0] = 0;
+    return 0;
+  }
+  if (src[src_n] != 0) {
+    buf = malloc((src_n + 1) * sizeof(wchar_t));
+    wcsncpy(buf, src, src_n);
+    buf[src_n] = 0;
+    real_src = buf;
+  }
+  else
+    real_src = src;
+  result = wcsxfrm_l(dest, real_src, dest_n, (locale_t)__loc);
+  if (buf != NULL) free(buf);
+  return result;
+}
+
+# endif
+
+/* Numeric */
+
+char _Locale_decimal_point(struct _Locale_numeric *__loc)
+{
+  return *(nl_langinfo_l(RADIXCHAR, (locale_t)__loc));
+}
+
+char _Locale_thousands_sep(struct _Locale_numeric *__loc)
+{
+  return *(nl_langinfo_l(THOUSEP, (locale_t)__loc));
+}
+
+const char* _Locale_grouping(struct _Locale_numeric *__loc)
+{
+  return (_Locale_thousands_sep(__loc) != 0 ) ? (nl_langinfo_l(GROUPING, (locale_t)__loc)) : _empty_str;
+}
+
+const char *_Locale_true(struct _Locale_numeric *__loc)
+{
+  return nl_langinfo_l(YESSTR, (locale_t)__loc);
+}
+
+const char *_Locale_false(struct _Locale_numeric *__loc)
+{
+  return nl_langinfo_l(NOSTR, (locale_t)__loc);
+}
+
+#ifndef _STLP_NO_WCHAR_T
+wchar_t _WLocale_decimal_point(struct _Locale_numeric *__loc)
+{ return (wchar_t)_Locale_decimal_point(__loc); }
+wchar_t _WLocale_thousands_sep(struct _Locale_numeric *__loc)
+{ return (wchar_t)_Locale_thousands_sep(__loc); }
+const wchar_t *_WLocale_true(struct _Locale_numeric *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_true(__loc), buf, bufSize); }
+const wchar_t *_WLocale_false(struct _Locale_numeric *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_false(__loc), buf, bufSize); }
+#endif
+
+/* Monetary */
+
+const char *_Locale_int_curr_symbol(struct _Locale_monetary *__loc)
+{
+  return nl_langinfo_l(INT_CURR_SYMBOL, (locale_t)__loc);
+}
+
+const char *_Locale_currency_symbol(struct _Locale_monetary *__loc)
+{
+  return nl_langinfo_l(CURRENCY_SYMBOL, (locale_t)__loc);
+}
+
+char _Locale_mon_decimal_point(struct _Locale_monetary * __loc)
+{
+  return *(nl_langinfo_l(MON_DECIMAL_POINT,(locale_t)__loc));
+}
+
+char _Locale_mon_thousands_sep(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(MON_THOUSANDS_SEP, (locale_t)__loc));
+}
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t *_WLocale_int_curr_symbol(struct _Locale_monetary *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_int_curr_symbol(__loc), buf, bufSize); }
+const wchar_t *_WLocale_currency_symbol(struct _Locale_monetary *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_currency_symbol(__loc), buf, bufSize); }
+wchar_t _WLocale_mon_decimal_point(struct _Locale_monetary * __loc)
+{ return (wchar_t)_Locale_mon_decimal_point(__loc); }
+wchar_t _WLocale_mon_thousands_sep(struct _Locale_monetary * __loc)
+{ return (wchar_t)_Locale_mon_thousands_sep(__loc); }
+const wchar_t *_WLocale_positive_sign(struct _Locale_monetary *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_positive_sign(__loc), buf, bufSize); }
+const wchar_t *_WLocale_negative_sign(struct _Locale_monetary *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_negative_sign(__loc), buf, bufSize); }
+#endif
+
+const char *_Locale_mon_grouping(struct _Locale_monetary *__loc)
+{
+  return (_Locale_mon_thousands_sep( __loc ) != 0 ) ? nl_langinfo_l(MON_GROUPING, (locale_t)__loc) : _empty_str;
+}
+
+const char *_Locale_positive_sign(struct _Locale_monetary *__loc)
+{
+  return nl_langinfo_l(POSITIVE_SIGN, (locale_t)__loc);
+}
+
+const char *_Locale_negative_sign(struct _Locale_monetary *__loc)
+{
+  return nl_langinfo_l(NEGATIVE_SIGN, (locale_t)__loc);
+}
+
+char _Locale_int_frac_digits(struct _Locale_monetary *__loc)
+{
+  /* We are forced to manually handled the "C" locale for consistency with
+   * the default implementation in STLport. */
+  const char* lname = ((locale_t)__loc)->__names[LC_MONETARY];
+  if (lname[0] == 'C' && lname[1] == 0)
+    return 0;
+  return *(nl_langinfo_l(INT_FRAC_DIGITS, (locale_t)__loc));
+}
+
+char _Locale_frac_digits(struct _Locale_monetary *__loc)
+{
+  /* We are forced to manually handled the "C" locale for consistency with
+   * the default implementation in STLport. */
+  const char* lname = ((locale_t)__loc)->__names[LC_MONETARY];
+  if (lname[0] == 'C' && lname[1] == 0)
+    return 0;
+  return *(nl_langinfo_l(FRAC_DIGITS, (locale_t)__loc));
+}
+
+/* 1 if currency_symbol precedes a positive value, 0 if succeeds */
+int _Locale_p_cs_precedes(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(P_CS_PRECEDES, (locale_t)__loc));
+}
+
+/* 1 if a space separates currency_symbol from a positive value. */
+int _Locale_p_sep_by_space(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(P_SEP_BY_SPACE, (locale_t)__loc));
+}
+
+/*
+ * 0 Parentheses surround the quantity and currency_symbol
+ * 1 The sign string precedes the quantity and currency_symbol
+ * 2 The sign string succeeds the quantity and currency_symbol.
+ * 3 The sign string immediately precedes the currency_symbol.
+ * 4 The sign string immediately succeeds the currency_symbol.
+ */
+int _Locale_p_sign_posn(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(P_SIGN_POSN, (locale_t)__loc));
+}
+
+/* 1 if currency_symbol precedes a negative value, 0 if succeeds */
+int _Locale_n_cs_precedes(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(N_CS_PRECEDES, (locale_t)__loc));
+}
+
+/* 1 if a space separates currency_symbol from a negative value. */
+int _Locale_n_sep_by_space(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(N_SEP_BY_SPACE, (locale_t)__loc));
+}
+
+/*
+ * 0 Parentheses surround the quantity and currency_symbol
+ * 1 The sign string precedes the quantity and currency_symbol
+ * 2 The sign string succeeds the quantity and currency_symbol.
+ * 3 The sign string immediately precedes the currency_symbol.
+ * 4 The sign string immediately succeeds the currency_symbol.
+ */
+int _Locale_n_sign_posn(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(N_SIGN_POSN, (locale_t)__loc));
+}
+
+
+/* Time */
+const char *_Locale_full_monthname(struct _Locale_time *__loc, int _m )
+{
+  return nl_langinfo_l(MON_1 + _m, (locale_t)__loc);
+}
+
+const char *_Locale_abbrev_monthname(struct _Locale_time *__loc, int _m )
+{
+  return nl_langinfo_l(ABMON_1 + _m, (locale_t)__loc);
+}
+
+const char *_Locale_full_dayofweek(struct _Locale_time *__loc, int _d )
+{
+  return nl_langinfo_l(DAY_1 + _d, (locale_t)__loc);
+}
+
+const char *_Locale_abbrev_dayofweek(struct _Locale_time *__loc, int _d )
+{
+  return nl_langinfo_l(ABDAY_1 + _d, (locale_t)__loc);
+}
+
+const char *_Locale_d_t_fmt(struct _Locale_time *__loc)
+{
+  return nl_langinfo_l(D_T_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_d_fmt(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(D_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_t_fmt(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(T_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_long_d_t_fmt(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(ERA_D_T_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_long_d_fmt(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(ERA_D_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_am_str(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(AM_STR, (locale_t)__loc);
+}
+
+const char *_Locale_pm_str(struct _Locale_time* __loc )
+{
+  return nl_langinfo_l(PM_STR, (locale_t)__loc);
+}
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t *_WLocale_full_monthname(struct _Locale_time *__loc, int _m, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_full_monthname(__loc, _m), buf, bufSize); }
+const wchar_t *_WLocale_abbrev_monthname(struct _Locale_time *__loc, int _m, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_abbrev_monthname(__loc, _m), buf, bufSize); }
+const wchar_t *_WLocale_full_dayofweek(struct _Locale_time *__loc, int _d, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_full_dayofweek(__loc, _d), buf, bufSize); }
+const wchar_t *_WLocale_abbrev_dayofweek(struct _Locale_time *__loc, int _d, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_abbrev_dayofweek(__loc, _d), buf, bufSize); }
+const wchar_t *_WLocale_am_str(struct _Locale_time *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_am_str(__loc), buf, bufSize); }
+const wchar_t *_WLocale_pm_str(struct _Locale_time* __loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_pm_str(__loc), buf, bufSize); }
+#endif
+
+/* Messages */
+
+nl_catd_type _Locale_catopen(struct _Locale_messages *__loc, const char *__cat_name )
+{
+  return catopen( __cat_name, NL_CAT_LOCALE );
+}
+
+void _Locale_catclose(struct _Locale_messages *__loc, nl_catd_type __cat )
+{
+  catclose( __cat );
+}
+
+const char *_Locale_catgets(struct _Locale_messages *__loc, nl_catd_type __cat,
+                            int __setid, int __msgid, const char *dfault)
+{
+  return catgets( __cat, __setid, __msgid, dfault );
+}
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale_win32/c_locale_win32.c
@@ -0,0 +1,1786 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * Written 2000
+ * Anton Lapach
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include <limits.h>
+#if defined (_STLP_MSVC) || defined (__ICL)
+#  include <memory.h>
+#endif
+#include <string.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
+#  define _STLP_STRCPY(D, DS, S) strcpy_s(D, DS, S)
+#  define _STLP_STRNCPY(D, DS, S, C) strncpy_s(D, DS, S, C)
+#  define _STLP_STRCAT(D, DS, S) strcat_s(D, DS, S)
+#else
+#  define _STLP_STRCPY(D, DS, S) strcpy(D, S)
+#  define _STLP_STRNCPY(D, DS, S, C) strncpy(D, S, C)
+#  define _STLP_STRCAT(D, DS, S) strcat(D, S)
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* Framework functions */
+/*
+  locale :: "lang[_country[.code_page]]"
+  | ".code_page"
+  | ""
+  | NULL
+
+*/
+
+typedef struct _LOCALECONV {
+  const char* name;
+  const char* abbrev;
+} LOCALECONV;
+
+#define MAX_LANG_LEN        64  /* max language name length */
+#define MAX_CTRY_LEN        64  /* max country name length */
+#define MAX_MODIFIER_LEN    0   /* max modifier name length - n/a */
+#define MAX_LC_LEN          (MAX_LANG_LEN+MAX_CTRY_LEN+MAX_MODIFIER_LEN+3)
+                                /* max entire locale string length */
+#define MAX_CP_LEN          5   /* max code page name length */
+
+#if !defined (LANG_INVARIANT)
+#  define LANG_INVARIANT 0x7f
+#  define _STLP_LANG_INVARIANT_DEFINED
+#endif
+
+#ifndef CP_UTF7
+#  define CP_UTF7 65000
+#endif
+
+#ifndef CP_UTF8
+#  define CP_UTF8 65001
+#endif
+
+#define INVARIANT_LCID MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT)
+
+static const char *_C_name = "C";
+
+/*  non-NLS language string table */
+static LOCALECONV __rg_language[] = {
+  {"american",                    "ENU"},
+  {"american english",            "ENU"},
+  {"american-english",            "ENU"},
+  {"australian",                  "ENA"},
+  {"belgian",                     "NLB"},
+  {"canadian",                    "ENC"},
+  {"chh",                         "ZHH"},
+  {"chi",                         "ZHI"},
+  {"chinese",                     "CHS"},
+  {"chinese-hongkong",            "ZHH"},
+  {"chinese-simplified",          "CHS"},
+  {"chinese-singapore",           "ZHI"},
+  {"chinese-traditional",         "CHT"},
+  {"dutch-belgian",               "NLB"},
+  {"english-american",            "ENU"},
+  {"english-aus",                 "ENA"},
+  {"english-belize",              "ENL"},
+  {"english-can",                 "ENC"},
+  {"english-caribbean",           "ENB"},
+  {"english-ire",                 "ENI"},
+  {"english-jamaica",             "ENJ"},
+  {"english-nz",                  "ENZ"},
+  {"english-south africa",        "ENS"},
+  {"english-trinidad y tobago",   "ENT"},
+  {"english-uk",                  "ENG"},
+  {"english-us",                  "ENU"},
+  {"english-usa",                 "ENU"},
+  {"french-belgian",              "FRB"},
+  {"french-canadian",             "FRC"},
+  {"french-luxembourg",           "FRL"},
+  {"french-swiss",                "FRS"},
+  {"german-austrian",             "DEA"},
+  {"german-lichtenstein",         "DEC"},
+  {"german-luxembourg",           "DEL"},
+  {"german-swiss",                "DES"},
+  {"irish-english",               "ENI"},
+  {"italian-swiss",               "ITS"},
+  {"norwegian",                   "NOR"},
+  {"norwegian-bokmal",            "NOR"},
+  {"norwegian-nynorsk",           "NON"},
+  {"portuguese-brazilian",        "PTB"},
+  {"spanish-argentina",           "ESS"},
+  {"spanish-bolivia",             "ESB"},
+  {"spanish-chile",               "ESL"},
+  {"spanish-colombia",            "ESO"},
+  {"spanish-costa rica",          "ESC"},
+  {"spanish-dominican republic",  "ESD"},
+  {"spanish-ecuador",             "ESF"},
+  {"spanish-el salvador",         "ESE"},
+  {"spanish-guatemala",           "ESG"},
+  {"spanish-honduras",            "ESH"},
+  {"spanish-mexican",             "ESM"},
+  {"spanish-modern",              "ESN"},
+  {"spanish-nicaragua",           "ESI"},
+  {"spanish-panama",              "ESA"},
+  {"spanish-paraguay",            "ESZ"},
+  {"spanish-peru",                "ESR"},
+  {"spanish-puerto rico",         "ESU"},
+  {"spanish-uruguay",             "ESY"},
+  {"spanish-venezuela",           "ESV"},
+  {"swedish-finland",             "SVF"},
+  {"swiss",                       "DES"},
+  {"uk",                          "ENG"},
+  {"us",                          "ENU"},
+  {"usa",                         "ENU"}
+};
+
+/*  non-NLS country string table */
+static LOCALECONV __rg_country[] = {
+  {"america",                     "USA"},
+  {"britain",                     "GBR"},
+  {"china",                       "CHN"},
+  {"czech",                       "CZE"},
+  {"england",                     "GBR"},
+  {"great britain",               "GBR"},
+  {"holland",                     "NLD"},
+  {"hong-kong",                   "HKG"},
+  {"new-zealand",                 "NZL"},
+  {"nz",                          "NZL"},
+  {"pr china",                    "CHN"},
+  {"pr-china",                    "CHN"},
+  {"puerto-rico",                 "PRI"},
+  {"slovak",                      "SVK"},
+  {"south africa",                "ZAF"},
+  {"south korea",                 "KOR"},
+  {"south-africa",                "ZAF"},
+  {"south-korea",                 "KOR"},
+  {"trinidad & tobago",           "TTO"},
+  {"uk",                          "GBR"},
+  {"united-kingdom",              "GBR"},
+  {"united-states",               "USA"},
+  {"us",                          "USA"},
+};
+
+typedef struct _Locale_name_hint {
+  LCID id;
+} _Locale_lcid_t;
+
+typedef struct _Locale_ctype {
+  _Locale_lcid_t lc;
+  UINT cp;
+  unsigned short ctable[256];
+} _Locale_ctype_t;
+
+typedef struct _Locale_numeric {
+  _Locale_lcid_t lc;
+  char cp[MAX_CP_LEN + 1];
+  char decimal_point[4];
+  char thousands_sep[4];
+  char *grouping;
+} _Locale_numeric_t;
+
+typedef struct _Locale_time {
+  _Locale_lcid_t lc;
+  char cp[MAX_CP_LEN + 1];
+  char *month[12];
+  char *abbrev_month[12];
+  char *dayofweek[7];
+  char *abbrev_dayofweek[7];
+  char *date_time_format;
+  char *long_date_time_format;
+  char *date_format;
+  char *long_date_format;
+  char *time_format;
+  char am[9];
+  char pm[9];
+} _Locale_time_t;
+
+typedef struct _Locale_collate {
+  _Locale_lcid_t lc;
+  char cp[MAX_CP_LEN + 1];
+} _Locale_collate_t;
+
+typedef struct _Locale_monetary {
+  _Locale_lcid_t lc;
+  char cp[MAX_CP_LEN + 1];
+  char decimal_point[4];
+  char thousands_sep[4];
+  char *grouping;
+  char int_curr_symbol[5]; /* 3 + 1 + 1 */
+  char curr_symbol[6];
+  char negative_sign[5];
+  char positive_sign[5];
+  int frac_digits;
+  int int_frac_digits;
+} _Locale_monetary_t;
+
+/* Internal function */
+static void __FixGrouping(char *grouping);
+static const char* __ConvertName(const char* lname, LOCALECONV* ConvTable, int TableSize);
+static int __ParseLocaleString(const char* lname, char* lang, char* ctry, char* page);
+static int __GetLCID(const char* lang, const char* ctry, LCID* lcid);
+static int __GetLCIDFromName(const char* lname, LCID* lcid, char *cp, _Locale_lcid_t *hint);
+static char const* __GetLocaleName(LCID lcid, const char* cp, char* buf);
+static char const* __Extract_locale_name(const char* loc, const char* category, char* buf);
+static char const* __TranslateToSystem(const char* lname, char* buf, _Locale_lcid_t* hint, int *__err_code);
+static void __GetLocaleInfoUsingACP(LCID lcid, const char* cp, LCTYPE lctype, char* buf, int buf_size, wchar_t* wbuf, int wbuf_size);
+static int __intGetACP(LCID lcid);
+static int __intGetOCP(LCID lcid);
+static int __GetDefaultCP(LCID lcid);
+static char* __ConvertToCP(int from_cp, int to_cp, const char *from, size_t size, size_t *ret_buf_size);
+static void my_ltoa(long __x, char* buf);
+
+void my_ltoa(long __x, char* buf) {
+  char rbuf[64];
+  char* ptr = rbuf;
+
+  if (__x == 0)
+    *ptr++ = '0';
+  else {
+    for (; __x != 0; __x /= 10)
+      *ptr++ = (char)(__x % 10) + '0';
+  }
+  while(ptr > rbuf) *buf++ = *--ptr;
+  /* psw */
+  *buf = '\0';
+}
+
+#if defined (__cplusplus)
+_STLP_BEGIN_NAMESPACE
+extern "C" {
+#endif
+
+_Locale_lcid_t* _Locale_get_ctype_hint(_Locale_ctype_t* ltype)
+{ return (ltype != 0) ? &ltype->lc : 0; }
+_Locale_lcid_t* _Locale_get_numeric_hint(_Locale_numeric_t* lnumeric)
+{ return (lnumeric != 0) ? &lnumeric->lc : 0; }
+_Locale_lcid_t* _Locale_get_time_hint(_Locale_time_t* ltime)
+{ return (ltime != 0) ? &ltime->lc : 0; }
+_Locale_lcid_t* _Locale_get_collate_hint(_Locale_collate_t* lcollate)
+{ return (lcollate != 0) ? &lcollate->lc : 0; }
+_Locale_lcid_t* _Locale_get_monetary_hint(_Locale_monetary_t* lmonetary)
+{ return (lmonetary != 0) ? &lmonetary->lc : 0; }
+_Locale_lcid_t* _Locale_get_messages_hint(struct _Locale_messages* lmessages) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lmessages)
+  return 0;
+}
+
+#define MAP(x, y) if ((mask & x) != 0) ret |= (y)
+unsigned short MapCtypeMask(unsigned short mask) {
+  unsigned short ret = 0;
+  MAP(C1_UPPER, _Locale_UPPER | _Locale_PRINT);
+  MAP(C1_LOWER, _Locale_LOWER | _Locale_PRINT);
+  MAP(C1_DIGIT, _Locale_DIGIT | _Locale_PRINT);
+  MAP(C1_SPACE, _Locale_SPACE | _Locale_PRINT);
+  MAP(C1_PUNCT, _Locale_PUNCT | _Locale_PRINT);
+  /* MAP(C1_BLANK, ?); */
+  MAP(C1_XDIGIT, _Locale_XDIGIT | _Locale_PRINT);
+  MAP(C1_ALPHA, _Locale_ALPHA | _Locale_PRINT);
+  if ((mask & C1_CNTRL) != 0) { ret |= _Locale_CNTRL; ret &= ~_Locale_PRINT; }
+  return ret;
+}
+
+static void MapCtypeMasks(unsigned short *cur, unsigned short *end) {
+  for (; cur != end; ++cur) {
+    *cur = MapCtypeMask(*cur);
+  }
+}
+
+_Locale_ctype_t* _Locale_ctype_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  char cp_name[MAX_CP_LEN + 1];
+  int NativeCP;
+  unsigned char Buffer[256];
+  unsigned char *ptr;
+  CPINFO CPInfo;
+  int i;
+  wchar_t *wbuffer;
+  int BufferSize;
+
+  _Locale_ctype_t *ltype = (_Locale_ctype_t*)malloc(sizeof(_Locale_ctype_t));
+
+  if (!ltype) { *__err_code = _STLP_LOC_NO_MEMORY; return ltype; }
+  memset(ltype, 0, sizeof(_Locale_ctype_t));
+
+  if (__GetLCIDFromName(name, &ltype->lc.id, cp_name, lc_hint) == -1)
+  { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+#if defined (__BORLANDC__)
+  if ( ltype->lc.id == INVARIANT_LCID && name[0] == 'C' && name[1] == 0 )
+  { ltype->lc.id = 0x409; }
+#endif
+
+  ltype->cp = atoi(cp_name);
+
+  NativeCP = __GetDefaultCP(ltype->lc.id);
+
+  /* Make table with all characters. */
+  for (i = 0; i < 256; ++i) Buffer[i] = (unsigned char)i;
+
+  if (!GetCPInfo(NativeCP, &CPInfo)) { free(ltype); return NULL; }
+
+  if (CPInfo.MaxCharSize > 1) {
+    for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr+=2)
+      for (i = *ptr; i <= *(ptr + 1); ++i) Buffer[i] = 0;
+  }
+
+  if ((UINT)NativeCP != ltype->cp) {
+    OSVERSIONINFO ver_info;
+    ver_info.dwOSVersionInfoSize = sizeof(ver_info);
+    GetVersionEx(&ver_info);
+    if (ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+      /* Convert character sequence to Unicode. */
+      BufferSize = MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0);
+      if (!BufferSize) { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+      wbuffer = (wchar_t*)malloc(BufferSize * sizeof(wchar_t));
+      if (!wbuffer) { free(ltype); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+      MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize);
+
+      GetStringTypeW(CT_CTYPE1, wbuffer, 256, ltype->ctable);
+      MapCtypeMasks(ltype->ctable, ltype->ctable + 256);
+      free(wbuffer);
+    }
+    else {
+      unsigned short ctable[256];
+      unsigned char TargetBuffer[256];
+      GetStringTypeA(ltype->lc.id, CT_CTYPE1, (const char*)Buffer, 256, ctable);
+
+      /* Convert character sequence to target code page. */
+      BufferSize = MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0);
+      if (!BufferSize) { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+      wbuffer = (wchar_t*)malloc(BufferSize * sizeof(wchar_t));
+      if (!wbuffer) { free(ltype); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+      MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize);
+      if (!WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuffer, BufferSize, (char*)TargetBuffer, 256, NULL, FALSE))
+      { free(wbuffer); free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+      free(wbuffer);
+
+      /* Translate ctype table. */
+      for (i = 0; i < 256; ++i) {
+        if (!TargetBuffer[i]) continue;
+        ltype->ctable[TargetBuffer[i]] = MapCtypeMask(ctable[i]);
+      }
+    }
+  }
+  else {
+    GetStringTypeA(ltype->lc.id, CT_CTYPE1, (const char*)Buffer, 256, ltype->ctable);
+    MapCtypeMasks(ltype->ctable, ltype->ctable + 256);
+  }
+  return ltype;
+}
+
+_Locale_numeric_t* _Locale_numeric_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  wchar_t wbuf[4];
+  char *GroupingBuffer;
+  int BufferSize;
+
+  _Locale_numeric_t *lnum = (_Locale_numeric_t*)malloc(sizeof(_Locale_numeric_t));
+  if (!lnum) { *__err_code = _STLP_LOC_NO_MEMORY; return lnum; }
+  memset(lnum, 0, sizeof(_Locale_numeric_t));
+
+  if (__GetLCIDFromName(name, &lnum->lc.id, lnum->cp, lc_hint) == -1)
+  { free(lnum); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+#if defined (__BORLANDC__)
+  if (lnum->lc.id != INVARIANT_LCID) {
+#endif
+  __GetLocaleInfoUsingACP(lnum->lc.id, lnum->cp, LOCALE_SDECIMAL, lnum->decimal_point, 4, wbuf, 4);
+  __GetLocaleInfoUsingACP(lnum->lc.id, lnum->cp, LOCALE_STHOUSAND, lnum->thousands_sep, 4, wbuf, 4);
+#if defined (__BORLANDC__)
+  }
+  else
+    lnum->decimal_point[0] = '.';
+#endif
+
+  if (lnum->lc.id != INVARIANT_LCID) {
+    BufferSize = GetLocaleInfoA(lnum->lc.id, LOCALE_SGROUPING, NULL, 0);
+    GroupingBuffer = (char*)malloc(BufferSize);
+    if (!GroupingBuffer) { free(lnum); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+    GetLocaleInfoA(lnum->lc.id, LOCALE_SGROUPING, GroupingBuffer, BufferSize);
+    __FixGrouping(GroupingBuffer);
+    lnum->grouping = GroupingBuffer;
+  }
+  else {
+    lnum->grouping = (char*)malloc(1);
+    if (!lnum->grouping) { free(lnum); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+    lnum->grouping[0] = 0;
+  }
+
+  return lnum;
+}
+
+static int __ConvertDate(const char *NTDate, char *buffer, int buf_size) {
+  /* This function will return an incomplete buffer if buffer is not long enough */
+  const char *cur_char;
+  char *cur_output, *end_output;
+
+  /* Correct time format. */
+  cur_char = NTDate;
+  cur_output = buffer;
+  end_output = cur_output + buf_size;
+  buf_size = 0;
+  while (*cur_char) {
+    if (cur_output && (cur_output == end_output)) break;
+    switch (*cur_char) {
+    case 'd':
+    {
+      if (*(cur_char + 1) == 'd') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (*(cur_char + 2) == 'd') {
+          if (*(cur_char + 3) == 'd') {
+            if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'A'; }
+            buf_size += 2;
+            cur_char += 3;
+          }
+          else {
+            if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'a'; }
+            buf_size += 2;
+            cur_char += 2;
+          }
+        }
+        else {
+          if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'd'; }
+          buf_size += 2;
+          cur_char++;
+        }
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'd'; }
+        buf_size += 3;
+      }
+    }
+    break;
+    case 'M':
+    {
+      if (*(cur_char + 1) == 'M') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (*(cur_char + 2) == 'M') {
+          if (*(cur_char + 3) == 'M') {
+            if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'B'; }
+            buf_size += 2;
+            cur_char += 3;
+          }
+          else {
+            if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'b'; }
+            buf_size += 2;
+            cur_char += 2;
+          }
+        }
+        else {
+          if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'm'; }
+          buf_size += 2;
+          cur_char++;
+        }
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'm'; }
+        buf_size += 3;
+      }
+    }
+    break;
+    case 'y':
+    {
+      if (*(cur_char + 1) == 'y') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (*(cur_char + 2) == 'y' && *(cur_char + 3) == 'y') {
+          if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'Y'; }
+          buf_size += 2;
+          cur_char += 3;
+        }
+        else {
+          if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'y'; }
+          buf_size += 2;
+          cur_char++;
+        }
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'y'; }
+        buf_size += 3;
+      }
+    }
+    break;
+    case '%':
+    {
+      if (cur_output && (cur_output + 2 > end_output)) {
+        *cur_output = 0;
+        return ++buf_size;
+      }
+      if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '%'; }
+      buf_size += 2;
+    }
+    break;
+    case '\'':
+    {
+      ++cur_char;
+      while (*cur_char != '\'' && *cur_char != 0 && (cur_output == NULL || cur_output != end_output)) {
+        if (cur_output) { *cur_output++ = *cur_char; }
+        ++cur_char;
+        buf_size += 1;
+      }
+    }
+    break;
+    default:
+    {
+      if (cur_output) { *(cur_output++) = *cur_char; }
+      buf_size += 1;
+    }
+    break;
+    }
+    if (*cur_char == 0) break;
+    ++cur_char;
+  }
+
+  if (!cur_output || cur_output != end_output) {
+    if (cur_output) *cur_output = 0;
+    buf_size += 1;
+  }
+  else {
+    /* We trunc result */
+    *(--cur_output) = 0;
+  }
+
+  return buf_size;
+}
+
+static int __ConvertTime(const char *NTTime, char *buffer, int buf_size) {
+  const char *cur_char;
+  char *cur_output, *end_output;
+  cur_char = NTTime;
+  cur_output = buffer;
+  end_output = cur_output + buf_size;
+  buf_size = 0;
+  while (*cur_char) {
+    switch(*cur_char) {
+    case 'h':
+      if (*(cur_char + 1) == 'h') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'I'; }
+        buf_size += 2;
+        ++cur_char;
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'I'; }
+        buf_size += 3;
+      }
+      break;
+    case 'H':
+      if (*(cur_char + 1) == 'H') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'H'; }
+        buf_size += 2;
+        ++cur_char;
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'H'; }
+        buf_size += 3;
+      }
+      break;
+    case 'm':
+      if (*(cur_char + 1) == 'm') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'M'; }
+        buf_size += 2;
+        cur_char++;
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'M'; }
+        buf_size += 3;
+      }
+      break;
+    case 's':
+      if (*(cur_char + 1) == 's') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'S'; }
+        buf_size += 2;
+        ++cur_char;
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'S'; }
+        buf_size += 3;
+      }
+      break;
+    case 't':
+      if (*(cur_char + 1) == 't')
+        ++cur_char;
+      if (cur_output && (cur_output + 2 > end_output)) {
+        *cur_output = 0;
+        return ++buf_size;
+      }
+      if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'p'; }
+      buf_size += 2;
+      break;
+    case '%':
+      if (cur_output && (cur_output + 2 > end_output)) {
+        *cur_output = 0;
+        return ++buf_size;
+      }
+      if (cur_output) { *(cur_output++)='%'; *(cur_output++)='%'; }
+      buf_size += 2;
+      break;
+    case '\'':
+      ++cur_char;
+      while (*cur_char != '\'' && *cur_char != 0 && (!cur_output || (cur_output != end_output))) {
+        if (cur_output) *cur_output++ = *cur_char;
+        ++cur_char;
+        buf_size += 1;
+      }
+      break;
+    default:
+      if (cur_output) { *(cur_output++) = *cur_char; }
+      buf_size += 1;
+      break;
+    }
+    if (*cur_char == 0) break;
+    ++cur_char;
+  }
+
+  if (!cur_output || cur_output != end_output) {
+    if (cur_output) *cur_output = 0;
+    buf_size += 1;
+  }
+  else {
+    /* We trunc result */
+    *(--cur_output) = 0;
+  }
+
+  return buf_size;
+}
+
+_Locale_time_t* _Locale_time_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  int size, month, dayofweek;
+  size_t length;
+  char fmt80[80];
+  wchar_t wbuf80[80];
+
+  _Locale_time_t *ltime = (_Locale_time_t*)malloc(sizeof(_Locale_time_t));
+  
+  if (!ltime) { *__err_code = _STLP_LOC_NO_MEMORY; return ltime; }
+  memset(ltime, 0, sizeof(_Locale_time_t));
+
+  if (__GetLCIDFromName(name, &ltime->lc.id, ltime->cp, lc_hint) == -1)
+  { free(ltime); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+#if defined (__BORLANDC__)
+  if ( ltime->lc.id == INVARIANT_LCID && name[0] == 'C' && name[1] == 0 )
+  { ltime->lc.id = 0x409; }
+#endif
+
+  for (month = LOCALE_SMONTHNAME1; month <= LOCALE_SMONTHNAME12; ++month) { /* Small hack :-) */
+    size = GetLocaleInfoA(ltime->lc.id, month, NULL, 0);
+    ltime->month[month - LOCALE_SMONTHNAME1] = (char*)malloc(size);
+    if (!ltime->month[month - LOCALE_SMONTHNAME1])
+    { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+    __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, month, ltime->month[month - LOCALE_SMONTHNAME1], size, wbuf80, 80);
+  }
+
+  for (month = LOCALE_SABBREVMONTHNAME1; month <= LOCALE_SABBREVMONTHNAME12; ++month) {
+    size = GetLocaleInfoA(ltime->lc.id, month, NULL, 0);
+    ltime->abbrev_month[month - LOCALE_SABBREVMONTHNAME1] = (char*)malloc(size);
+    if (!ltime->abbrev_month[month - LOCALE_SABBREVMONTHNAME1])
+    { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+    __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, month, ltime->abbrev_month[month - LOCALE_SABBREVMONTHNAME1], size, wbuf80, 80);
+  }
+
+  for (dayofweek = LOCALE_SDAYNAME1; dayofweek <= LOCALE_SDAYNAME7; ++dayofweek) {
+    int dayindex = ( dayofweek != LOCALE_SDAYNAME7 ) ? dayofweek - LOCALE_SDAYNAME1 + 1 : 0;
+    size = GetLocaleInfoA(ltime->lc.id, dayofweek, NULL, 0);
+    ltime->dayofweek[dayindex] = (char*)malloc(size);
+    if (!ltime->dayofweek[dayindex])
+    { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+    __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, dayofweek, ltime->dayofweek[dayindex], size, wbuf80, 80);
+  }
+
+  for (dayofweek = LOCALE_SABBREVDAYNAME1; dayofweek <= LOCALE_SABBREVDAYNAME7; ++dayofweek) {
+    int dayindex = ( dayofweek != LOCALE_SABBREVDAYNAME7 ) ? dayofweek - LOCALE_SABBREVDAYNAME1 + 1 : 0;
+    size = GetLocaleInfoA(ltime->lc.id, dayofweek, NULL, 0);
+    ltime->abbrev_dayofweek[dayindex] = (char*)malloc(size);
+    if (!ltime->abbrev_dayofweek[dayindex])
+    { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+    __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, dayofweek, ltime->abbrev_dayofweek[dayindex], size, wbuf80, 80);
+  }
+
+  __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_SSHORTDATE, fmt80, 80, wbuf80, 80);
+  size = __ConvertDate(fmt80, NULL, 0);
+  ltime->date_format = (char*)malloc(size);
+  if (!ltime->date_format)
+  { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+  __ConvertDate(fmt80, ltime->date_format, size);
+
+  __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_SLONGDATE, fmt80, 80, wbuf80, 80);
+  size = __ConvertDate(fmt80, NULL, 0);
+  ltime->long_date_format = (char*)malloc(size);
+  if (!ltime->long_date_format)
+  { _Locale_time_destroy(ltime);*__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+  __ConvertDate(fmt80, ltime->long_date_format, size);
+
+  __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_STIMEFORMAT, fmt80, 80, wbuf80, 80);
+  size = __ConvertTime(fmt80, NULL, 0);
+  ltime->time_format = (char*)malloc(size);
+  if (!ltime->time_format)
+  { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+  __ConvertTime(fmt80, ltime->time_format, size);
+
+  /* NT doesn't provide this information, we must simulate. */
+  length = strlen(ltime->date_format) + strlen(ltime->time_format) + 1 /* space */ + 1 /* trailing 0 */;
+  ltime->date_time_format = (char*)malloc(length);
+  if (!ltime->date_time_format)
+  { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+  _STLP_STRCPY(ltime->date_time_format, length, ltime->date_format);
+  _STLP_STRCAT(ltime->date_time_format, length, " ");
+  _STLP_STRCAT(ltime->date_time_format, length, ltime->time_format);
+
+  /* NT doesn't provide this information, we must simulate. */
+  length = strlen(ltime->long_date_format) + strlen(ltime->time_format) + 1 /* space */ + 1 /* trailing 0 */;
+  ltime->long_date_time_format = (char*)malloc(length);
+  if (!ltime->long_date_time_format)
+  { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+  _STLP_STRCPY(ltime->long_date_time_format, length, ltime->long_date_format);
+  _STLP_STRCAT(ltime->long_date_time_format, length, " ");
+  _STLP_STRCAT(ltime->long_date_time_format, length, ltime->time_format);
+
+  __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_S1159, ltime->am, 9, wbuf80, 80);
+  __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_S2359, ltime->pm, 9, wbuf80, 80);
+
+  return ltime;
+}
+
+_Locale_collate_t* _Locale_collate_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  _Locale_collate_t *lcol = (_Locale_collate_t*)malloc(sizeof(_Locale_collate_t));
+  if (!lcol) { *__err_code = _STLP_LOC_NO_MEMORY; return lcol; }
+  memset(lcol, 0, sizeof(_Locale_collate_t));
+
+  if (__GetLCIDFromName(name, &lcol->lc.id, lcol->cp, lc_hint) == -1)
+  { free(lcol); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+#if defined (__BORLANDC__)
+  if ( lcol->lc.id == INVARIANT_LCID && name[0] == 'C' && name[1] == 0 )
+  { lcol->lc.id = 0x409; }
+#endif
+
+  return lcol;
+}
+
+_Locale_monetary_t* _Locale_monetary_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  char *GroupingBuffer;
+  int BufferSize;
+  char FracDigits[3];
+  wchar_t wbuf[6];
+
+  _Locale_monetary_t *lmon = (_Locale_monetary_t*)malloc(sizeof(_Locale_monetary_t));
+  if (!lmon) { *__err_code = _STLP_LOC_NO_MEMORY; return lmon; }
+  memset(lmon, 0, sizeof(_Locale_monetary_t));
+
+  if (__GetLCIDFromName(name, &lmon->lc.id, lmon->cp, lc_hint) == -1)
+  { free(lmon); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+  if (lmon->lc.id != INVARIANT_LCID) {
+    /* Extract information about monetary system */
+    __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SDECIMAL, lmon->decimal_point, 4, wbuf, 6);
+    __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_STHOUSAND, lmon->thousands_sep, 4, wbuf, 6);
+
+    BufferSize = GetLocaleInfoA(lmon->lc.id, LOCALE_SGROUPING, NULL, 0);
+    GroupingBuffer = (char*)malloc(BufferSize);
+    if (!GroupingBuffer)
+    { lmon->grouping = NULL; *__err_code = _STLP_LOC_NO_MEMORY; return lmon; }
+    GetLocaleInfoA(lmon->lc.id, LOCALE_SGROUPING, GroupingBuffer, BufferSize);
+    __FixGrouping(GroupingBuffer);
+    lmon->grouping = GroupingBuffer;
+
+    __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SCURRENCY, lmon->curr_symbol, 6, wbuf, 6);
+    __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SNEGATIVESIGN, lmon->negative_sign, 5, wbuf, 6);
+    __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SPOSITIVESIGN, lmon->positive_sign, 5, wbuf, 6);
+
+    GetLocaleInfoA(lmon->lc.id, LOCALE_ICURRDIGITS, FracDigits, 3);
+    lmon->frac_digits = atoi(FracDigits);
+
+    GetLocaleInfoA(lmon->lc.id, LOCALE_IINTLCURRDIGITS, FracDigits, 3);
+    lmon->int_frac_digits = atoi(FracDigits);
+
+    __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SINTLSYMBOL, lmon->int_curr_symbol, 5, wbuf, 6);
+    /* Even if Platform SDK documentation says that the returned symbol should
+     * be a 3 letters symbol followed by a seperation character, experimentation
+     * has shown that no seperation character is ever appended. We are adding it
+     * ourself to conform to the POSIX specification.
+     */
+    if (lmon->int_curr_symbol[3] == 0) {
+      lmon->int_curr_symbol[3] = ' ';
+      lmon->int_curr_symbol[4] = 0;
+    }
+  }
+  /* else it is already ok */
+
+  return lmon;
+}
+
+struct _Locale_messages* _Locale_messages_create(const char *name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  /* The Win32 API has no support for messages facet */
+  _STLP_MARK_PARAMETER_AS_UNUSED(name)
+  _STLP_MARK_PARAMETER_AS_UNUSED(lc_hint)
+  *__err_code = _STLP_LOC_UNSUPPORTED_FACET_CATEGORY;
+  return NULL;
+}
+
+static const char* _Locale_common_default(char* buf) {
+  char cp[MAX_CP_LEN + 1];
+  int CodePage = __GetDefaultCP(LOCALE_USER_DEFAULT);
+  my_ltoa(CodePage, cp);
+  return __GetLocaleName(LOCALE_USER_DEFAULT, cp, buf);
+}
+
+const char* _Locale_ctype_default(char* buf)
+{ return _Locale_common_default(buf); }
+
+const char* _Locale_numeric_default(char * buf)
+{ return _Locale_common_default(buf); }
+
+const char* _Locale_time_default(char* buf)
+{ return _Locale_common_default(buf); }
+
+const char* _Locale_collate_default(char* buf)
+{ return _Locale_common_default(buf); }
+
+const char* _Locale_monetary_default(char* buf)
+{ return _Locale_common_default(buf); }
+
+const char* _Locale_messages_default(char* buf)
+{ return _Locale_common_default(buf); }
+
+char const* _Locale_ctype_name(const _Locale_ctype_t* ltype, char* buf) {
+  char cp_buf[MAX_CP_LEN + 1];
+  my_ltoa(ltype->cp, cp_buf);
+  return __GetLocaleName(ltype->lc.id, cp_buf, buf);
+}
+
+char const* _Locale_numeric_name(const _Locale_numeric_t* lnum, char* buf)
+{ return __GetLocaleName(lnum->lc.id, lnum->cp, buf); }
+
+char const* _Locale_time_name(const _Locale_time_t* ltime, char* buf)
+{ return __GetLocaleName(ltime->lc.id, ltime->cp, buf); }
+
+char const* _Locale_collate_name(const _Locale_collate_t* lcol, char* buf)
+{ return __GetLocaleName(lcol->lc.id, lcol->cp, buf); }
+
+char const* _Locale_monetary_name(const _Locale_monetary_t* lmon, char* buf)
+{ return __GetLocaleName(lmon->lc.id, lmon->cp, buf); }
+
+char const* _Locale_messages_name(const struct _Locale_messages* lmes, char* buf) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lmes)
+  _STLP_MARK_PARAMETER_AS_UNUSED(buf)
+  return NULL;
+}
+
+void _Locale_ctype_destroy(_Locale_ctype_t* ltype) {
+  if (!ltype) return;
+
+  free(ltype);
+}
+
+void _Locale_numeric_destroy(_Locale_numeric_t* lnum) {
+  if (!lnum) return;
+
+  if (lnum->grouping) free(lnum->grouping);
+  free(lnum);
+}
+
+void _Locale_time_destroy(_Locale_time_t* ltime) {
+  int i;
+  if (!ltime) return;
+
+  for (i = 0; i < 12; ++i) {
+    if (ltime->month[i]) free(ltime->month[i]);
+    if (ltime->abbrev_month[i]) free(ltime->abbrev_month[i]);
+  }
+
+  for (i = 0; i < 7; ++i) {
+    if (ltime->dayofweek[i]) free(ltime->dayofweek[i]);
+    if (ltime->abbrev_dayofweek[i]) free(ltime->abbrev_dayofweek[i]);
+  }
+
+  if (ltime->date_format) free(ltime->date_format);
+  if (ltime->long_date_format) free(ltime->long_date_format);
+  if (ltime->time_format) free(ltime->time_format);
+  if (ltime->date_time_format) free(ltime->date_time_format);
+  if (ltime->long_date_time_format) free(ltime->long_date_time_format);
+
+  free(ltime);
+}
+
+void _Locale_collate_destroy(_Locale_collate_t* lcol) {
+  if (!lcol) return;
+
+  free(lcol);
+}
+
+void _Locale_monetary_destroy(_Locale_monetary_t* lmon) {
+  if (!lmon) return;
+
+  if (lmon->grouping) free(lmon->grouping);
+  free(lmon);
+}
+
+void _Locale_messages_destroy(struct _Locale_messages* lmes)
+{ _STLP_MARK_PARAMETER_AS_UNUSED(lmes) }
+
+static char const* _Locale_extract_category_name(const char* name, const char* category, char* buf,
+                                                 _Locale_lcid_t* hint, int *__err_code) {
+  const char* cname = __Extract_locale_name(name, category, buf);
+  if (cname == 0 || (cname[0] == 'C' && cname[1] == 0)) {
+    return cname;
+  }
+  return __TranslateToSystem(cname, buf, hint, __err_code);
+}
+
+char const* _Locale_extract_ctype_name(const char* cname, char* buf,
+                                       _Locale_lcid_t* hint, int *__err_code)
+{ return _Locale_extract_category_name(cname, "LC_CTYPE", buf, hint, __err_code); }
+
+char const* _Locale_extract_numeric_name(const char* cname, char* buf,
+                                         _Locale_lcid_t* hint, int *__err_code)
+{ return _Locale_extract_category_name(cname, "LC_NUMERIC", buf, hint, __err_code); }
+
+char const* _Locale_extract_time_name(const char* cname, char* buf,
+                                      _Locale_lcid_t* hint, int *__err_code)
+{ return _Locale_extract_category_name(cname, "LC_TIME", buf, hint, __err_code); }
+
+char const* _Locale_extract_collate_name(const char* cname, char* buf,
+                                         _Locale_lcid_t* hint, int *__err_code)
+{ return _Locale_extract_category_name(cname, "LC_COLLATE", buf, hint, __err_code); }
+
+char const* _Locale_extract_monetary_name(const char* cname, char* buf,
+                                          _Locale_lcid_t* hint, int *__err_code)
+{ return _Locale_extract_category_name(cname, "LC_MONETARY", buf, hint, __err_code); }
+
+char const* _Locale_extract_messages_name(const char* cname, char* buf,
+                                          _Locale_lcid_t* hint, int *__err_code) {
+  if (cname[0] == 'L' && cname[1] == 'C' && cname[2] == '_') {
+    return _C_name;
+  }
+  if (cname[0] == 'C' && cname[1] == 0) {
+    return _C_name;
+  }
+  return __TranslateToSystem(cname, buf, hint, __err_code);
+}
+
+/* ctype */
+
+const _Locale_mask_t* _Locale_ctype_table(_Locale_ctype_t* ltype) {
+  _STLP_STATIC_ASSERT(sizeof(_Locale_mask_t) == sizeof(ltype->ctable[0]))
+  return (const _Locale_mask_t*)ltype->ctable;
+}
+
+int _Locale_toupper(_Locale_ctype_t* ltype, int c) {
+  char buf[2], out_buf[2];
+  buf[0] = (char)c; buf[1] = 0;
+  if ((UINT)__GetDefaultCP(ltype->lc.id) == ltype->cp) {
+    LCMapStringA(ltype->lc.id, LCMAP_LINGUISTIC_CASING | LCMAP_UPPERCASE, buf, 2, out_buf, 2);
+    return out_buf[0];
+  }
+  else {
+    wchar_t wbuf[2];
+    MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, buf, 2, wbuf, 2);
+    WideCharToMultiByte(__GetDefaultCP(ltype->lc.id), WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, buf, 2, NULL, FALSE);
+
+    LCMapStringA(ltype->lc.id, LCMAP_LINGUISTIC_CASING | LCMAP_UPPERCASE, buf, 2, out_buf, 2);
+
+    MultiByteToWideChar(__GetDefaultCP(ltype->lc.id), MB_PRECOMPOSED, out_buf, 2, wbuf, 2);
+    WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, out_buf, 2, NULL, FALSE);
+    return out_buf[0];
+  }
+}
+
+int _Locale_tolower(_Locale_ctype_t* ltype, int c) {
+  char buf[2], out_buf[2];
+  buf[0] = (char)c; buf[1] = 0;
+  if ((UINT)__GetDefaultCP(ltype->lc.id) == ltype->cp) {
+    LCMapStringA(ltype->lc.id, LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, buf, 2, out_buf, 2);
+    return out_buf[0];
+  }
+  else {
+    wchar_t wbuf[2];
+    MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, buf, 2, wbuf, 2);
+    WideCharToMultiByte(__GetDefaultCP(ltype->lc.id), WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, buf, 2, NULL, FALSE);
+
+    LCMapStringA(ltype->lc.id, LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, buf, 2, out_buf, 2);
+
+    MultiByteToWideChar(__GetDefaultCP(ltype->lc.id), MB_PRECOMPOSED, out_buf, 2, wbuf, 2);
+    WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, out_buf, 2, NULL, FALSE);
+    return out_buf[0];
+  }
+}
+
+#ifndef CSTR_EQUAL /* VC5SP3*/
+#  define CSTR_EQUAL 2
+#endif
+#ifndef CSTR_LESS_THAN /* VC5SP3 */
+#  define CSTR_LESS_THAN 1
+#endif
+
+static DWORD max_DWORD = 0xffffffff;
+static DWORD trim_size_t_to_DWORD(size_t n) { return n < (size_t)max_DWORD ? (DWORD)n : max_DWORD; }
+
+/* Collate */
+/* This function takes care of the potential size_t DWORD different size. */
+static int _Locale_strcmp_auxA(_Locale_collate_t* lcol,
+                               const char* s1, size_t n1,
+                               const char* s2, size_t n2) {
+  int result = CSTR_EQUAL;
+  while (n1 > 0 || n2 > 0) {
+    DWORD size1 = trim_size_t_to_DWORD(n1);
+    DWORD size2 = trim_size_t_to_DWORD(n2);
+    result = CompareStringA(lcol->lc.id, 0, s1, size1, s2, size2);
+    if (result != CSTR_EQUAL)
+      break;
+    n1 -= size1;
+    n2 -= size2;
+  }
+  return result;
+}
+
+int _Locale_strcmp(_Locale_collate_t* lcol,
+                   const char* s1, size_t n1,
+                   const char* s2, size_t n2) {
+  int result;
+  if (__GetDefaultCP(lcol->lc.id) == atoi(lcol->cp)) {
+    result = _Locale_strcmp_auxA(lcol, s1, n1, s2, n2);
+  }
+  else {
+    char *buf1, *buf2;
+    size_t size1, size2;
+    buf1 = __ConvertToCP(atoi(lcol->cp), __GetDefaultCP(lcol->lc.id), s1, n1, &size1);
+    buf2 = __ConvertToCP(atoi(lcol->cp), __GetDefaultCP(lcol->lc.id), s2, n2, &size2);
+
+    result = _Locale_strcmp_auxA(lcol, buf1, size1, buf2, size2);
+    free(buf1); free(buf2);
+  }
+  return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1;
+}
+
+size_t _Locale_strxfrm(_Locale_collate_t* lcol,
+                       char* dst, size_t dst_size,
+                       const char* src, size_t src_size) {
+  int result;
+
+  /* The Windows API do not support transformation of very long strings (src_size > INT_MAX)
+   * In this case the result will just be the input string:
+   */
+  if (src_size > INT_MAX) {
+    if (dst != 0) {
+      _STLP_STRNCPY(dst, dst_size, src, src_size);
+    }
+    return src_size;
+  }
+  if (dst_size > INT_MAX) {
+    /* now that we know that src_size <= INT_MAX we can safely decrease dst_size to INT_MAX. */
+    dst_size = INT_MAX;
+  }
+
+  if (__GetDefaultCP(lcol->lc.id) == atoi(lcol->cp))
+    result = LCMapStringA(lcol->lc.id, LCMAP_SORTKEY, src, (int)src_size, dst, (int)dst_size);
+  else {
+    char *buf;
+    size_t size;
+    buf = __ConvertToCP(atoi(lcol->cp), __GetDefaultCP(lcol->lc.id), src, src_size, &size);
+
+    result = LCMapStringA(lcol->lc.id, LCMAP_SORTKEY, buf, (int)size, dst, (int)dst_size);
+    free(buf);
+  }
+  return result != 0 ? result - 1 : 0;
+}
+
+/* Numeric */
+static const char* __true_name = "true";
+static const char* __false_name = "false";
+
+char _Locale_decimal_point(_Locale_numeric_t* lnum)
+{ return lnum->decimal_point[0]; }
+
+char _Locale_thousands_sep(_Locale_numeric_t* lnum)
+{ return lnum->thousands_sep[0]; }
+
+const char* _Locale_grouping(_Locale_numeric_t * lnum) {
+  if (!lnum->grouping) return "";
+  else return lnum->grouping;
+}
+
+const char * _Locale_true(_Locale_numeric_t * lnum) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lnum)
+  return __true_name; /* NT does't provide information about this */
+}
+
+const char * _Locale_false(_Locale_numeric_t * lnum) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lnum)
+  return __false_name; /* NT does't provide information about this */
+}
+
+/* Monetary */
+const char* _Locale_int_curr_symbol(_Locale_monetary_t * lmon)
+{ return lmon->int_curr_symbol; }
+
+const char* _Locale_currency_symbol(_Locale_monetary_t * lmon)
+{ return lmon->curr_symbol; }
+
+char _Locale_mon_decimal_point(_Locale_monetary_t * lmon)
+{ return lmon->decimal_point[0]; }
+
+char _Locale_mon_thousands_sep(_Locale_monetary_t * lmon)
+{ return lmon->thousands_sep[0]; }
+
+const char* _Locale_mon_grouping(_Locale_monetary_t * lmon) {
+  if (!lmon->grouping) return "";
+  else return lmon->grouping;
+}
+
+const char* _Locale_positive_sign(_Locale_monetary_t * lmon)
+{ return lmon->positive_sign; }
+
+const char* _Locale_negative_sign(_Locale_monetary_t * lmon)
+{ return lmon->negative_sign; }
+
+char _Locale_int_frac_digits(_Locale_monetary_t * lmon)
+{ return (char)lmon->int_frac_digits; }
+
+char _Locale_frac_digits(_Locale_monetary_t * lmon)
+{ return (char)lmon->frac_digits; }
+
+int _Locale_p_cs_precedes(_Locale_monetary_t * lmon) {
+  char loc_data[2];
+  GetLocaleInfoA(lmon->lc.id, LOCALE_IPOSSYMPRECEDES, loc_data, 2);
+  if (loc_data[0] == '0') return 0;
+  else if (loc_data[0] == '1') return 1;
+  else return -1;
+}
+
+int _Locale_p_sep_by_space(_Locale_monetary_t * lmon) {
+  char loc_data[2];
+  GetLocaleInfoA(lmon->lc.id, LOCALE_IPOSSEPBYSPACE, loc_data, 2);
+  if (loc_data[0] == '0') return 0;
+  else if (loc_data[0] == '1') return 1;
+  else return -1;
+}
+
+int _Locale_p_sign_posn(_Locale_monetary_t * lmon) {
+  char loc_data[2];
+  if (lmon->lc.id != INVARIANT_LCID) {
+    GetLocaleInfoA(lmon->lc.id, LOCALE_IPOSSIGNPOSN, loc_data, 2);
+    return atoi(loc_data);
+  }
+  else {
+    return CHAR_MAX;
+  }
+}
+
+int _Locale_n_cs_precedes(_Locale_monetary_t * lmon) {
+  char loc_data[2];
+  GetLocaleInfoA(lmon->lc.id, LOCALE_INEGSYMPRECEDES, loc_data, 2);
+  if (loc_data[0] == '0') return 0;
+  else if (loc_data[0] == '1') return 1;
+  else return -1;
+}
+
+int _Locale_n_sep_by_space(_Locale_monetary_t * lmon) {
+  char loc_data[2];
+  GetLocaleInfoA(lmon->lc.id, LOCALE_INEGSEPBYSPACE, loc_data, 2);
+  if (loc_data[0] == '0') return 0;
+  else if (loc_data[0] == '1') return 1;
+  else return -1;
+}
+
+int _Locale_n_sign_posn(_Locale_monetary_t * lmon) {
+  char loc_data[2];
+  if (lmon->lc.id != INVARIANT_LCID) {
+    GetLocaleInfoA(lmon->lc.id, LOCALE_INEGSIGNPOSN, loc_data, 2);
+    return atoi(loc_data);
+  }
+  else {
+    return CHAR_MAX;
+  }
+}
+
+/* Time */
+const char * _Locale_full_monthname(_Locale_time_t * ltime, int month) {
+  const char **names = (const char**)ltime->month;
+  return names[month];
+}
+
+const char * _Locale_abbrev_monthname(_Locale_time_t * ltime, int month) {
+  const char **names = (const char**)ltime->abbrev_month;
+  return names[month];
+}
+
+const char * _Locale_full_dayofweek(_Locale_time_t * ltime, int day) {
+  const char **names = (const char**)ltime->dayofweek;
+  return names[day];
+}
+
+const char * _Locale_abbrev_dayofweek(_Locale_time_t * ltime, int day) {
+  const char **names = (const char**)ltime->abbrev_dayofweek;
+  return names[day];
+}
+
+const char* _Locale_d_t_fmt(_Locale_time_t* ltime)
+{ return ltime->date_time_format; }
+
+const char* _Locale_long_d_t_fmt(_Locale_time_t* ltime)
+{ return ltime->long_date_time_format; }
+
+const char* _Locale_d_fmt(_Locale_time_t* ltime)
+{ return ltime->date_format; }
+
+const char* _Locale_long_d_fmt(_Locale_time_t* ltime)
+{ return ltime->long_date_format; }
+
+const char* _Locale_t_fmt(_Locale_time_t* ltime)
+{ return ltime->time_format; }
+
+const char* _Locale_am_str(_Locale_time_t* ltime)
+{ return ltime->am; }
+
+const char* _Locale_pm_str(_Locale_time_t* ltime)
+{ return ltime->pm; }
+
+/* Messages */
+nl_catd_type _Locale_catopen(struct _Locale_messages* lmes, const char* cat_name) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lmes)
+  _STLP_MARK_PARAMETER_AS_UNUSED(cat_name)
+  return -1;
+}
+void _Locale_catclose(struct _Locale_messages* lmes, nl_catd_type cat) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lmes)
+  _STLP_MARK_PARAMETER_AS_UNUSED(&cat)
+}
+const char* _Locale_catgets(struct _Locale_messages* lmes, nl_catd_type cat,
+                            int setid, int msgid, const char *dfault) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lmes)
+  _STLP_MARK_PARAMETER_AS_UNUSED(&cat)
+  _STLP_MARK_PARAMETER_AS_UNUSED(&setid)
+  _STLP_MARK_PARAMETER_AS_UNUSED(&msgid)
+  return dfault;
+}
+
+#ifdef __cplusplus
+} /* extern C */
+_STLP_END_NAMESPACE
+#endif
+
+void __FixGrouping(char *grouping) {
+  /* This converts NT version which uses '0' instead of 0, etc ; to ANSI */
+  char *g = grouping;
+  char building_group = 0;
+  char repeat_last = 0;
+  /* Check there is a grouping info otherwise we would add a useless CHAR_MAX */
+  if (*g) {
+    for (; *g; ++g) {
+      if (*g > '0' && *g <= '9') {
+        if (!building_group) {
+          *grouping = *g - '0';
+          building_group = 1;
+        }
+        else {
+          /* Known issue: grouping might roll. */
+          *grouping = *grouping * 10 + *g - '0';
+        }
+      }
+      else if (*g == '0') {
+        if (!building_group) {
+          repeat_last = 1;
+        }
+        else
+          /* Known issue: grouping might roll. */
+          *grouping *= 10;
+      }
+      else if (*g == ';') {
+        /* Stop adding to the current group */
+        building_group = 0;
+        ++grouping;
+      }
+      /* else we ignore the character */
+    }
+
+    if (!repeat_last)
+      *grouping++ = CHAR_MAX;
+    *grouping = 0;
+  }
+}
+
+const char* __ConvertName(const char* lname, LOCALECONV* ConvTable, int TableSize) {
+  int i;
+  int cmp;
+  int low = 0;
+  int high = TableSize - 1;
+
+  /*  typical binary search - do until no more to search or match */
+  while (low <= high) {
+    i = (low + high) / 2;
+
+    if ((cmp = lstrcmpiA(lname, (*(ConvTable + i)).name)) == 0)
+      return (*(ConvTable + i)).abbrev;
+    else if (cmp < 0)
+      high = i - 1;
+    else
+      low = i + 1;
+  }
+  return lname;
+}
+
+int __ParseLocaleString(const char* lname,
+                        char* lang, char* ctry, char* page) {
+  int param = 0;
+  size_t len;
+  size_t tmpLen;
+
+  if (lname[0] == 0)
+    return 0;
+
+  /* We look for the first country separator '_' */
+  len = strcspn(lname, "_");
+  if (lname[len] == '_') {
+    if (len == 0 || len > MAX_LANG_LEN) return -1; /* empty lang is invalid*/
+    _STLP_STRNCPY(lang, MAX_LANG_LEN + 1, lname, len);
+    lname += len + 1;
+    ++param;
+  }
+
+  /* We look for the last code page separator '.' */
+  len = -1;
+  tmpLen = strcspn(lname, ".");
+  while (lname[tmpLen] == '.') {
+    len = tmpLen; ++tmpLen;
+    tmpLen += strcspn(lname + tmpLen, ".");
+  }
+  if (len != -1) { /* Means that we found a '.' */
+    if (param == 0) {
+      /* We have no lang yet so we have to fill it first, no country */
+      if (len > MAX_LANG_LEN) return -1;
+      if (len == 0) {
+        /* No language nor country, only code page */
+        ++param;
+      }
+      else
+      { _STLP_STRNCPY(lang, MAX_LANG_LEN + 1, lname, len); }
+      ++param;
+    }
+    else {
+      /* We already have a lang so we are now looking for the country: */
+      if (len == 0) return -1; /* We forbid locale name with the "_." motif in it */
+      if (len > MAX_CTRY_LEN) return -1;
+      _STLP_STRNCPY(ctry, MAX_CTRY_LEN + 1, lname, len);
+    }
+    ++param;
+    lname += len + 1;
+  }
+
+  /* We look for ',' for compatibility with POSIX */
+  len = strcspn(lname, ",");
+  switch (param) {
+    case 0:
+      if (len > MAX_LANG_LEN) return -1;
+      _STLP_STRNCPY(lang, MAX_LANG_LEN + 1, lname, len);
+      break;
+    case 1:
+      if (len > MAX_CTRY_LEN) return -1;
+      _STLP_STRNCPY(ctry, MAX_CTRY_LEN + 1, lname, len);
+      break;
+    default:
+      if (len > MAX_CP_LEN) return -1;
+      _STLP_STRNCPY(page, MAX_CP_LEN + 1, lname, len);
+      break;
+  }
+
+  /* ',' POSIX modifier is not used in NT */
+  return 0;
+}
+
+/* Data necessary for find LCID*/
+static CRITICAL_SECTION __criticalSection;
+static int __FindFlag;
+static LCID __FndLCID;
+static const char* __FndLang;
+static const char* __FndCtry;
+
+void _Locale_init()
+{ InitializeCriticalSection(&__criticalSection); }
+
+void _Locale_final()
+{ DeleteCriticalSection(&__criticalSection); }
+
+static LCID LocaleFromHex(const char* locale) {
+  unsigned long result = 0;
+  int digit;
+  while (*locale) {
+    result <<= 4;
+    digit = (*locale >= '0' && *locale <= '9') ? *locale - '0':
+            (*locale >= 'A' && *locale <= 'F') ? (*locale - 'A') + 10
+                                               : (*locale - 'a') + 10;
+    result += digit;
+    ++locale;
+  }
+  return (LCID)result;
+}
+
+static BOOL CALLBACK EnumLocalesProcA(LPSTR locale) {
+  LCID lcid = LocaleFromHex(locale);
+  int LangFlag = 0, CtryFlag = !__FndCtry;
+  static char Lang[MAX_LANG_LEN], Ctry[MAX_CTRY_LEN];
+
+  GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, Lang, MAX_LANG_LEN);
+  if (lstrcmpiA(Lang, __FndLang) != 0) {
+    GetLocaleInfoA(lcid, LOCALE_SABBREVLANGNAME, Lang, MAX_LANG_LEN);
+    if (lstrcmpiA(Lang, __FndLang) != 0) {
+      GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, Lang, MAX_LANG_LEN);
+      if (lstrcmpiA(Lang, __FndLang) == 0) LangFlag = 1;
+    }
+    else LangFlag = 1;
+  }
+  else LangFlag = 1;
+
+  if (__FndCtry) {
+    GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, Ctry, MAX_CTRY_LEN);
+    if (lstrcmpiA(Ctry, __FndCtry) != 0) {
+      GetLocaleInfoA(lcid, LOCALE_SABBREVCTRYNAME, Ctry, MAX_CTRY_LEN);
+      if (lstrcmpiA(Ctry, __FndCtry) != 0) {
+        GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, Ctry, MAX_CTRY_LEN);
+        if (lstrcmpiA(Ctry, __FndCtry) == 0) CtryFlag = 1;
+      }
+      else CtryFlag = 1;
+    }
+    else
+      CtryFlag = 1;
+  }
+
+  if (LangFlag && CtryFlag) {
+    __FindFlag = 1;
+    __FndLCID = lcid;
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+int __GetLCID(const char* lang, const char* ctry, LCID* lcid) {
+  int ret;
+  EnterCriticalSection(&__criticalSection);
+
+  __FindFlag = 0;
+  __FndLang = lang;
+  __FndCtry = ctry;
+  EnumSystemLocalesA(EnumLocalesProcA, LCID_INSTALLED);
+
+  if (__FindFlag != 0) *lcid = __FndLCID;
+  ret = __FindFlag != 0 ? 0 : -1;
+
+  LeaveCriticalSection(&__criticalSection);
+  return ret;
+}
+
+int __GetLCIDFromName(const char* lname, LCID* lcid, char* cp, _Locale_lcid_t *hint) {
+  char lang[MAX_LANG_LEN + 1], ctry[MAX_CTRY_LEN + 1], page[MAX_CP_LEN + 1];
+  int result = 0;
+  if (lname == NULL || lname[0] == 0) {
+    *lcid = LOCALE_USER_DEFAULT;
+    return 0;
+  }
+
+  memset(lang, 0, MAX_LANG_LEN + 1);
+  memset(ctry, 0, MAX_CTRY_LEN + 1);
+  memset(page, 0, MAX_CP_LEN + 1);
+  if (__ParseLocaleString(lname, lang, ctry, page) == -1) return -1;
+
+  if (hint != 0) {
+    *lcid = hint->id;
+  }
+  else {
+    if (lang[0] == 0 && ctry[0] == 0)
+      *lcid = LOCALE_USER_DEFAULT; /* Only code page given. */
+    else {
+      if (ctry[0] == 0) {
+        result = __GetLCID(__ConvertName(lang, __rg_language, sizeof(__rg_language) / sizeof(LOCALECONV)), NULL, lcid);
+        if (result != 0) {
+          /* Check 'C' special case. Check is done after call to __GetLCID because normal programs do not
+           * generate facet from 'C' name, they use the locale::classic() facets. */
+          if (lang[0] == 'C' && lang[1] == 0) {
+            *lcid = INVARIANT_LCID;
+            result = 0;
+          }
+        }
+      }
+      else {
+        result = __GetLCID(__ConvertName(lang, __rg_language, sizeof(__rg_language) / sizeof(LOCALECONV)),
+                           __ConvertName(ctry, __rg_country, sizeof(__rg_country) / sizeof(LOCALECONV)),
+                           lcid);
+        if (result != 0) {
+          /* Non NLS mapping might introduce problem with some locales when only one entry is mapped,
+           * the lang or the country (example: chinese locales like 'chinese_taiwan' gives 'CHS_taiwan'
+           * that do not exists in system). This is why we are giving this locale an other chance by
+           * calling __GetLCID without the mapping. */
+          result = __GetLCID(lang, ctry, lcid);
+        }
+      }
+    }
+  }
+
+  if (result == 0) {
+    /* Handling code page */
+    if (lstrcmpiA(page, "ACP") == 0 || page[0] == 0)
+      my_ltoa(__intGetACP(*lcid), cp);
+    else if (lstrcmpiA(page, "OCP") == 0)
+      my_ltoa(__intGetOCP(*lcid), cp);
+    else if (lstrcmpiA(page, "UTF7") == 0)
+      my_ltoa(CP_UTF7, cp);
+    else if (lstrcmpiA(page, "UTF8") == 0)
+      my_ltoa(CP_UTF8, cp);
+    else
+      _STLP_STRNCPY(cp, MAX_CP_LEN + 1, page, 5);
+
+    /* Code page must be an integer value,
+     * 0 returned by __intGetACP and 1 returned by __intGetOCP are invalid
+     * values.
+     */
+    if (cp[1] == 0 && (cp[0] == '0' || cp[1] == '1'))
+      return -1;
+    else if (atoi(cp) == 0)
+      return -1;
+  }
+
+  return result;
+}
+
+char const* __GetLocaleName(LCID lcid, const char* cp, char* buf) {
+  if (lcid == INVARIANT_LCID) {
+    return _C_name;
+  }
+  else {
+    char lang[MAX_LANG_LEN + 1], ctry[MAX_CTRY_LEN + 1];
+    GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, lang, MAX_LANG_LEN);
+    GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, ctry, MAX_CTRY_LEN);
+    _STLP_STRCPY(buf, _Locale_MAX_SIMPLE_NAME, lang);
+    _STLP_STRCAT(buf, _Locale_MAX_SIMPLE_NAME, "_");
+    _STLP_STRCAT(buf, _Locale_MAX_SIMPLE_NAME, ctry);
+    _STLP_STRCAT(buf, _Locale_MAX_SIMPLE_NAME, ".");
+    _STLP_STRCAT(buf, _Locale_MAX_SIMPLE_NAME, cp);
+    return buf;
+  }
+}
+
+char const* __Extract_locale_name(const char* loc, const char* category, char* buf) {
+  char *expr;
+  size_t len_name;
+
+  if (loc[0] == 'L' && loc[1] == 'C' && loc[2] == '_') {
+    expr = strstr((char*)loc, category);
+    if (expr == NULL) return NULL; /* Category not found. */
+    expr = strchr(expr, '=');
+    if (expr == NULL) return NULL;
+    ++expr;
+    len_name = strcspn(expr, ";");
+    len_name = len_name >= _Locale_MAX_SIMPLE_NAME ? _Locale_MAX_SIMPLE_NAME - 1
+                                                   : len_name;
+    _STLP_STRNCPY(buf, _Locale_MAX_SIMPLE_NAME, expr, len_name); buf[len_name] = 0;
+    return buf;
+  }
+  else {
+    return loc;
+  }
+}
+
+char const* __TranslateToSystem(const char* lname, char* buf, _Locale_lcid_t* hint,
+                                int *__err_code) {
+  LCID lcid;
+  char cp[MAX_CP_LEN + 1];
+  if (__GetLCIDFromName(lname, &lcid, cp, hint) != 0)
+  { *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+  return __GetLocaleName(lcid, cp, buf);
+}
+
+void __GetLocaleInfoUsingACP(LCID lcid, const char* cp, LCTYPE lctype, char* buf, int buf_size, wchar_t* wbuf, int wbuf_size) {
+  wchar_t *Buffer;
+  int BufferSize;
+  int icp;
+
+  GetLocaleInfoA(lcid, lctype, buf, buf_size);
+
+  icp = atoi(cp);
+  if (icp != CP_ACP && buf[0] != 0) {
+    BufferSize = MultiByteToWideChar(CP_ACP, 0, buf, -1, NULL, 0);
+    if (BufferSize > wbuf_size)
+    {
+      Buffer = (wchar_t*)malloc(sizeof(wchar_t) * BufferSize);
+    }
+    else
+    {
+      Buffer = wbuf;
+    }
+    MultiByteToWideChar(CP_ACP, 0, buf, -1, Buffer, BufferSize);
+    WideCharToMultiByte(icp, 0, Buffer, -1, buf, buf_size, NULL, NULL);
+    if (Buffer != wbuf)
+    {
+      free(Buffer);
+    }
+  }
+}
+
+/* Return 0 if ANSI code page not used */
+int __intGetACP(LCID lcid) {
+  char cp[6];
+  if (!GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, cp, 6)) {
+#if defined (_STLP_LANG_INVARIANT_DEFINED)
+    if (lcid == INVARIANT_LCID) {
+      /* We are using a limited PSDK, we rely on the most common code page */
+      return 1252;
+    }
+#endif
+    return 0;
+  }
+  return atoi(cp);
+}
+
+/* Return 1 if OEM code page not used */
+int __intGetOCP(LCID lcid) {
+  char cp[6];
+  if (!GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE, cp, 6))
+    return 0;
+  return atoi(cp);
+}
+
+int __GetDefaultCP(LCID lcid) {
+  int cp = __intGetACP(lcid);
+  if (cp == 0) return __intGetOCP(lcid);
+  else return cp;
+}
+
+static int trim_size_t_to_int(size_t n) { return n < (size_t)INT_MAX ? (int)n : INT_MAX; }
+
+char* __ConvertToCP(int from_cp, int to_cp, const char *from, size_t size, size_t *ret_buf_size) {
+  size_t wbuffer_size, buffer_size, from_offset, wbuf_offset;
+  int from_size, to_size, wbuf_size;
+  wchar_t *wbuffer;
+  char* buffer;
+
+  size_t orig_size = size;
+
+  wbuffer_size = 0;
+  from_offset = 0;
+  while (size > 0) {
+    from_size = trim_size_t_to_int(size);
+    wbuffer_size += MultiByteToWideChar(from_cp, MB_PRECOMPOSED,
+                                        from + from_offset, from_size, NULL, 0);
+    from_offset += from_size;
+    size -= from_size;
+  }
+
+  wbuffer = (wchar_t*)malloc(sizeof(wchar_t)*wbuffer_size);
+
+  size = orig_size;
+  wbuf_offset = 0;
+  from_offset = 0;
+  while (size > 0) {
+    from_size = trim_size_t_to_int(size);
+    wbuf_size = trim_size_t_to_int(wbuffer_size - wbuf_offset);
+    wbuf_offset += MultiByteToWideChar(from_cp, MB_PRECOMPOSED,
+                                       from + from_offset, from_size, wbuffer + wbuf_offset, wbuf_size);
+    from_offset += from_size;
+    size -= from_size;
+  }
+
+  buffer_size = 0;
+  wbuf_offset = 0;
+  size = wbuffer_size;
+  while (size > 0) {
+    wbuf_size = trim_size_t_to_int(size);
+    buffer_size += WideCharToMultiByte(to_cp, WC_COMPOSITECHECK | WC_SEPCHARS,
+                                       wbuffer + wbuf_offset, wbuf_size,
+                                       NULL, 0, NULL, FALSE);
+    wbuf_offset += wbuf_size;
+    size -= wbuf_size;
+  }
+
+  buffer = (char*)malloc(buffer_size);
+  *ret_buf_size = buffer_size;
+
+  size = wbuffer_size;
+  wbuf_offset = 0;
+  while (size > 0) {
+    wbuf_size = trim_size_t_to_int(size);
+    to_size = trim_size_t_to_int(buffer_size);
+    buffer_size -= WideCharToMultiByte(to_cp, WC_COMPOSITECHECK | WC_SEPCHARS,
+                                       wbuffer + wbuf_offset, wbuf_size,
+                                       buffer, to_size, NULL, FALSE);
+    wbuf_offset += wbuf_size;
+    size -= wbuf_size;
+  }
+
+  free(wbuffer);
+  return buffer;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef _STLP_NO_WCHAR_T
+#  include "c_wlocale_win32.c"
+#endif
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale_win32/c_wlocale_win32.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2007 2008
+ * Francois Dumont
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
+#  define _STLP_WCSNCPY(D, DS, S, C) wcsncpy_s(D, DS, S, C)
+#else
+#  define _STLP_WCSNCPY(D, DS, S, C) wcsncpy(D, S, C)
+#endif
+
+static const wchar_t* __wtrue_name = L"true";
+static const wchar_t* __wfalse_name = L"false";
+
+typedef struct _Locale_codecvt {
+  _Locale_lcid_t lc;
+  UINT cp;
+  unsigned char cleads[256 / CHAR_BIT];
+  unsigned char max_char_size;
+  DWORD mbtowc_flags;
+  DWORD wctomb_flags;
+} _Locale_codecvt_t;
+
+/* Ctype */
+_Locale_mask_t _WLocale_ctype(_Locale_ctype_t* ltype, wint_t c,
+                              _Locale_mask_t which_bits) {
+  wchar_t buf[2];
+  WORD out[2];
+  buf[0] = c; buf[1] = 0;
+  GetStringTypeW(CT_CTYPE1, buf, -1, out);
+  _STLP_MARK_PARAMETER_AS_UNUSED(ltype)
+  return (_Locale_mask_t)(MapCtypeMask(out[0]) & which_bits);
+}
+
+wint_t _WLocale_tolower(_Locale_ctype_t* ltype, wint_t c) {
+  wchar_t in_c = c;
+  wchar_t res;
+
+  LCMapStringW(ltype->lc.id, LCMAP_LOWERCASE, &in_c, 1, &res, 1);
+  return res;
+}
+
+wint_t _WLocale_toupper(_Locale_ctype_t* ltype, wint_t c) {
+  wchar_t in_c = c;
+  wchar_t res;
+
+  LCMapStringW(ltype->lc.id, LCMAP_UPPERCASE, &in_c, 1, &res, 1);
+  return res;
+}
+
+_Locale_codecvt_t* _Locale_codecvt_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  char cp_name[MAX_CP_LEN + 1];
+  unsigned char *ptr;
+  CPINFO CPInfo;
+  int i;
+
+  _Locale_codecvt_t *lcodecvt = (_Locale_codecvt_t*)malloc(sizeof(_Locale_codecvt_t));
+
+  if (!lcodecvt) { *__err_code = _STLP_LOC_NO_MEMORY; return lcodecvt; }
+  memset(lcodecvt, 0, sizeof(_Locale_codecvt_t));
+
+  if (__GetLCIDFromName(name, &lcodecvt->lc.id, cp_name, lc_hint) == -1)
+  { free(lcodecvt); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+  lcodecvt->cp = atoi(cp_name);
+  if (!GetCPInfo(lcodecvt->cp, &CPInfo)) { free(lcodecvt); return NULL; }
+
+  if (lcodecvt->cp != CP_UTF7 && lcodecvt->cp != CP_UTF8) {
+    lcodecvt->mbtowc_flags = MB_PRECOMPOSED;
+    lcodecvt->wctomb_flags = WC_COMPOSITECHECK | WC_SEPCHARS;
+  }
+  lcodecvt->max_char_size = CPInfo.MaxCharSize;
+
+  if (CPInfo.MaxCharSize > 1) {
+    for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr += 2)
+      for (i = *ptr; i <= *(ptr + 1); ++i) lcodecvt->cleads[i / CHAR_BIT] |= (0x01 << i % CHAR_BIT);
+  }
+
+  return lcodecvt;
+}
+
+char const* _Locale_codecvt_name(const _Locale_codecvt_t* lcodecvt, char* buf) {
+  char cp_buf[MAX_CP_LEN + 1];
+  my_ltoa(lcodecvt->cp, cp_buf);
+  return __GetLocaleName(lcodecvt->lc.id, cp_buf, buf);
+}
+
+void _Locale_codecvt_destroy(_Locale_codecvt_t* lcodecvt) {
+  if (!lcodecvt) return;
+
+  free(lcodecvt);
+}
+
+int _WLocale_mb_cur_max (_Locale_codecvt_t * lcodecvt)
+{ return lcodecvt->max_char_size; }
+
+int _WLocale_mb_cur_min (_Locale_codecvt_t *lcodecvt) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt)
+  return 1;
+}
+
+int _WLocale_is_stateless (_Locale_codecvt_t * lcodecvt)
+{ return (lcodecvt->max_char_size == 1) ? 1 : 0; }
+
+static int __isleadbyte(int i, unsigned char *ctable) {
+  unsigned char c = (unsigned char)i;
+  return (ctable[c / CHAR_BIT] & (0x01 << c % CHAR_BIT));
+}
+
+static int __mbtowc(_Locale_codecvt_t *l, wchar_t *dst, const char *from, unsigned int count) {
+  int result;
+
+  if (l->cp == CP_UTF7 || l->cp == CP_UTF8) {
+    result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1);
+    if (result == 0) {
+      switch (GetLastError()) {
+        case ERROR_NO_UNICODE_TRANSLATION:
+          return -2;
+        default:
+          return -1;
+      }
+    }
+  }
+  else {
+    if (count == 1 && __isleadbyte(*from, l->cleads)) return (size_t)-2;
+    result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1);
+    if (result == 0) return -1;
+  }
+
+  return result;
+}
+
+size_t _WLocale_mbtowc(_Locale_codecvt_t *lcodecvt, wchar_t *to,
+                       const char *from, size_t n, mbstate_t *shift_state) {
+  int result;
+  _STLP_MARK_PARAMETER_AS_UNUSED(shift_state)
+  if (lcodecvt->max_char_size == 1) { /* Single byte encoding. */
+    result = MultiByteToWideChar(lcodecvt->cp, lcodecvt->mbtowc_flags, from, 1, to, 1);
+    if (result == 0) return (size_t)-1;
+    return result;
+  }
+  else { /* Multi byte encoding. */
+    int retval;
+    unsigned int count = 1;
+    while (n--) {
+      retval = __mbtowc(lcodecvt, to, from, count);
+      if (retval == -2)
+      { if (++count > ((unsigned int)lcodecvt->max_char_size)) return (size_t)-1; }
+      else if (retval == -1)
+      { return (size_t)-1; }
+      else
+      { return count; }
+    }
+    return (size_t)-2;
+  }
+}
+
+size_t _WLocale_wctomb(_Locale_codecvt_t *lcodecvt, char *to, size_t n,
+                       const wchar_t c, mbstate_t *shift_state) {
+  int size = WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, NULL, 0, NULL, NULL);
+
+  if (!size) return (size_t)-1;
+  if ((size_t)size > n) return (size_t)-2;
+
+  if (n > INT_MAX)
+    /* Limiting the output buf size to INT_MAX seems like reasonable to transform a single wchar_t. */
+    n = INT_MAX;
+
+  WideCharToMultiByte(lcodecvt->cp,  lcodecvt->wctomb_flags, &c, 1, to, (int)n, NULL, NULL);
+
+  _STLP_MARK_PARAMETER_AS_UNUSED(shift_state)
+  return (size_t)size;
+}
+
+size_t _WLocale_unshift(_Locale_codecvt_t *lcodecvt, mbstate_t *st,
+                        char *buf, size_t n, char **next) {
+  /* _WLocale_wctomb do not even touch to st, there is nothing to unshift in this localization implementation. */
+  _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt)
+  _STLP_MARK_PARAMETER_AS_UNUSED(st)
+  _STLP_MARK_PARAMETER_AS_UNUSED(&n)
+  *next = buf;
+  return 0;
+}
+
+/* Collate */
+/* This function takes care of the potential size_t DWORD different size. */
+static int _WLocale_strcmp_aux(_Locale_collate_t* lcol,
+                               const wchar_t* s1, size_t n1,
+                               const wchar_t* s2, size_t n2) {
+  int result = CSTR_EQUAL;
+  while (n1 > 0 || n2 > 0) {
+    DWORD size1 = trim_size_t_to_DWORD(n1);
+    DWORD size2 = trim_size_t_to_DWORD(n2);
+    result = CompareStringW(lcol->lc.id, 0, s1, size1, s2, size2);
+    if (result != CSTR_EQUAL)
+      break;
+    n1 -= size1;
+    n2 -= size2;
+  }
+  return result;
+}
+
+int _WLocale_strcmp(_Locale_collate_t* lcol,
+                    const wchar_t* s1, size_t n1,
+                    const wchar_t* s2, size_t n2) {
+  int result;
+  result = _WLocale_strcmp_aux(lcol, s1, n1, s2, n2);
+  return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1;
+}
+
+size_t _WLocale_strxfrm(_Locale_collate_t* lcol,
+                        wchar_t* dst, size_t dst_size,
+                        const wchar_t* src, size_t src_size) {
+  int result, i;
+
+  /* see _Locale_strxfrm: */
+  if (src_size > INT_MAX) {
+    if (dst != 0) {
+      _STLP_WCSNCPY(dst, dst_size, src, src_size);
+    }
+    return src_size;
+  }
+  if (dst_size > INT_MAX) {
+    dst_size = INT_MAX;
+  }
+  result = LCMapStringW(lcol->lc.id, LCMAP_SORTKEY, src, (int)src_size, dst, (int)dst_size);
+  if (result != 0 && dst != 0) {
+    for (i = result - 1; i >= 0; --i) {
+      dst[i] = ((unsigned char*)dst)[i];
+    }
+  }
+  return result != 0 ? result - 1 : 0;
+}
+
+/* Numeric */
+wchar_t _WLocale_decimal_point(_Locale_numeric_t* lnum) {
+  wchar_t buf[4];
+  GetLocaleInfoW(lnum->lc.id, LOCALE_SDECIMAL, buf, 4);
+  return buf[0];
+}
+
+wchar_t _WLocale_thousands_sep(_Locale_numeric_t* lnum) {
+  wchar_t buf[4];
+  GetLocaleInfoW(lnum->lc.id, LOCALE_STHOUSAND, buf, 4);
+  return buf[0];
+}
+
+const wchar_t * _WLocale_true(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lnum)
+  _STLP_MARK_PARAMETER_AS_UNUSED(buf)
+  _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize)
+  return __wtrue_name;
+}
+
+const wchar_t * _WLocale_false(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lnum)
+  _STLP_MARK_PARAMETER_AS_UNUSED(buf)
+  _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize)
+  return __wfalse_name;
+}
+
+/* Monetary */
+const wchar_t* _WLocale_int_curr_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(lmon->lc.id, LOCALE_SINTLSYMBOL, buf, (int)bufSize); return buf; }
+
+const wchar_t* _WLocale_currency_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(lmon->lc.id, LOCALE_SCURRENCY, buf, (int)bufSize); return buf; }
+
+wchar_t _WLocale_mon_decimal_point(_Locale_monetary_t * lmon)
+{ return lmon->decimal_point[0]; }
+
+wchar_t _WLocale_mon_thousands_sep(_Locale_monetary_t * lmon)
+{ return lmon->thousands_sep[0]; }
+
+const wchar_t* _WLocale_positive_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(lmon->lc.id, LOCALE_SPOSITIVESIGN, buf, (int)bufSize); return buf; }
+
+const wchar_t* _WLocale_negative_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(lmon->lc.id, LOCALE_SNEGATIVESIGN, buf, (int)bufSize); return buf; }
+
+/* Time */
+const wchar_t * _WLocale_full_monthname(_Locale_time_t * ltime, int month,
+                                        wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(ltime->lc.id, LOCALE_SMONTHNAME1 + month, buf, (int)bufSize); return buf; }
+
+const wchar_t * _WLocale_abbrev_monthname(_Locale_time_t * ltime, int month,
+                                          wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVMONTHNAME1 + month, buf, (int)bufSize); return buf; }
+
+const wchar_t * _WLocale_full_dayofweek(_Locale_time_t * ltime, int day,
+                                        wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(ltime->lc.id, LOCALE_SDAYNAME1 + day, buf, (int)bufSize); return buf; }
+
+const wchar_t * _WLocale_abbrev_dayofweek(_Locale_time_t * ltime, int day,
+                                          wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVDAYNAME1 + day, buf, (int)bufSize); return buf; }
+
+const wchar_t* _WLocale_am_str(_Locale_time_t* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(ltime->lc.id, LOCALE_S1159, buf, (int)bufSize); return buf; }
+
+const wchar_t* _WLocale_pm_str(_Locale_time_t* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ GetLocaleInfoW(ltime->lc.id, LOCALE_S2359, buf, (int)bufSize); return buf; }
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/codecvt.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+#include "stlport_prefix.h"
+
+#include <locale>
+#include <algorithm>
+
+_STLP_BEGIN_NAMESPACE
+
+//----------------------------------------------------------------------
+// codecvt<char, char, mbstate_t>
+
+codecvt<char, char, mbstate_t>::~codecvt() {}
+
+int codecvt<char, char, mbstate_t>::do_length(state_type&,
+                                              const  char* from,
+                                              const  char* end,
+                                              size_t mx) const
+{ return (int)(min) ( __STATIC_CAST(size_t, (end - from)), mx); }
+
+int codecvt<char, char, mbstate_t>::do_max_length() const _STLP_NOTHROW
+{ return 1; }
+
+bool
+codecvt<char, char, mbstate_t>::do_always_noconv() const _STLP_NOTHROW
+{ return true; }
+
+int
+codecvt<char, char, mbstate_t>::do_encoding() const _STLP_NOTHROW
+{ return 1; }
+
+codecvt_base::result
+codecvt<char, char, mbstate_t>::do_unshift(state_type& /* __state */,
+                                           char*       __to,
+                                           char*       /* __to_limit */,
+                                           char*&      __to_next) const
+{ __to_next = __to; return noconv; }
+
+codecvt_base::result
+codecvt<char, char, mbstate_t>::do_in (state_type&  /* __state */ ,
+                                       const char*  __from,
+                                       const char*  /* __from_end */,
+                                       const char*& __from_next,
+                                       char*        __to,
+                                       char*        /* __to_end */,
+                                       char*&       __to_next) const
+{ __from_next = __from; __to_next   = __to; return noconv; }
+
+codecvt_base::result
+codecvt<char, char, mbstate_t>::do_out(state_type&  /* __state */,
+                                       const char*  __from,
+                                       const char*  /* __from_end */,
+                                       const char*& __from_next,
+                                       char*        __to,
+                                       char*        /* __to_limit */,
+                                       char*&       __to_next) const
+{ __from_next = __from; __to_next   = __to; return noconv; }
+
+
+#if !defined (_STLP_NO_WCHAR_T)
+//----------------------------------------------------------------------
+// codecvt<wchar_t, char, mbstate_t>
+
+codecvt<wchar_t, char, mbstate_t>::~codecvt() {}
+
+
+codecvt<wchar_t, char, mbstate_t>::result
+codecvt<wchar_t, char, mbstate_t>::do_out(state_type&         /* state */,
+                                          const intern_type*  from,
+                                          const intern_type*  from_end,
+                                          const intern_type*& from_next,
+                                          extern_type*        to,
+                                          extern_type*        to_limit,
+                                          extern_type*&       to_next) const {
+  ptrdiff_t len = (min) (from_end - from, to_limit - to);
+  copy(from, from + len, to);
+  from_next = from + len;
+  to_next   = to   + len;
+  return ok;
+}
+
+codecvt<wchar_t, char, mbstate_t>::result
+codecvt<wchar_t, char, mbstate_t>::do_in (state_type&       /* state */,
+                                          const extern_type*  from,
+                                          const extern_type*  from_end,
+                                          const extern_type*& from_next,
+                                          intern_type*        to,
+                                          intern_type*        to_limit,
+                                          intern_type*&       to_next) const {
+  ptrdiff_t len = (min) (from_end - from, to_limit - to);
+  copy(__REINTERPRET_CAST(const unsigned char*, from),
+       __REINTERPRET_CAST(const unsigned char*, from) + len, to);
+  from_next = from + len;
+  to_next   = to   + len;
+  return ok;
+}
+
+codecvt<wchar_t, char, mbstate_t>::result
+codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type&   /* state */,
+                                              extern_type*  to,
+                                              extern_type*  ,
+                                              extern_type*& to_next) const {
+  to_next = to;
+  return noconv;
+}
+
+int codecvt<wchar_t, char, mbstate_t>::do_encoding() const _STLP_NOTHROW
+{ return 1; }
+
+bool codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _STLP_NOTHROW
+{ return true; }
+
+int codecvt<wchar_t, char, mbstate_t>::do_length(state_type&,
+                                                 const  extern_type* from,
+                                                 const  extern_type* end,
+                                                 size_t mx) const
+{ return (int)(min) ((size_t) (end - from), mx); }
+
+int codecvt<wchar_t, char, mbstate_t>::do_max_length() const _STLP_NOTHROW
+{ return 1; }
+#endif /* wchar_t */
+
+_STLP_END_NAMESPACE
+
+// Local Variables:
+// mode:C++
+// End:
+
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/collate.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+#include "stlport_prefix.h"
+
+#include <locale>
+
+_STLP_BEGIN_NAMESPACE
+
+// collate<char>
+
+collate<char>::~collate() {}
+
+int collate<char>::do_compare(const char* low1, const char* high1,
+                              const char* low2, const char* high2) const
+{ return _STLP_PRIV __lexicographical_compare_3way(low1, high1, low2, high2); }
+
+string collate<char>::do_transform(const char* low, const char* high) const
+{ return string(low, high); }
+
+long collate<char>::do_hash(const char* low, const char* high) const {
+  unsigned long result = 0;
+  for ( ; low < high; ++low)
+    result = 5 * result + *low;
+  return result;
+}
+
+#if !defined (_STLP_NO_WCHAR_T)
+// collate<wchar_t>
+
+collate<wchar_t>::~collate() {}
+
+int
+collate<wchar_t>::do_compare(const wchar_t* low1, const wchar_t* high1,
+                             const wchar_t* low2, const wchar_t* high2) const
+{ return _STLP_PRIV __lexicographical_compare_3way(low1, high1, low2, high2); }
+
+wstring collate<wchar_t>::do_transform(const wchar_t* low, const wchar_t* high) const
+{ return wstring(low, high); }
+
+long collate<wchar_t>::do_hash(const wchar_t* low, const wchar_t* high) const {
+  unsigned long result = 0;
+  for ( ; low < high; ++low)
+    result = 5 * result + *low;
+  return result;
+}
+#endif
+
+_STLP_END_NAMESPACE
+
+
+// Local Variables:
+// mode:C++
+// End:
+
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/complex.cpp
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include "stlport_prefix.h"
+
+#include <numeric>
+#include <cmath>
+#include <complex>
+
+#if defined (_STLP_MSVC_LIB) && (_STLP_MSVC_LIB >= 1400)
+// hypot is deprecated.
+#  if defined (_STLP_MSVC)
+#    pragma warning (disable : 4996)
+#  elif defined (__ICL)
+#    pragma warning (disable : 1478)
+#  endif
+#endif
+
+_STLP_BEGIN_NAMESPACE
+
+// Complex division and square roots.
+
+// Absolute value
+_STLP_TEMPLATE_NULL
+_STLP_DECLSPEC float _STLP_CALL abs(const complex<float>& __z)
+{ return ::hypot(__z._M_re, __z._M_im); }
+_STLP_TEMPLATE_NULL
+_STLP_DECLSPEC double _STLP_CALL abs(const complex<double>& __z)
+{ return ::hypot(__z._M_re, __z._M_im); }
+
+#if !defined (_STLP_NO_LONG_DOUBLE)
+_STLP_TEMPLATE_NULL
+_STLP_DECLSPEC long double _STLP_CALL abs(const complex<long double>& __z)
+{ return ::hypot(__z._M_re, __z._M_im); }
+#endif
+
+// Phase
+
+_STLP_TEMPLATE_NULL
+_STLP_DECLSPEC float _STLP_CALL arg(const complex<float>& __z)
+{ return ::atan2(__z._M_im, __z._M_re); }
+
+_STLP_TEMPLATE_NULL
+_STLP_DECLSPEC double _STLP_CALL arg(const complex<double>& __z)
+{ return ::atan2(__z._M_im, __z._M_re); }
+
+#if !defined (_STLP_NO_LONG_DOUBLE)
+_STLP_TEMPLATE_NULL
+_STLP_DECLSPEC long double _STLP_CALL arg(const complex<long double>& __z)
+{ return ::atan2(__z._M_im, __z._M_re); }
+#endif
+
+// Construct a complex number from polar representation
+_STLP_TEMPLATE_NULL
+_STLP_DECLSPEC complex<float> _STLP_CALL polar(const float& __rho, const float& __phi)
+{ return complex<float>(__rho * ::cos(__phi), __rho * ::sin(__phi)); }
+_STLP_TEMPLATE_NULL
+_STLP_DECLSPEC complex<double> _STLP_CALL polar(const double& __rho, const double& __phi)
+{ return complex<double>(__rho * ::cos(__phi), __rho * ::sin(__phi)); }
+
+#if !defined (_STLP_NO_LONG_DOUBLE)
+_STLP_TEMPLATE_NULL
+_STLP_DECLSPEC complex<long double> _STLP_CALL polar(const long double& __rho, const long double& __phi)
+{ return complex<long double>(__rho * ::cos(__phi), __rho * ::sin(__phi)); }
+#endif
+
+// Division
+template <class _Tp>
+static void _divT(const _Tp& __z1_r, const _Tp& __z1_i,
+                  const _Tp& __z2_r, const _Tp& __z2_i,
+                  _Tp& __res_r, _Tp& __res_i) {
+  _Tp __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
+  _Tp __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
+
+  if (__ar <= __ai) {
+    _Tp __ratio = __z2_r / __z2_i;
+    _Tp __denom = __z2_i * (1 + __ratio * __ratio);
+    __res_r = (__z1_r * __ratio + __z1_i) / __denom;
+    __res_i = (__z1_i * __ratio - __z1_r) / __denom;
+  }
+  else {
+    _Tp __ratio = __z2_i / __z2_r;
+    _Tp __denom = __z2_r * (1 + __ratio * __ratio);
+    __res_r = (__z1_r + __z1_i * __ratio) / __denom;
+    __res_i = (__z1_i - __z1_r * __ratio) / __denom;
+  }
+}
+
+template <class _Tp>
+static void _divT(const _Tp& __z1_r,
+                  const _Tp& __z2_r, const _Tp& __z2_i,
+                  _Tp& __res_r, _Tp& __res_i) {
+  _Tp __ar = __z2_r >= 0 ? __z2_r : -__z2_r;
+  _Tp __ai = __z2_i >= 0 ? __z2_i : -__z2_i;
+
+  if (__ar <= __ai) {
+    _Tp __ratio = __z2_r / __z2_i;
+    _Tp __denom = __z2_i * (1 + __ratio * __ratio);
+    __res_r = (__z1_r * __ratio) / __denom;
+    __res_i = - __z1_r / __denom;
+  }
+  else {
+    _Tp __ratio = __z2_i / __z2_r;
+    _Tp __denom = __z2_r * (1 + __ratio * __ratio);
+    __res_r = __z1_r / __denom;
+    __res_i = - (__z1_r * __ratio) / __denom;
+  }
+}
+
+void _STLP_CALL
+complex<float>::_div(const float& __z1_r, const float& __z1_i,
+                     const float& __z2_r, const float& __z2_i,
+                     float& __res_r, float& __res_i)
+{ _divT(__z1_r, __z1_i, __z2_r, __z2_i, __res_r, __res_i); }
+
+void _STLP_CALL
+complex<float>::_div(const float& __z1_r,
+                     const float& __z2_r, const float& __z2_i,
+                     float& __res_r, float& __res_i)
+{ _divT(__z1_r, __z2_r, __z2_i, __res_r, __res_i); }
+
+
+void  _STLP_CALL
+complex<double>::_div(const double& __z1_r, const double& __z1_i,
+                      const double& __z2_r, const double& __z2_i,
+                      double& __res_r, double& __res_i)
+{ _divT(__z1_r, __z1_i, __z2_r, __z2_i, __res_r, __res_i); }
+
+void _STLP_CALL
+complex<double>::_div(const double& __z1_r,
+                      const double& __z2_r, const double& __z2_i,
+                      double& __res_r, double& __res_i)
+{ _divT(__z1_r, __z2_r, __z2_i, __res_r, __res_i); }
+
+#if !defined (_STLP_NO_LONG_DOUBLE)
+void  _STLP_CALL
+complex<long double>::_div(const long double& __z1_r, const long double& __z1_i,
+                           const long double& __z2_r, const long double& __z2_i,
+                           long double& __res_r, long double& __res_i)
+{ _divT(__z1_r, __z1_i, __z2_r, __z2_i, __res_r, __res_i); }
+
+void _STLP_CALL
+complex<long double>::_div(const long double& __z1_r,
+                           const long double& __z2_r, const long double& __z2_i,
+                           long double& __res_r, long double& __res_i)
+{ _divT(__z1_r, __z2_r, __z2_i, __res_r, __res_i); }
+#endif
+
+//----------------------------------------------------------------------
+// Square root
+template <class _Tp>
+static complex<_Tp> sqrtT(const complex<_Tp>& z) {
+  _Tp re = z._M_re;
+  _Tp im = z._M_im;
+  _Tp mag = ::hypot(re, im);
+  complex<_Tp> result;
+
+  if (mag == 0.f) {
+    result._M_re = result._M_im = 0.f;
+  } else if (re > 0.f) {
+    result._M_re = ::sqrt(0.5f * (mag + re));
+    result._M_im = im/result._M_re/2.f;
+  } else {
+    result._M_im = ::sqrt(0.5f * (mag - re));
+    if (im < 0.f)
+      result._M_im = - result._M_im;
+    result._M_re = im/result._M_im/2.f;
+  }
+  return result;
+}
+
+complex<float> _STLP_CALL
+sqrt(const complex<float>& z) { return sqrtT(z); }
+
+complex<double>  _STLP_CALL
+sqrt(const complex<double>& z) { return sqrtT(z); }
+
+#if !defined (_STLP_NO_LONG_DOUBLE)
+complex<long double> _STLP_CALL
+sqrt(const complex<long double>& z) { return sqrtT(z); }
+#endif
+
+// exp, log, pow for complex<float>, complex<double>, and complex<long double>
+//----------------------------------------------------------------------
+// exp
+template <class _Tp>
+static complex<_Tp> expT(const complex<_Tp>& z) {
+  _Tp expx = ::exp(z._M_re);
+  return complex<_Tp>(expx * ::cos(z._M_im),
+                      expx * ::sin(z._M_im));
+}
+_STLP_DECLSPEC complex<float>  _STLP_CALL exp(const complex<float>& z)
+{ return expT(z); }
+
+_STLP_DECLSPEC complex<double> _STLP_CALL exp(const complex<double>& z)
+{ return expT(z); }
+
+#if !defined (_STLP_NO_LONG_DOUBLE)
+_STLP_DECLSPEC complex<long double> _STLP_CALL exp(const complex<long double>& z)
+{ return expT(z); }
+#endif
+
+//----------------------------------------------------------------------
+// log10
+template <class _Tp>
+static complex<_Tp> log10T(const complex<_Tp>& z, const _Tp& ln10_inv) {
+  complex<_Tp> r;
+
+  r._M_im = ::atan2(z._M_im, z._M_re) * ln10_inv;
+  r._M_re = ::log10(::hypot(z._M_re, z._M_im));
+  return r;
+}
+
+_STLP_DECLSPEC complex<float> _STLP_CALL log10(const complex<float>& z)
+{
+  const float LN10_INVF = 1.f / ::log(10.f);
+  return log10T(z, LN10_INVF);
+}
+
+_STLP_DECLSPEC complex<double> _STLP_CALL log10(const complex<double>& z)
+{
+  const double LN10_INV = 1. / ::log10(10.);
+  return log10T(z, LN10_INV);
+}
+
+#if !defined (_STLP_NO_LONG_DOUBLE)
+_STLP_DECLSPEC complex<long double> _STLP_CALL log10(const complex<long double>& z)
+{
+  const long double LN10_INVL = 1.l / ::log(10.l);
+  return log10T(z, LN10_INVL);
+}
+#endif
+
+//----------------------------------------------------------------------
+// log
+template <class _Tp>
+static complex<_Tp> logT(const complex<_Tp>& z) {
+  complex<_Tp> r;
+
+  r._M_im = ::atan2(z._M_im, z._M_re);
+  r._M_re = ::log(::hypot(z._M_re, z._M_im));
+  return r;
+}
+_STLP_DECLSPEC complex<float> _STLP_CALL log(const complex<float>& z)
+{ return logT(z); }
+
+_STLP_DECLSPEC complex<double> _STLP_CALL log(const complex<double>& z)
+{ return logT(z); }
+
+#ifndef _STLP_NO_LONG_DOUBLE
+_STLP_DECLSPEC complex<long double> _STLP_CALL log(const complex<long double>& z)
+{ return logT(z); }
+# endif
+
+//----------------------------------------------------------------------
+// pow
+template <class _Tp>
+static complex<_Tp> powT(const _Tp& a, const complex<_Tp>& b) {
+  _Tp logr = ::log(a);
+  _Tp x = ::exp(logr * b._M_re);
+  _Tp y = logr * b._M_im;
+
+  return complex<_Tp>(x * ::cos(y), x * ::sin(y));
+}
+
+template <class _Tp>
+static complex<_Tp> powT(const complex<_Tp>& z_in, int n) {
+  complex<_Tp> z = z_in;
+  z = _STLP_PRIV __power(z, (n < 0 ? -n : n), multiplies< complex<_Tp> >());
+  if (n < 0)
+    return _Tp(1.0) / z;
+  else
+    return z;
+}
+
+template <class _Tp>
+static complex<_Tp> powT(const complex<_Tp>& a, const _Tp& b) {
+  _Tp logr = ::log(::hypot(a._M_re,a._M_im));
+  _Tp logi = ::atan2(a._M_im, a._M_re);
+  _Tp x = ::exp(logr * b);
+  _Tp y = logi * b;
+
+  return complex<_Tp>(x * ::cos(y), x * ::sin(y));
+}
+
+template <class _Tp>
+static complex<_Tp> powT(const complex<_Tp>& a, const complex<_Tp>& b) {
+  _Tp logr = ::log(::hypot(a._M_re,a._M_im));
+  _Tp logi = ::atan2(a._M_im, a._M_re);
+  _Tp x = ::exp(logr * b._M_re - logi * b._M_im);
+  _Tp y = logr * b._M_im + logi * b._M_re;
+
+  return complex<_Tp>(x * ::cos(y), x * ::sin(y));
+}
+
+_STLP_DECLSPEC complex<float> _STLP_CALL pow(const float& a, const complex<float>& b)
+{ return powT(a, b); }
+
+_STLP_DECLSPEC complex<float> _STLP_CALL pow(const complex<float>& z_in, int n)
+{ return powT(z_in, n); }
+
+_STLP_DECLSPEC complex<float> _STLP_CALL pow(const complex<float>& a, const float& b)
+{ return powT(a, b); }
+
+_STLP_DECLSPEC complex<float> _STLP_CALL pow(const complex<float>& a, const complex<float>& b)
+{ return powT(a, b); }
+
+_STLP_DECLSPEC complex<double> _STLP_CALL pow(const double& a, const complex<double>& b)
+{ return powT(a, b); }
+
+_STLP_DECLSPEC complex<double> _STLP_CALL pow(const complex<double>& z_in, int n)
+{ return powT(z_in, n); }
+
+_STLP_DECLSPEC complex<double> _STLP_CALL pow(const complex<double>& a, const double& b)
+{ return powT(a, b); }
+
+_STLP_DECLSPEC complex<double> _STLP_CALL pow(const complex<double>& a, const complex<double>& b)
+{ return powT(a, b); }
+
+#if !defined (_STLP_NO_LONG_DOUBLE)
+_STLP_DECLSPEC complex<long double> _STLP_CALL pow(const long double& a,
+                                                   const complex<long double>& b)
+{ return powT(a, b); }
+
+
+_STLP_DECLSPEC complex<long double> _STLP_CALL pow(const complex<long double>& z_in, int n)
+{ return powT(z_in, n); }
+
+_STLP_DECLSPEC complex<long double> _STLP_CALL pow(const complex<long double>& a,
+                                                   const long double& b)
+{ return powT(a, b); }
+
+_STLP_DECLSPEC complex<long double> _STLP_CALL pow(const complex<long double>& a,
+                                                   const complex<long double>& b)
+{ return powT(a, b); }
+#endif
+
+_STLP_END_NAMESPACE
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/complex_io.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include "stlport_prefix.h"
+
+#include <complex>
+#include <istream>
+
+_STLP_BEGIN_NAMESPACE
+
+// Specializations for narrow characters; lets us avoid the nuisance of
+// widening.
+_STLP_OPERATOR_SPEC
+basic_ostream<char, char_traits<char> >& _STLP_CALL
+operator<< (basic_ostream<char, char_traits<char> >& __os, const complex<float>& __z)
+{ return __os << '(' << (double)__z.real() << ',' << (double)__z.imag() << ')'; }
+
+_STLP_OPERATOR_SPEC
+basic_ostream<char, char_traits<char> >& _STLP_CALL
+operator<< (basic_ostream<char, char_traits<char> >& __os, const complex<double>& __z)
+{ return __os << '(' << __z.real() << ',' << __z.imag() << ')'; }
+
+#ifndef _STLP_NO_LONG_DOUBLE
+_STLP_OPERATOR_SPEC
+basic_ostream<char, char_traits<char> >& _STLP_CALL
+operator<< (basic_ostream<char, char_traits<char> >& __os, const complex<long double>& __z)
+{ return __os << '(' << __z.real() << ',' << __z.imag() << ')'; }
+#endif
+
+// Specialization for narrow characters; lets us avoid widen.
+_STLP_OPERATOR_SPEC
+basic_istream<char, char_traits<char> >& _STLP_CALL
+operator>>(basic_istream<char, char_traits<char> >& __is, complex<float>& __z) {
+  float  __re = 0;
+  float  __im = 0;
+
+  char __c;
+
+  __is >> __c;
+  if (__c == '(') {
+    __is >> __re >> __c;
+    if (__c == ',')
+      __is >> __im >> __c;
+    if (__c != ')')
+      __is.setstate(ios_base::failbit);
+  }
+  else {
+    __is.putback(__c);
+    __is >> __re;
+  }
+
+  if (__is)
+    __z = complex<float>(__re, __im);
+  return __is;
+}
+
+_STLP_OPERATOR_SPEC
+basic_istream<char, char_traits<char> >& _STLP_CALL
+operator>>(basic_istream<char, char_traits<char> >& __is, complex<double>& __z) {
+  double  __re = 0;
+  double  __im = 0;
+
+  char __c;
+
+  __is >> __c;
+  if (__c == '(') {
+    __is >> __re >> __c;
+    if (__c == ',')
+      __is >> __im >> __c;
+    if (__c != ')')
+      __is.setstate(ios_base::failbit);
+  }
+  else {
+    __is.putback(__c);
+    __is >> __re;
+  }
+
+  if (__is)
+    __z = complex<double>(__re, __im);
+  return __is;
+}
+
+#ifndef _STLP_NO_LONG_DOUBLE
+_STLP_OPERATOR_SPEC
+basic_istream<char, char_traits<char> >& _STLP_CALL
+operator>>(basic_istream<char, char_traits<char> >& __is, complex<long double>& __z) {
+  long double  __re = 0;
+  long double  __im = 0;
+
+  char __c;
+
+  __is >> __c;
+  if (__c == '(') {
+    __is >> __re >> __c;
+    if (__c == ',')
+      __is >> __im >> __c;
+    if (__c != ')')
+      __is.setstate(ios_base::failbit);
+  }
+  else {
+    __is.putback(__c);
+    __is >> __re;
+  }
+
+  if (__is)
+    __z = complex<long double>(__re, __im);
+  return __is;
+}
+#endif
+
+// Force instantiation of complex I/O functions
+#if !(defined (_STLP_NO_FORCE_INSTANTIATE) || defined (_STLP_NO_WCHAR_T))
+
+_STLP_OPERATOR_SPEC basic_istream<wchar_t, char_traits<wchar_t> >&  _STLP_CALL
+operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&, complex<float>&);
+
+_STLP_OPERATOR_SPEC basic_istream<wchar_t, char_traits<wchar_t> >&  _STLP_CALL
+operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&, complex<double>&);
+
+#ifndef _STLP_NO_LONG_DOUBLE
+_STLP_OPERATOR_SPEC basic_istream<wchar_t, char_traits<wchar_t> >&  _STLP_CALL
+operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&, complex<long double>&);
+
+_STLP_OPERATOR_SPEC basic_ostream<wchar_t, char_traits<wchar_t> >&  _STLP_CALL
+operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&, const complex<long double>&);
+#endif
+
+_STLP_OPERATOR_SPEC basic_ostream<wchar_t, char_traits<wchar_t> >&  _STLP_CALL
+operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&, const complex<float>&);
+
+_STLP_OPERATOR_SPEC basic_ostream<wchar_t, char_traits<wchar_t> >&  _STLP_CALL
+operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&, const complex<double>&);
+
+#endif /* _STLP_NO_WCHAR_T */
+
+_STLP_END_NAMESPACE
+
+
+// Local Variables: