summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/locale
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/locale
parentInitial commit. (diff)
downloadceph-6d07fdb6bb33b1af39833b850bb6cf8af79fe293.tar.xz
ceph-6d07fdb6bb33b1af39833b850bb6cf8af79fe293.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/locale')
-rw-r--r--src/boost/libs/locale/build/Jamfile.v2445
-rw-r--r--src/boost/libs/locale/build/has_iconv.cpp14
-rw-r--r--src/boost/libs/locale/build/has_icu_test.cpp29
-rw-r--r--src/boost/libs/locale/build/has_xlocale.cpp12
-rw-r--r--src/boost/libs/locale/build/option.cpp10
-rw-r--r--src/boost/libs/locale/examples/boundary.cpp72
-rw-r--r--src/boost/libs/locale/examples/calendar.cpp71
-rw-r--r--src/boost/libs/locale/examples/collate.cpp40
-rw-r--r--src/boost/libs/locale/examples/conversions.cpp44
-rw-r--r--src/boost/libs/locale/examples/hello.cpp41
-rw-r--r--src/boost/libs/locale/examples/wboundary.cpp104
-rw-r--r--src/boost/libs/locale/examples/wconversions.cpp73
-rw-r--r--src/boost/libs/locale/examples/whello.cpp45
-rw-r--r--src/boost/libs/locale/index.html16
-rw-r--r--src/boost/libs/locale/meta/libraries.json14
-rw-r--r--src/boost/libs/locale/performance/perf_collate.cpp51
-rw-r--r--src/boost/libs/locale/performance/perf_convert.cpp56
-rw-r--r--src/boost/libs/locale/performance/perf_format.cpp39
-rw-r--r--src/boost/libs/locale/src/encoding/codepage.cpp201
-rw-r--r--src/boost/libs/locale/src/encoding/conv.hpp118
-rw-r--r--src/boost/libs/locale/src/encoding/iconv_codepage.ipp214
-rw-r--r--src/boost/libs/locale/src/encoding/uconv_codepage.ipp164
-rw-r--r--src/boost/libs/locale/src/encoding/wconv_codepage.ipp539
-rw-r--r--src/boost/libs/locale/src/icu/all_generator.hpp30
-rw-r--r--src/boost/libs/locale/src/icu/boundary.cpp231
-rw-r--r--src/boost/libs/locale/src/icu/cdata.hpp28
-rw-r--r--src/boost/libs/locale/src/icu/codecvt.cpp159
-rw-r--r--src/boost/libs/locale/src/icu/codecvt.hpp24
-rw-r--r--src/boost/libs/locale/src/icu/collator.cpp201
-rw-r--r--src/boost/libs/locale/src/icu/conversion.cpp212
-rw-r--r--src/boost/libs/locale/src/icu/date_time.cpp292
-rw-r--r--src/boost/libs/locale/src/icu/formatter.cpp618
-rw-r--r--src/boost/libs/locale/src/icu/formatter.hpp132
-rw-r--r--src/boost/libs/locale/src/icu/icu_backend.cpp166
-rw-r--r--src/boost/libs/locale/src/icu/icu_backend.hpp20
-rw-r--r--src/boost/libs/locale/src/icu/icu_util.hpp32
-rw-r--r--src/boost/libs/locale/src/icu/numeric.cpp426
-rw-r--r--src/boost/libs/locale/src/icu/predefined_formatters.hpp187
-rw-r--r--src/boost/libs/locale/src/icu/time_zone.cpp239
-rw-r--r--src/boost/libs/locale/src/icu/time_zone.hpp26
-rw-r--r--src/boost/libs/locale/src/icu/uconv.hpp316
-rw-r--r--src/boost/libs/locale/src/posix/all_generator.hpp48
-rw-r--r--src/boost/libs/locale/src/posix/codecvt.cpp252
-rw-r--r--src/boost/libs/locale/src/posix/codecvt.hpp28
-rw-r--r--src/boost/libs/locale/src/posix/collate.cpp124
-rw-r--r--src/boost/libs/locale/src/posix/converter.cpp165
-rw-r--r--src/boost/libs/locale/src/posix/numeric.cpp514
-rw-r--r--src/boost/libs/locale/src/posix/posix_backend.cpp184
-rw-r--r--src/boost/libs/locale/src/posix/posix_backend.hpp20
-rw-r--r--src/boost/libs/locale/src/shared/date_time.cpp469
-rw-r--r--src/boost/libs/locale/src/shared/format.cpp188
-rw-r--r--src/boost/libs/locale/src/shared/formatting.cpp180
-rw-r--r--src/boost/libs/locale/src/shared/generator.cpp192
-rw-r--r--src/boost/libs/locale/src/shared/ids.cpp88
-rw-r--r--src/boost/libs/locale/src/shared/ios_prop.hpp109
-rw-r--r--src/boost/libs/locale/src/shared/localization_backend.cpp285
-rw-r--r--src/boost/libs/locale/src/shared/message.cpp784
-rw-r--r--src/boost/libs/locale/src/shared/mo_hash.hpp61
-rw-r--r--src/boost/libs/locale/src/shared/mo_lambda.cpp411
-rw-r--r--src/boost/libs/locale/src/shared/mo_lambda.hpp38
-rw-r--r--src/boost/libs/locale/src/std/all_generator.hpp54
-rw-r--r--src/boost/libs/locale/src/std/codecvt.cpp55
-rw-r--r--src/boost/libs/locale/src/std/collate.cpp113
-rw-r--r--src/boost/libs/locale/src/std/converter.cpp148
-rw-r--r--src/boost/libs/locale/src/std/numeric.cpp456
-rw-r--r--src/boost/libs/locale/src/std/std_backend.cpp234
-rw-r--r--src/boost/libs/locale/src/std/std_backend.hpp20
-rw-r--r--src/boost/libs/locale/src/util/codecvt_converter.cpp458
-rw-r--r--src/boost/libs/locale/src/util/default_locale.cpp80
-rw-r--r--src/boost/libs/locale/src/util/gregorian.cpp852
-rw-r--r--src/boost/libs/locale/src/util/gregorian.hpp25
-rw-r--r--src/boost/libs/locale/src/util/iconv.hpp58
-rw-r--r--src/boost/libs/locale/src/util/info.cpp75
-rw-r--r--src/boost/libs/locale/src/util/locale_data.cpp113
-rw-r--r--src/boost/libs/locale/src/util/locale_data.hpp47
-rw-r--r--src/boost/libs/locale/src/util/numeric.hpp393
-rw-r--r--src/boost/libs/locale/src/util/timezone.hpp53
-rw-r--r--src/boost/libs/locale/src/win32/all_generator.hpp45
-rw-r--r--src/boost/libs/locale/src/win32/api.hpp357
-rw-r--r--src/boost/libs/locale/src/win32/collate.cpp127
-rw-r--r--src/boost/libs/locale/src/win32/converter.cpp106
-rw-r--r--src/boost/libs/locale/src/win32/lcid.cpp127
-rw-r--r--src/boost/libs/locale/src/win32/lcid.hpp25
-rw-r--r--src/boost/libs/locale/src/win32/numeric.cpp245
-rw-r--r--src/boost/libs/locale/src/win32/win_backend.cpp153
-rw-r--r--src/boost/libs/locale/src/win32/win_backend.hpp20
-rw-r--r--src/boost/libs/locale/test/Jamfile.v256
-rwxr-xr-xsrc/boost/libs/locale/test/generate_catalogs.sh14
-rw-r--r--src/boost/libs/locale/test/he/LC_MESSAGES/default.mobin0 -> 616 bytes
-rw-r--r--src/boost/libs/locale/test/he/LC_MESSAGES/default.po35
-rw-r--r--src/boost/libs/locale/test/he/LC_MESSAGES/fall.mobin0 -> 180 bytes
-rw-r--r--src/boost/libs/locale/test/he/LC_MESSAGES/fall.po10
-rw-r--r--src/boost/libs/locale/test/he/LC_MESSAGES/simple.mobin0 -> 310 bytes
-rw-r--r--src/boost/libs/locale/test/he/LC_MESSAGES/simple.po23
-rw-r--r--src/boost/libs/locale/test/he_IL/LC_MESSAGES/full.mobin0 -> 183 bytes
-rw-r--r--src/boost/libs/locale/test/he_IL/LC_MESSAGES/full.po10
-rw-r--r--src/boost/libs/locale/test/test_boundary.cpp537
-rw-r--r--src/boost/libs/locale/test/test_codecvt.cpp283
-rw-r--r--src/boost/libs/locale/test/test_codepage.cpp517
-rw-r--r--src/boost/libs/locale/test/test_codepage_converter.cpp323
-rw-r--r--src/boost/libs/locale/test/test_collate.cpp139
-rw-r--r--src/boost/libs/locale/test/test_config.cpp133
-rw-r--r--src/boost/libs/locale/test/test_convert.cpp129
-rw-r--r--src/boost/libs/locale/test/test_date_time.cpp302
-rw-r--r--src/boost/libs/locale/test/test_formatting.cpp576
-rw-r--r--src/boost/libs/locale/test/test_generator.cpp100
-rw-r--r--src/boost/libs/locale/test/test_icu_vs_os_timezone.cpp65
-rw-r--r--src/boost/libs/locale/test/test_ios_prop.cpp84
-rw-r--r--src/boost/libs/locale/test/test_locale.hpp118
-rw-r--r--src/boost/libs/locale/test/test_locale_tools.hpp126
-rw-r--r--src/boost/libs/locale/test/test_message.cpp535
-rw-r--r--src/boost/libs/locale/test/test_posix_collate.cpp120
-rw-r--r--src/boost/libs/locale/test/test_posix_convert.cpp122
-rw-r--r--src/boost/libs/locale/test/test_posix_formatting.cpp281
-rw-r--r--src/boost/libs/locale/test/test_posix_tools.hpp31
-rw-r--r--src/boost/libs/locale/test/test_std_collate.cpp129
-rw-r--r--src/boost/libs/locale/test/test_std_convert.cpp120
-rw-r--r--src/boost/libs/locale/test/test_std_formatting.cpp371
-rw-r--r--src/boost/libs/locale/test/test_utf.cpp303
-rw-r--r--src/boost/libs/locale/test/test_winapi_collate.cpp133
-rw-r--r--src/boost/libs/locale/test/test_winapi_convert.cpp108
-rw-r--r--src/boost/libs/locale/test/test_winapi_formatting.cpp267
-rwxr-xr-xsrc/boost/libs/locale/tools/cross-compile-gettext.sh60
123 files changed, 20490 insertions, 0 deletions
diff --git a/src/boost/libs/locale/build/Jamfile.v2 b/src/boost/libs/locale/build/Jamfile.v2
new file mode 100644
index 000000000..578e722ee
--- /dev/null
+++ b/src/boost/libs/locale/build/Jamfile.v2
@@ -0,0 +1,445 @@
+# copyright John Maddock 2003, Artyom Beilis 2010
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt.
+
+
+
+project /boost/locale
+ : source-location ../src
+ ;
+
+import configure ;
+import os ;
+import toolset ;
+import project ;
+import feature ;
+# Features
+
+feature.feature boost.locale.iconv : on off : optional propagated ;
+feature.feature boost.locale.icu : on off : optional propagated ;
+feature.feature boost.locale.posix : on off : optional propagated ;
+feature.feature boost.locale.std : on off : optional propagated ;
+feature.feature boost.locale.winapi : on off : optional propagated ;
+
+# Configuration of libraries
+
+## iconv
+
+obj has_iconv_libc_obj : ../build/has_iconv.cpp ;
+exe has_iconv : has_iconv_libc_obj ;
+explicit has_iconv ;
+
+ICONV_PATH = [ modules.peek : ICONV_PATH ] ;
+
+lib iconv
+ :
+ : <search>$(ICONV_PATH)/lib <link>shared <runtime-link>shared
+ :
+ : <include>$(ICONV_PATH)/include
+ ;
+
+explicit iconv ;
+
+obj has_iconv_libc_ext : ../build/has_iconv.cpp iconv ;
+exe has_external_iconv : has_iconv_libc_ext iconv ;
+explicit has_external_iconv ;
+
+exe accepts_shared_option : ../build/option.cpp
+ : <cxxflags>-shared-libstdc++
+ <cxxflags>-shared-libgcc
+ <linkflags>-shared-libstdc++
+ <linkflags>-shared-libgcc
+ ;
+
+# Xlocale
+obj has_xlocale_obj : ../build/has_xlocale.cpp ;
+exe has_xlocale : has_xlocale_obj ;
+explicit has_xlocale ;
+
+#end xlocale
+
+
+ICU_PATH = [ modules.peek : ICU_PATH ] ;
+ICU_LINK = [ modules.peek : ICU_LINK ] ;
+
+if $(ICU_LINK)
+{
+ ICU_OPTS = <include>$(ICU_PATH)/include <linkflags>$(ICU_LINK) <dll-path>$(ICU_PATH)/bin <runtime-link>shared ;
+ ICU64_OPTS = <include>$(ICU_PATH)/include <linkflags>$(ICU_LINK) <dll-path>$(ICU_PATH)/bin64 <runtime-link>shared ;
+}
+else
+{
+ searched-lib icuuc : : <name>icuuc
+ <search>$(ICU_PATH)/lib
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuuc : : <toolset>msvc
+ <variant>debug
+ <name>icuucd
+ <search>$(ICU_PATH)/lib
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuuc : : <name>this_is_an_invalid_library_name ;
+
+ searched-lib icudt : : <search>$(ICU_PATH)/lib
+ <name>icudata
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icudt : : <search>$(ICU_PATH)/lib
+ <name>icudt
+ <toolset>msvc
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icudt : : <name>this_is_an_invalid_library_name ;
+
+ searched-lib icuin : : <search>$(ICU_PATH)/lib
+ <name>icui18n
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuin : : <toolset>msvc
+ <variant>debug
+ <name>icuind
+ <search>$(ICU_PATH)/lib
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuin : : <toolset>msvc
+ <variant>release
+ <name>icuin
+ <search>$(ICU_PATH)/lib
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuin : : <name>this_is_an_invalid_library_name ;
+
+ explicit icuuc icudt icuin ;
+
+ ICU_OPTS = <include>$(ICU_PATH)/include
+ <library>icuuc/<link>shared/<runtime-link>shared
+ <library>icudt/<link>shared/<runtime-link>shared
+ <library>icuin/<link>shared/<runtime-link>shared
+ <dll-path>$(ICU_PATH)/bin
+ <runtime-link>shared ;
+
+
+
+ searched-lib icuuc_64 : : <name>icuuc
+ <search>$(ICU_PATH)/lib64
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuuc_64 : : <toolset>msvc
+ <variant>debug
+ <name>icuucd
+ <search>$(ICU_PATH)/lib64
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuuc_64 : : <name>this_is_an_invalid_library_name ;
+
+ searched-lib icudt_64 : : <search>$(ICU_PATH)/lib64
+ <name>icudata
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icudt_64 : : <search>$(ICU_PATH)/lib64
+ <name>icudt
+ <toolset>msvc
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icudt_64 : : <name>this_is_an_invalid_library_name ;
+
+ searched-lib icuin_64 : : <search>$(ICU_PATH)/lib64
+ <name>icui18n
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuin_64 : : <toolset>msvc
+ <variant>debug
+ <name>icuind
+ <search>$(ICU_PATH)/lib64
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuin_64 : : <toolset>msvc
+ <variant>release
+ <name>icuin
+ <search>$(ICU_PATH)/lib64
+ <link>shared
+ <runtime-link>shared ;
+
+ searched-lib icuin_64 : : <name>this_is_an_invalid_library_name ;
+
+ explicit icuuc_64 icudt_64 icuin_64 ;
+
+ ICU64_OPTS = <include>$(ICU_PATH)/include
+ <library>icuuc_64/<link>shared/<runtime-link>shared
+ <library>icudt_64/<link>shared/<runtime-link>shared
+ <library>icuin_64/<link>shared/<runtime-link>shared
+ <dll-path>$(ICU_PATH)/bin64
+ <runtime-link>shared ;
+
+
+}
+
+obj has_icu_obj : ../build/has_icu_test.cpp : $(ICU_OPTS) ;
+obj has_icu64_obj : ../build/has_icu_test.cpp : $(ICU64_OPTS) ;
+
+exe has_icu : has_icu_obj : $(ICU_OPTS) ;
+exe has_icu64 : has_icu64_obj : $(ICU64_OPTS) ;
+
+explicit has_icu has_icu64 ;
+
+
+# This function is called whenever the 'boost_locale' metatarget
+# below is generated and figures what external components we have,
+# what user wants, and what sources have to be compiled in the end.
+rule configure-full ( properties * : flags-only )
+{
+
+ local result ;
+ local flags-result ;
+
+ local found-iconv ;
+
+ if <boost.locale.iconv>on in $(properties)
+ || ! <boost.locale.iconv> in $(properties:G)
+ && ! <target-os>solaris in $(properties)
+ {
+ # See if iconv is bundled with standard library.
+ if [ configure.builds has_iconv : $(properties) : "iconv (libc)" ]
+ {
+ found-iconv = true ;
+ }
+ else
+ {
+ if [ configure.builds has_external_iconv : $(properties) : "iconv (separate)" ]
+ {
+ found-iconv = true ;
+ result += <library>iconv ;
+ }
+ }
+ }
+ if $(found-iconv)
+ {
+ flags-result += <define>BOOST_LOCALE_WITH_ICONV=1 ;
+ }
+
+ local found-icu ;
+
+ if ! <boost.locale.icu>off in $(properties)
+ {
+ if [ configure.builds has_icu : $(properties) : "icu" ]
+ {
+ found-icu = true ;
+ flags-result += <define>BOOST_LOCALE_WITH_ICU=1 $(ICU_OPTS) ;
+ }
+ else if [ configure.builds has_icu64 : $(properties) : "icu (lib64)" ]
+ {
+ found-icu = true ;
+ flags-result += <define>BOOST_LOCALE_WITH_ICU=1 $(ICU64_OPTS) ;
+ }
+
+ if $(found-icu)
+ {
+ ICU_SOURCES =
+ boundary
+ codecvt
+ collator
+ conversion
+ date_time
+ formatter
+ icu_backend
+ numeric
+ time_zone
+ ;
+
+ result += <source>icu/$(ICU_SOURCES).cpp
+ <library>../../thread/build//boost_thread
+ ;
+ }
+
+ }
+
+ if ! $(found-iconv) && ! $(found-icu) && ! <target-os>windows in $(properties) && ! <target-os>cygwin in $(properties)
+ {
+ ECHO "- Boost.Locale needs either iconv or ICU library to be built." ;
+ result += <build>no ;
+ }
+
+ if ! <boost.locale.std> in $(properties:G)
+ {
+ if <toolset>sun in $(properties)
+ {
+ properties += <boost.locale.std>off ;
+ }
+ else
+ {
+ properties += <boost.locale.std>on ;
+ }
+ }
+
+ if <boost.locale.std>off in $(properties)
+ {
+ flags-result += <define>BOOST_LOCALE_NO_STD_BACKEND=1 ;
+ }
+ else
+ {
+ STD_SOURCES =
+ codecvt
+ collate
+ converter
+ numeric
+ std_backend
+ ;
+ result += <source>std/$(STD_SOURCES).cpp ;
+ }
+
+ if ! <boost.locale.winapi> in $(properties:G)
+ {
+ if <target-os>windows in $(properties)
+ || <target-os>cygwin in $(properties)
+ {
+ properties += <boost.locale.winapi>on ;
+ }
+ else
+ {
+ properties += <boost.locale.winapi>off ;
+ }
+ }
+ if <target-os>windows in $(properties)
+ && <toolset>gcc in $(properties)
+ && <link>shared in $(properties)
+ && [ configure.builds accepts_shared_option : $(properties) : "g++ -shared-* supported" ]
+ {
+ flags-result += <cxxflags>-shared-libstdc++
+ <cxxflags>-shared-libgcc
+ <linkflags>-shared-libstdc++
+ <linkflags>-shared-libgcc
+ ;
+ }
+
+ if <boost.locale.winapi>off in $(properties)
+ {
+ flags-result += <define>BOOST_LOCALE_NO_WINAPI_BACKEND=1 ;
+ }
+ else
+ {
+ WINAPI_SOURCES =
+ collate
+ converter
+ numeric
+ win_backend
+ ;
+ result += <source>win32/$(WINAPI_SOURCES).cpp ;
+ }
+
+ if ( ! <boost.locale.winapi>off in $(properties) || ! <boost.locale.std>off in $(properties) )
+ && ( <target-os>windows in $(properties) || <target-os>cygwin in $(properties) )
+ {
+ result += <source>win32/lcid.cpp ;
+ }
+
+ if ! <boost.locale.posix> in $(properties:G)
+ {
+ if <target-os>linux in $(properties)
+ || <target-os>darwin in $(properties)
+ || ( <target-os>freebsd in $(properties) && [ configure.builds has_xlocale : $(properties) : "xlocale supported" ] )
+ {
+ properties += <boost.locale.posix>on ;
+ }
+ else
+ {
+ properties += <boost.locale.posix>off ;
+ }
+ }
+
+ if <boost.locale.posix>off in $(properties)
+ {
+ flags-result += <define>BOOST_LOCALE_NO_POSIX_BACKEND=1 ;
+ }
+ else
+ {
+ POSIX_SOURCES =
+ collate
+ converter
+ numeric
+ codecvt
+ posix_backend
+ ;
+ result += <source>posix/$(POSIX_SOURCES).cpp ;
+ }
+
+ if <boost.locale.posix>on in $(properties) || <boost.locale.std>on in $(properties) || <boost.locale.winapi>on in $(properties)
+ {
+ result += <source>util/gregorian.cpp ;
+ }
+
+ result += <library>../../system/build//boost_system ;
+
+
+ if "$(flags-only)" = "flags"
+ {
+ return $(flags-result) ;
+ }
+ else {
+ result += $(flags-result) ;
+ return $(result) ;
+ }
+}
+
+rule configure ( properties * )
+{
+ local result = [ configure-full $(properties) : "all" ] ;
+ return $(result) ;
+
+}
+
+rule configure-flags ( properties * )
+{
+ local result ;
+ result = [ configure-full $(properties) : "flags" ] ;
+ return $(result) ;
+
+}
+
+
+alias build_options : : : : <conditional>@configure ;
+alias build_flags : : : : <conditional>@configure-flags ;
+
+lib boost_locale
+ :
+ encoding/codepage.cpp
+ shared/date_time.cpp
+ shared/format.cpp
+ shared/formatting.cpp
+ shared/generator.cpp
+ shared/ids.cpp
+ shared/localization_backend.cpp
+ shared/message.cpp
+ shared/mo_lambda.cpp
+ util/codecvt_converter.cpp
+ util/default_locale.cpp
+ util/info.cpp
+ util/locale_data.cpp
+ :
+ # Don't link explicitly, not required
+ <define>BOOST_THREAD_NO_LIB=1
+ <link>shared:<define>BOOST_LOCALE_DYN_LINK=1
+ <threading>multi
+ # Meanwhile remove this
+ <conditional>@configure
+ ;
+
+boost-install boost_locale ;
+
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/build/has_iconv.cpp b/src/boost/libs/locale/build/has_iconv.cpp
new file mode 100644
index 000000000..7b500580f
--- /dev/null
+++ b/src/boost/libs/locale/build/has_iconv.cpp
@@ -0,0 +1,14 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <iconv.h>
+
+int main()
+{
+ iconv_t d = iconv_open(0,0);
+ (void)(d);
+}
diff --git a/src/boost/libs/locale/build/has_icu_test.cpp b/src/boost/libs/locale/build/has_icu_test.cpp
new file mode 100644
index 000000000..9419b3019
--- /dev/null
+++ b/src/boost/libs/locale/build/has_icu_test.cpp
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright (c) 2010
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+#include <unicode/uversion.h>
+#include <unicode/locid.h>
+#include <unicode/utypes.h>
+#include <unicode/uchar.h>
+#include <unicode/coll.h>
+
+#if defined(_MSC_VER) && !defined(_DLL)
+#error "Mixing ICU with a static runtime doesn't work"
+#endif
+
+int main()
+{
+ icu::Locale loc;
+ UErrorCode err = U_ZERO_ERROR;
+ UChar32 c = ::u_charFromName(U_UNICODE_CHAR_NAME, "GREEK SMALL LETTER ALPHA", &err);
+ return err;
+}
+
diff --git a/src/boost/libs/locale/build/has_xlocale.cpp b/src/boost/libs/locale/build/has_xlocale.cpp
new file mode 100644
index 000000000..4d788e2b7
--- /dev/null
+++ b/src/boost/libs/locale/build/has_xlocale.cpp
@@ -0,0 +1,12 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <xlocale.h>
+int main()
+{
+ newlocale(LC_ALL_MASK,"",0);
+}
diff --git a/src/boost/libs/locale/build/option.cpp b/src/boost/libs/locale/build/option.cpp
new file mode 100644
index 000000000..d321a959d
--- /dev/null
+++ b/src/boost/libs/locale/build/option.cpp
@@ -0,0 +1,10 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+int main()
+{
+}
diff --git a/src/boost/libs/locale/examples/boundary.cpp b/src/boost/libs/locale/examples/boundary.cpp
new file mode 100644
index 000000000..7c643f938
--- /dev/null
+++ b/src/boost/libs/locale/examples/boundary.cpp
@@ -0,0 +1,72 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/locale.hpp>
+#include <iostream>
+#include <cassert>
+#include <ctime>
+
+int main()
+{
+ using namespace boost::locale;
+ using namespace std;
+
+ generator gen;
+ // Make system default locale global
+ std::locale loc = gen("");
+ locale::global(loc);
+ cout.imbue(loc);
+
+
+ string text="Hello World! あにま! Linux2.6 and Windows7 is word and number. שָלוֹם עוֹלָם!";
+
+ cout<<text<<endl;
+
+ boundary::ssegment_index index(boundary::word,text.begin(),text.end());
+ boundary::ssegment_index::iterator p,e;
+
+ for(p=index.begin(),e=index.end();p!=e;++p) {
+ cout<<"Part ["<<*p<<"] has ";
+ if(p->rule() & boundary::word_number)
+ cout<<"number(s) ";
+ if(p->rule() & boundary::word_letter)
+ cout<<"letter(s) ";
+ if(p->rule() & boundary::word_kana)
+ cout<<"kana character(s) ";
+ if(p->rule() & boundary::word_ideo)
+ cout<<"ideographic character(s) ";
+ if(p->rule() & boundary::word_none)
+ cout<<"no word characters";
+ cout<<endl;
+ }
+
+ index.map(boundary::character,text.begin(),text.end());
+
+ for(p=index.begin(),e=index.end();p!=e;++p) {
+ cout<<"|" <<*p ;
+ }
+ cout<<"|\n\n";
+
+ index.map(boundary::line,text.begin(),text.end());
+
+ for(p=index.begin(),e=index.end();p!=e;++p) {
+ cout<<"|" <<*p ;
+ }
+ cout<<"|\n\n";
+
+ index.map(boundary::sentence,text.begin(),text.end());
+
+ for(p=index.begin(),e=index.end();p!=e;++p) {
+ cout<<"|" <<*p ;
+ }
+ cout<<"|\n\n";
+
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/examples/calendar.cpp b/src/boost/libs/locale/examples/calendar.cpp
new file mode 100644
index 000000000..d905511a7
--- /dev/null
+++ b/src/boost/libs/locale/examples/calendar.cpp
@@ -0,0 +1,71 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/locale.hpp>
+#include <iostream>
+#include <iomanip>
+#include <ctime>
+
+int main()
+{
+ using namespace boost::locale;
+
+ generator gen;
+ std::locale::global(gen(""));
+ std::cout.imbue(std::locale());
+ // Setup environment
+
+ boost::locale::date_time now;
+
+ date_time start=now;
+
+ // Set the first day of the first month of this year
+ start.set(period::month(),now.minimum(period::month()));
+ start.set(period::day(),start.minimum(period::day()));
+
+ int current_year = period::year(now);
+
+
+ // Display current year
+ std::cout << format("{1,ftime='%Y'}") % now << std::endl;
+
+ //
+ // Run forward untill current year is the date
+ //
+ for(now=start; period::year(now) == current_year;) {
+
+ // Print heading of month
+ if(calendar().is_gregorian())
+ std::cout << format("{1,ftime='%B'}") % now <<std::endl;
+ else
+ std::cout << format("{1,ftime='%B'} ({1,ftime='%Y-%m-%d',locale=en} - {2,locale=en,ftime='%Y-%m-%d'})")
+ % now
+ % date_time(now,now.maximum(period::day())*period::day()) << std::endl;
+
+ int first = calendar().first_day_of_week();
+
+ // Print weeks days
+ for(int i=0;i<7;i++) {
+ date_time tmp(now,period::day_of_week() * (first + i));
+ std::cout << format("{1,w=8,ftime='%a'} ") % tmp;
+ }
+ std::cout << std::endl;
+
+ int current_month = now / period::month();
+ int skip = now / period::day_of_week_local() - 1;
+ for(int i=0;i<skip*9;i++)
+ std::cout << ' ';
+ for(;now / period::month() == current_month ;now += period::day()) {
+ std::cout << format("{1,w=8,ftime='%e'} ") % now;
+ if(now / period::day_of_week_local() == 7)
+ std::cout << std::endl;
+ }
+ std::cout << std::endl;
+ }
+
+}
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/examples/collate.cpp b/src/boost/libs/locale/examples/collate.cpp
new file mode 100644
index 000000000..9e14e43ab
--- /dev/null
+++ b/src/boost/libs/locale/examples/collate.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <iostream>
+#include <string>
+#include <set>
+
+#include <boost/locale.hpp>
+
+using namespace std;
+using namespace boost::locale;
+
+int main()
+{
+ generator gen;
+ std::locale::global(gen(""));
+ /// Set global locale to requested
+
+ /// Create a set that includes all strings sorted according to ABC order
+ /// std::locale can be used as object for comparison
+ typedef std::set<std::string,std::locale> set_type;
+ set_type all_strings;
+
+ /// Read all strings into the set
+ while(!cin.eof()) {
+ std::string tmp;
+ getline(cin,tmp);
+ all_strings.insert(tmp);
+ }
+ /// Print them out
+ for(set_type::iterator p=all_strings.begin();p!=all_strings.end();++p) {
+ cout<<*p<<endl;
+ }
+
+}
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/examples/conversions.cpp b/src/boost/libs/locale/examples/conversions.cpp
new file mode 100644
index 000000000..74037f235
--- /dev/null
+++ b/src/boost/libs/locale/examples/conversions.cpp
@@ -0,0 +1,44 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/locale.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
+#include <iostream>
+
+#include <ctime>
+
+
+
+int main()
+{
+ using namespace boost::locale;
+ using namespace std;
+ // Create system default locale
+ generator gen;
+ locale loc=gen("");
+ locale::global(loc);
+ cout.imbue(loc);
+
+
+ cout<<"Correct case conversion can't be done by simple, character by character conversion"<<endl;
+ cout<<"because case conversion is context sensitive and not 1-to-1 conversion"<<endl;
+ cout<<"For example:"<<endl;
+ cout<<" German grüßen correctly converted to "<<to_upper("grüßen")<<", instead of incorrect "
+ <<boost::to_upper_copy(std::string("grüßen"))<<endl;
+ cout<<" where ß is replaced with SS"<<endl;
+ cout<<" Greek ὈΔΥΣΣΕΎΣ is correctly converted to "<<to_lower("ὈΔΥΣΣΕΎΣ")<<", instead of incorrect "
+ <<boost::to_lower_copy(std::string("ὈΔΥΣΣΕΎΣ"))<<endl;
+ cout<<" where Σ is converted to σ or to ς, according to position in the word"<<endl;
+ cout<<"Such type of conversion just can't be done using std::toupper that work on character base, also std::toupper is "<<endl;
+ cout<<"not even applicable when working with variable character length like in UTF-8 or UTF-16 limiting the correct "<<endl;
+ cout<<"behavior to unicode subset BMP or ASCII only"<<endl;
+
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/examples/hello.cpp b/src/boost/libs/locale/examples/hello.cpp
new file mode 100644
index 000000000..e1a2d93b9
--- /dev/null
+++ b/src/boost/libs/locale/examples/hello.cpp
@@ -0,0 +1,41 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/locale.hpp>
+#include <iostream>
+
+#include <ctime>
+
+int main()
+{
+ using namespace boost::locale;
+ using namespace std;
+ generator gen;
+ locale loc=gen("");
+ // Create system default locale
+
+ locale::global(loc);
+ // Make it system global
+
+ cout.imbue(loc);
+ // Set as default locale for output
+
+ cout <<format("Today {1,date} at {1,time} we had run our first localization example") % time(0)
+ <<endl;
+
+ cout<<"This is how we show numbers in this locale "<<as::number << 103.34 <<endl;
+ cout<<"This is how we show currency in this locale "<<as::currency << 103.34 <<endl;
+ cout<<"This is typical date in the locale "<<as::date << std::time(0) <<endl;
+ cout<<"This is typical time in the locale "<<as::time << std::time(0) <<endl;
+ cout<<"This is upper case "<<to_upper("Hello World!")<<endl;
+ cout<<"This is lower case "<<to_lower("Hello World!")<<endl;
+ cout<<"This is title case "<<to_title("Hello World!")<<endl;
+ cout<<"This is fold case "<<fold_case("Hello World!")<<endl;
+
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/examples/wboundary.cpp b/src/boost/libs/locale/examples/wboundary.cpp
new file mode 100644
index 000000000..a14325faa
--- /dev/null
+++ b/src/boost/libs/locale/examples/wboundary.cpp
@@ -0,0 +1,104 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+//
+// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
+//
+// BIG FAT WARNING FOR Microsoft Visual Studio Users
+//
+// YOU NEED TO CONVERT THIS SOURCE FILE ENCODING TO UTF-8 WITH BOM ENCODING.
+//
+// Unfortunately MSVC understands that the source code is encoded as
+// UTF-8 only if you add useless BOM in the beginning.
+//
+// So, before you compile "wide" examples with MSVC, please convert them to text
+// files with BOM. There are two very simple ways to do it:
+//
+// 1. Open file with Notepad and save it from there. It would convert
+// it to file with BOM.
+// 2. In Visual Studio go File->Advances Save Options... and select
+// Unicode (UTF-8 with signature) Codepage 65001
+//
+// Note: once converted to UTF-8 with BOM, this source code would not
+// compile with other compilers, because no-one uses BOM with UTF-8 today
+// because it is absolutely meaningless in context of UTF-8.
+//
+// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
+//
+#include <boost/locale.hpp>
+#include <iostream>
+#include <cassert>
+#include <ctime>
+
+int main()
+{
+ using namespace boost::locale;
+ using namespace std;
+
+ // Create system default locale
+ generator gen;
+ locale loc=gen("");
+ locale::global(loc);
+ wcout.imbue(loc);
+
+ // This is needed to prevent C library to
+ // convert strings to narrow
+ // instead of C++ on some platforms
+ std::ios_base::sync_with_stdio(false);
+
+
+ wstring text=L"Hello World! あにま! Linux2.6 and Windows7 is word and number. שָלוֹם עוֹלָם!";
+
+ wcout<<text<<endl;
+
+ boundary::wssegment_index index(boundary::word,text.begin(),text.end());
+ boundary::wssegment_index::iterator p,e;
+
+ for(p=index.begin(),e=index.end();p!=e;++p) {
+ wcout<<L"Part ["<<*p<<L"] has ";
+ if(p->rule() & boundary::word_number)
+ wcout<<L"number(s) ";
+ if(p->rule() & boundary::word_letter)
+ wcout<<L"letter(s) ";
+ if(p->rule() & boundary::word_kana)
+ wcout<<L"kana character(s) ";
+ if(p->rule() & boundary::word_ideo)
+ wcout<<L"ideographic character(s) ";
+ if(p->rule() & boundary::word_none)
+ wcout<<L"no word characters";
+ wcout<<endl;
+ }
+
+ index.map(boundary::character,text.begin(),text.end());
+
+ for(p=index.begin(),e=index.end();p!=e;++p) {
+ wcout<<L"|" <<*p ;
+ }
+ wcout<<L"|\n\n";
+
+ index.map(boundary::line,text.begin(),text.end());
+
+ for(p=index.begin(),e=index.end();p!=e;++p) {
+ wcout<<L"|" <<*p ;
+ }
+ wcout<<L"|\n\n";
+
+ index.map(boundary::sentence,text.begin(),text.end());
+
+ for(p=index.begin(),e=index.end();p!=e;++p) {
+ wcout<<L"|" <<*p ;
+ }
+ wcout<<"|\n\n";
+
+}
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
+
diff --git a/src/boost/libs/locale/examples/wconversions.cpp b/src/boost/libs/locale/examples/wconversions.cpp
new file mode 100644
index 000000000..d26a2a477
--- /dev/null
+++ b/src/boost/libs/locale/examples/wconversions.cpp
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+//
+// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
+//
+// BIG FAT WARNING FOR Microsoft Visual Studio Users
+//
+// YOU NEED TO CONVERT THIS SOURCE FILE ENCODING TO UTF-8 WITH BOM ENCODING.
+//
+// Unfortunately MSVC understands that the source code is encoded as
+// UTF-8 only if you add useless BOM in the beginning.
+//
+// So, before you compile "wide" examples with MSVC, please convert them to text
+// files with BOM. There are two very simple ways to do it:
+//
+// 1. Open file with Notepad and save it from there. It would convert
+// it to file with BOM.
+// 2. In Visual Studio go File->Advances Save Options... and select
+// Unicode (UTF-8 with signature) Codepage 65001
+//
+// Note: once converted to UTF-8 with BOM, this source code would not
+// compile with other compilers, because no-one uses BOM with UTF-8 today
+// because it is absolutely meaningless in context of UTF-8.
+//
+// ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
+//
+#include <boost/locale.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
+#include <iostream>
+
+#include <ctime>
+
+
+int main()
+{
+ using namespace boost::locale;
+ using namespace std;
+ // Create system default locale
+ generator gen;
+ locale loc=gen("");
+ locale::global(loc);
+ wcout.imbue(loc);
+
+ // This is needed to prevent C library to
+ // convert strings to narrow
+ // instead of C++ on some platforms
+ std::ios_base::sync_with_stdio(false);
+
+
+ wcout<<L"Correct case conversion can't be done by simple, character by character conversion"<<endl;
+ wcout<<L"because case conversion is context sensitive and not 1-to-1 conversion"<<endl;
+ wcout<<L"For example:"<<endl;
+ wcout<<L" German grüßen correctly converted to "<<to_upper(L"grüßen")<<L", instead of incorrect "
+ <<boost::to_upper_copy(std::wstring(L"grüßen"))<<endl;
+ wcout<<L" where ß is replaced with SS"<<endl;
+ wcout<<L" Greek ὈΔΥΣΣΕΎΣ is correctly converted to "<<to_lower(L"ὈΔΥΣΣΕΎΣ")<<L", instead of incorrect "
+ <<boost::to_lower_copy(std::wstring(L"ὈΔΥΣΣΕΎΣ"))<<endl;
+ wcout<<L" where Σ is converted to σ or to ς, according to position in the word"<<endl;
+ wcout<<L"Such type of conversion just can't be done using std::toupper that work on character base, also std::toupper is "<<endl;
+ wcout<<L"not fully applicable when working with variable character length like in UTF-8 or UTF-16 limiting the correct "<<endl;
+ wcout<<L"behavoir to BMP or ASCII only"<<endl;
+
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/examples/whello.cpp b/src/boost/libs/locale/examples/whello.cpp
new file mode 100644
index 000000000..a224eaf42
--- /dev/null
+++ b/src/boost/libs/locale/examples/whello.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/locale.hpp>
+#include <iostream>
+
+#include <ctime>
+
+int main()
+{
+ using namespace boost::locale;
+ using namespace std;
+
+ // Create system default locale
+ generator gen;
+ locale loc=gen("");
+ locale::global(loc);
+ wcout.imbue(loc);
+
+ // This is needed to prevent C library to
+ // convert strings to narrow
+ // instead of C++ on some platforms
+ std::ios_base::sync_with_stdio(false);
+
+
+ wcout <<wformat(L"Today {1,date} at {1,time} we had run our first localization example") % time(0)
+ <<endl;
+
+ wcout<<L"This is how we show numbers in this locale "<<as::number << 103.34 <<endl;
+ wcout<<L"This is how we show currency in this locale "<<as::currency << 103.34 <<endl;
+ wcout<<L"This is typical date in the locale "<<as::date << std::time(0) <<endl;
+ wcout<<L"This is typical time in the locale "<<as::time << std::time(0) <<endl;
+ wcout<<L"This is upper case "<<to_upper(L"Hello World!")<<endl;
+ wcout<<L"This is lower case "<<to_lower(L"Hello World!")<<endl;
+ wcout<<L"This is title case "<<to_title(L"Hello World!")<<endl;
+ wcout<<L"This is fold case "<<fold_case(L"Hello World!")<<endl;
+
+}
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/index.html b/src/boost/libs/locale/index.html
new file mode 100644
index 000000000..80b010d58
--- /dev/null
+++ b/src/boost/libs/locale/index.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+ <title>Boost.Locale Documentation</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+ <meta http-equiv="refresh" content="0; URL=doc/html/index.html" />
+</head>
+
+<body>
+ Automatic redirection failed, please go to <a href=
+ "doc/html/index.html">doc/html/index.html</a>
+</body>
+</html>
+<!-- Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) Distributed under the Boost Software License, Version 1.0 -->
diff --git a/src/boost/libs/locale/meta/libraries.json b/src/boost/libs/locale/meta/libraries.json
new file mode 100644
index 000000000..2364222ea
--- /dev/null
+++ b/src/boost/libs/locale/meta/libraries.json
@@ -0,0 +1,14 @@
+{
+ "key": "locale",
+ "name": "Locale",
+ "authors": [
+ "Artyom Beilis"
+ ],
+ "description": "Provide localization and Unicode handling tools for C++.",
+ "category": [
+ "String"
+ ],
+ "maintainers": [
+ "Artyom Beilis <artyomtnk -at- yahoo.com>"
+ ]
+}
diff --git a/src/boost/libs/locale/performance/perf_collate.cpp b/src/boost/libs/locale/performance/perf_collate.cpp
new file mode 100644
index 000000000..c0721d8cd
--- /dev/null
+++ b/src/boost/libs/locale/performance/perf_collate.cpp
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <iostream>
+#include <string>
+#include <set>
+
+#include <boost/locale.hpp>
+
+using namespace std;
+using namespace boost::locale;
+
+int main(int argc,char **argv)
+{
+ if(argc!=2) {
+ std::cerr << "Usage backend locale" << std::endl;
+ return 1;
+ }
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select(argv[1]);
+ generator gen(mgr);
+ std::locale::global(gen(argv[2]));
+ /// Set global locale to requested
+
+ /// Create a set that includes all strings sorted according to ABC order
+ /// std::locale can be used as object for comparison
+ std::vector<std::string> all;
+ typedef std::set<std::string,std::locale> set_type;
+ set_type all_strings;
+
+ /// Read all strings into the set
+ while(!cin.eof()) {
+ std::string tmp;
+ getline(cin,tmp);
+ all.push_back(tmp);
+ }
+ for(int i=0;i<10000;i++) {
+ std::vector<std::string> tmp = all;
+ std::sort(tmp.begin(),tmp.end(),std::locale());
+ if(i==0) {
+ for(unsigned j=0;j<tmp.size();j++)
+ std::cout << tmp[j] << std::endl;
+ }
+ }
+
+}
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/performance/perf_convert.cpp b/src/boost/libs/locale/performance/perf_convert.cpp
new file mode 100644
index 000000000..6d69be65f
--- /dev/null
+++ b/src/boost/libs/locale/performance/perf_convert.cpp
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <iostream>
+#include <string>
+#include <set>
+
+#include <boost/locale.hpp>
+
+using namespace std;
+using namespace boost::locale;
+
+int main(int argc,char **argv)
+{
+ if(argc!=2) {
+ std::cerr << "Usage backend locale" << std::endl;
+ return 1;
+ }
+ /// Set global locale to requested
+
+ /// Create a set that includes all strings sorted according to ABC order
+ /// std::locale can be used as object for comparison
+ std::vector<std::string> all;
+ typedef std::set<std::string,std::locale> set_type;
+ set_type all_strings;
+
+ /// Read all strings into the set
+ while(!cin.eof()) {
+ std::string tmp;
+ getline(cin,tmp);
+ all.push_back(tmp);
+ }
+
+ {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select(argv[1]);
+ generator gen(mgr);
+ std::locale::global(gen(argv[2]));
+ for(int i=0;i<10000;i++) {
+ for(unsigned j=0;j<all.size();j++) {
+ boost::locale::to_upper(all[j]);
+ boost::locale::to_lower(all[j]);
+ if(i==0) {
+ std::cout << boost::locale::to_upper(all[j]) << std::endl;
+ std::cout << boost::locale::to_lower(all[j]) << std::endl;
+ }
+ }
+ }
+ }
+
+}
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/performance/perf_format.cpp b/src/boost/libs/locale/performance/perf_format.cpp
new file mode 100644
index 000000000..417e1ba3e
--- /dev/null
+++ b/src/boost/libs/locale/performance/perf_format.cpp
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <iostream>
+#include <string>
+#include <set>
+#include <ctime>
+#include <boost/locale.hpp>
+
+using namespace std;
+using namespace boost::locale;
+
+int main(int argc,char **argv)
+{
+ if(argc!=2) {
+ std::cerr << "Usage backend locale" << std::endl;
+ return 1;
+ }
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select(argv[1]);
+ generator gen(mgr);
+ std::locale::global(gen(argv[2]));
+ /// Set global locale to requested
+
+ for(int i=0;i<100000;i++) {
+ std::ostringstream ss;
+ for(int j=0;j<5;j++) {
+ ss << boost::locale::as::datetime << std::time(0) <<" "<< boost::locale::as::number << 13456.345 <<"\n";
+ }
+ if(i==0)
+ std::cout << ss.str() << std::endl;
+ }
+
+}
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/encoding/codepage.cpp b/src/boost/libs/locale/src/encoding/codepage.cpp
new file mode 100644
index 000000000..c19e36b8c
--- /dev/null
+++ b/src/boost/libs/locale/src/encoding/codepage.cpp
@@ -0,0 +1,201 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/config.hpp>
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+#define BOOST_LOCALE_WITH_WCONV
+#endif
+
+#ifdef BOOST_LOCALE_WITH_ICONV
+#include "iconv_codepage.ipp"
+#endif
+#ifdef BOOST_LOCALE_WITH_ICU
+#include "uconv_codepage.ipp"
+#endif
+#ifdef BOOST_LOCALE_WITH_WCONV
+#include "wconv_codepage.ipp"
+#endif
+
+#include <boost/locale/encoding.hpp>
+#include <boost/locale/hold_ptr.hpp>
+
+#include <string>
+#include <cstring>
+#include <memory>
+
+namespace boost {
+ namespace locale {
+ namespace conv {
+ namespace impl {
+
+ std::string convert_between(char const *begin,
+ char const *end,
+ char const *to_charset,
+ char const *from_charset,
+ method_type how)
+ {
+ hold_ptr<converter_between> cvt;
+ #ifdef BOOST_LOCALE_WITH_ICONV
+ cvt.reset(new iconv_between());
+ if(cvt->open(to_charset,from_charset,how))
+ return cvt->convert(begin,end);
+ #endif
+ #ifdef BOOST_LOCALE_WITH_ICU
+ cvt.reset(new uconv_between());
+ if(cvt->open(to_charset,from_charset,how))
+ return cvt->convert(begin,end);
+ #endif
+ #ifdef BOOST_LOCALE_WITH_WCONV
+ cvt.reset(new wconv_between());
+ if(cvt->open(to_charset,from_charset,how))
+ return cvt->convert(begin,end);
+ #endif
+ throw invalid_charset_error(std::string(to_charset) + " or " + from_charset);
+ }
+
+ template<typename CharType>
+ std::basic_string<CharType> convert_to(
+ char const *begin,
+ char const *end,
+ char const *charset,
+ method_type how)
+ {
+ hold_ptr<converter_to_utf<CharType> > cvt;
+ #ifdef BOOST_LOCALE_WITH_ICONV
+ cvt.reset(new iconv_to_utf<CharType>());
+ if(cvt->open(charset,how))
+ return cvt->convert(begin,end);
+ #endif
+ #ifdef BOOST_LOCALE_WITH_ICU
+ cvt.reset(new uconv_to_utf<CharType>());
+ if(cvt->open(charset,how))
+ return cvt->convert(begin,end);
+ #endif
+ #ifdef BOOST_LOCALE_WITH_WCONV
+ cvt.reset(new wconv_to_utf<CharType>());
+ if(cvt->open(charset,how))
+ return cvt->convert(begin,end);
+ #endif
+ throw invalid_charset_error(charset);
+ }
+
+ template<typename CharType>
+ std::string convert_from(
+ CharType const *begin,
+ CharType const *end,
+ char const *charset,
+ method_type how)
+ {
+ hold_ptr<converter_from_utf<CharType> > cvt;
+ #ifdef BOOST_LOCALE_WITH_ICONV
+ cvt.reset(new iconv_from_utf<CharType>());
+ if(cvt->open(charset,how))
+ return cvt->convert(begin,end);
+ #endif
+ #ifdef BOOST_LOCALE_WITH_ICU
+ cvt.reset(new uconv_from_utf<CharType>());
+ if(cvt->open(charset,how))
+ return cvt->convert(begin,end);
+ #endif
+ #ifdef BOOST_LOCALE_WITH_WCONV
+ cvt.reset(new wconv_from_utf<CharType>());
+ if(cvt->open(charset,how))
+ return cvt->convert(begin,end);
+ #endif
+ throw invalid_charset_error(charset);
+ }
+
+ std::string normalize_encoding(char const *ccharset)
+ {
+ std::string charset;
+ charset.reserve(std::strlen(ccharset));
+ while(*ccharset!=0) {
+ char c=*ccharset++;
+ if('0' <= c && c<= '9')
+ charset+=c;
+ else if('a' <=c && c <='z')
+ charset+=c;
+ else if('A' <=c && c <='Z')
+ charset+=char(c-'A'+'a');
+ }
+ return charset;
+ }
+
+
+ } // impl
+
+ using namespace impl;
+
+ std::string between(char const *begin,char const *end,
+ std::string const &to_charset,std::string const &from_charset,method_type how)
+ {
+ return convert_between(begin,end,to_charset.c_str(),from_charset.c_str(),how);
+ }
+
+ template<>
+ std::basic_string<char> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
+ {
+ return convert_to<char>(begin,end,charset.c_str(),how);
+ }
+
+ template<>
+ std::string from_utf(char const *begin,char const *end,std::string const &charset,method_type how)
+ {
+ return convert_from<char>(begin,end,charset.c_str(),how);
+ }
+
+ template<>
+ std::basic_string<wchar_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
+ {
+ return convert_to<wchar_t>(begin,end,charset.c_str(),how);
+ }
+
+ template<>
+ std::string from_utf(wchar_t const *begin,wchar_t const *end,std::string const &charset,method_type how)
+ {
+ return convert_from<wchar_t>(begin,end,charset.c_str(),how);
+ }
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ template<>
+ std::basic_string<char16_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
+ {
+ return convert_to<char16_t>(begin,end,charset.c_str(),how);
+ }
+
+ template<>
+ std::string from_utf(char16_t const *begin,char16_t const *end,std::string const &charset,method_type how)
+ {
+ return convert_from<char16_t>(begin,end,charset.c_str(),how);
+ }
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ template<>
+ std::basic_string<char32_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
+ {
+ return convert_to<char32_t>(begin,end,charset.c_str(),how);
+ }
+
+ template<>
+ std::string from_utf(char32_t const *begin,char32_t const *end,std::string const &charset,method_type how)
+ {
+ return convert_from<char32_t>(begin,end,charset.c_str(),how);
+ }
+ #endif
+
+
+ }
+ }
+}
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/encoding/conv.hpp b/src/boost/libs/locale/src/encoding/conv.hpp
new file mode 100644
index 000000000..5453aeded
--- /dev/null
+++ b/src/boost/libs/locale/src/encoding/conv.hpp
@@ -0,0 +1,118 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_LOCALE_CONV_IMPL_HPP
+#define BOOST_LOCALE_CONV_IMPL_HPP
+
+#include <boost/locale/config.hpp>
+#include <boost/locale/encoding.hpp>
+namespace boost {
+ namespace locale {
+ namespace conv {
+ namespace impl {
+
+ template<typename CharType>
+ char const *utf_name()
+ {
+ union {
+ char first;
+ uint16_t u16;
+ uint32_t u32;
+ } v;
+
+ if(sizeof(CharType) == 1) {
+ return "UTF-8";
+ }
+ else if(sizeof(CharType) == 2) {
+ v.u16 = 1;
+ if(v.first == 1) {
+ return "UTF-16LE";
+ }
+ else {
+ return "UTF-16BE";
+ }
+ }
+ else if(sizeof(CharType) == 4) {
+ v.u32 = 1;
+ if(v.first == 1) {
+ return "UTF-32LE";
+ }
+ else {
+ return "UTF-32BE";
+ }
+
+ }
+ else {
+ return "Unknown Character Encoding";
+ }
+ }
+
+ std::string normalize_encoding(char const *encoding);
+
+ inline int compare_encodings(char const *l,char const *r)
+ {
+ return normalize_encoding(l).compare(normalize_encoding(r));
+ }
+
+ #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int encoding_to_windows_codepage(char const *ccharset);
+ #endif
+
+ class converter_between {
+ public:
+ typedef char char_type;
+
+ typedef std::string string_type;
+
+ virtual bool open(char const *to_charset,char const *from_charset,method_type how) = 0;
+
+ virtual std::string convert(char const *begin,char const *end) = 0;
+
+ virtual ~converter_between()
+ {
+ }
+ };
+
+ template<typename CharType>
+ class converter_from_utf {
+ public:
+ typedef CharType char_type;
+
+ typedef std::basic_string<char_type> string_type;
+
+ virtual bool open(char const *charset,method_type how) = 0;
+
+ virtual std::string convert(CharType const *begin,CharType const *end) = 0;
+
+ virtual ~converter_from_utf()
+ {
+ }
+ };
+
+ template<typename CharType>
+ class converter_to_utf {
+ public:
+ typedef CharType char_type;
+
+ typedef std::basic_string<char_type> string_type;
+
+ virtual bool open(char const *charset,method_type how) = 0;
+
+ virtual string_type convert(char const *begin,char const *end) = 0;
+
+ virtual ~converter_to_utf()
+ {
+ }
+ };
+ }
+ }
+ }
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+#endif
diff --git a/src/boost/libs/locale/src/encoding/iconv_codepage.ipp b/src/boost/libs/locale/src/encoding/iconv_codepage.ipp
new file mode 100644
index 000000000..276c60b6b
--- /dev/null
+++ b/src/boost/libs/locale/src/encoding/iconv_codepage.ipp
@@ -0,0 +1,214 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
+#define BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
+
+#include <boost/locale/encoding.hpp>
+#include "../util/iconv.hpp"
+#include <errno.h>
+#include "conv.hpp"
+#include <assert.h>
+#include <vector>
+
+namespace boost {
+namespace locale {
+namespace conv {
+namespace impl {
+
+class iconverter_base {
+public:
+
+ iconverter_base() :
+ cvt_((iconv_t)(-1))
+ {
+ }
+
+ ~iconverter_base()
+ {
+ close();
+ }
+
+ size_t conv(char const **inbufc,size_t *inchar_left,
+ char **outbuf,size_t *outchar_left)
+ {
+ char **inbuf = const_cast<char **>(inbufc);
+ return call_iconv(cvt_,inbuf,inchar_left,outbuf,outchar_left);
+ }
+
+ bool do_open(char const *to,char const *from,method_type how)
+ {
+ close();
+ cvt_ = iconv_open(to,from);
+ how_ = how;
+ return cvt_ != (iconv_t)(-1);
+ }
+
+ template<typename OutChar,typename InChar>
+ std::basic_string<OutChar> real_convert(InChar const *ubegin,InChar const *uend)
+ {
+ std::basic_string<OutChar> sresult;
+
+ sresult.reserve(uend - ubegin);
+
+ OutChar result[64];
+
+ char *out_start = reinterpret_cast<char *>(&result[0]);
+ char const *begin = reinterpret_cast<char const *>(ubegin);
+ char const *end = reinterpret_cast<char const *>(uend);
+
+ enum { normal , unshifting , done } state = normal;
+
+ while(state!=done) {
+
+ size_t in_left = end - begin;
+ size_t out_left = sizeof(result);
+
+ char *out_ptr = out_start;
+ size_t res = 0;
+ if(in_left == 0)
+ state = unshifting;
+
+ if(state == normal)
+ res = conv(&begin,&in_left,&out_ptr,&out_left);
+ else
+ res = conv(0,0,&out_ptr,&out_left);
+
+ int err = errno;
+
+ size_t output_count = (out_ptr - out_start) / sizeof(OutChar);
+
+ if(res!=0 && res!=(size_t)(-1)) {
+ if(how_ == stop) {
+ throw conversion_error();
+ }
+ }
+
+ sresult.append(&result[0],output_count);
+
+ if(res == (size_t)(-1)) {
+ if(err == EILSEQ || err == EINVAL) {
+ if(how_ == stop) {
+ throw conversion_error();
+ }
+
+ if(begin != end) {
+ begin+=sizeof(InChar);
+ if(begin >= end)
+ break;
+ }
+ else {
+ break;
+ }
+ }
+ else if (err==E2BIG) {
+ continue;
+ }
+ else {
+ // We should never get there
+ // but if we do
+ if(how_ == stop)
+ throw conversion_error();
+ else
+ break;
+ }
+ }
+ if(state == unshifting)
+ state = done;
+ }
+ return sresult;
+ }
+
+
+private:
+
+ void close()
+ {
+ if(cvt_!=(iconv_t)(-1)) {
+ iconv_close(cvt_);
+ cvt_ = (iconv_t)(-1);
+ }
+ }
+
+ iconv_t cvt_;
+
+ method_type how_;
+
+};
+
+template<typename CharType>
+class iconv_from_utf : public converter_from_utf<CharType>
+{
+public:
+
+ typedef CharType char_type;
+
+ virtual bool open(char const *charset,method_type how)
+ {
+ return self_.do_open(charset,utf_name<CharType>(),how);
+ }
+
+ virtual std::string convert(char_type const *ubegin,char_type const *uend)
+ {
+ return self_.template real_convert<char,char_type>(ubegin,uend);
+ }
+ virtual ~iconv_from_utf() {}
+private:
+ iconverter_base self_;
+};
+
+class iconv_between: public converter_between
+{
+public:
+ virtual bool open(char const *to_charset,char const *from_charset,method_type how)
+ {
+ return self_.do_open(to_charset,from_charset,how);
+ }
+ virtual std::string convert(char const *begin,char const *end)
+ {
+ return self_.real_convert<char,char>(begin,end);
+ }
+ virtual ~iconv_between() {}
+private:
+ iconverter_base self_;
+
+};
+
+template<typename CharType>
+class iconv_to_utf : public converter_to_utf<CharType>
+{
+public:
+
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+
+ virtual bool open(char const *charset,method_type how)
+ {
+ return self_.do_open(utf_name<CharType>(),charset,how);
+ }
+
+ virtual string_type convert(char const *begin,char const *end)
+ {
+ return self_.template real_convert<char_type,char>(begin,end);
+ }
+ virtual ~iconv_to_utf() {}
+private:
+ iconverter_base self_;
+};
+
+
+
+} // impl
+} // conv
+} // locale
+} // boost
+
+
+
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/encoding/uconv_codepage.ipp b/src/boost/libs/locale/src/encoding/uconv_codepage.ipp
new file mode 100644
index 000000000..51e7301bb
--- /dev/null
+++ b/src/boost/libs/locale/src/encoding/uconv_codepage.ipp
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_UCONV_CODEPAGE_HPP
+#define BOOST_LOCALE_IMPL_UCONV_CODEPAGE_HPP
+#include <boost/locale/encoding.hpp>
+#include "conv.hpp"
+#include "../icu/icu_util.hpp"
+#include "../icu/uconv.hpp"
+#include <unicode/ucnv.h>
+#include <unicode/ucnv_err.h>
+#include <vector>
+#include <memory>
+
+#include <boost/locale/hold_ptr.hpp>
+
+namespace boost {
+namespace locale {
+namespace conv {
+namespace impl {
+ template<typename CharType>
+ class uconv_to_utf : public converter_to_utf<CharType> {
+ public:
+ typedef CharType char_type;
+
+ typedef std::basic_string<char_type> string_type;
+
+ virtual bool open(char const *charset,method_type how)
+ {
+ close();
+ try {
+ cvt_from_.reset(new from_type(charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
+ cvt_to_.reset(new to_type("UTF-8",how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
+ }
+ catch(std::exception const &/*e*/) {
+ close();
+ return false;
+ }
+ return true;
+ }
+ void close()
+ {
+ cvt_from_.reset();
+ cvt_to_.reset();
+ }
+
+ virtual string_type convert(char const *begin,char const *end)
+ {
+ try {
+ return cvt_to_->std(cvt_from_->icu_checked(begin,end));
+ }
+ catch(std::exception const &/*e*/) {
+ throw conversion_error();
+ }
+ }
+
+ private:
+
+ typedef impl_icu::icu_std_converter<char> from_type;
+ typedef impl_icu::icu_std_converter<CharType> to_type;
+
+ hold_ptr<from_type> cvt_from_;
+ hold_ptr<to_type> cvt_to_;
+
+ };
+
+
+ template<typename CharType>
+ class uconv_from_utf : public converter_from_utf<CharType> {
+ public:
+ typedef CharType char_type;
+ virtual bool open(char const *charset,method_type how)
+ {
+ close();
+ try {
+ cvt_from_.reset(new from_type("UTF-8",how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
+ cvt_to_.reset(new to_type(charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
+ }
+ catch(std::exception const &/*e*/) {
+ close();
+ return false;
+ }
+ return true;
+ }
+ void close()
+ {
+ cvt_from_.reset();
+ cvt_to_.reset();
+ }
+
+ virtual std::string convert(CharType const *begin,CharType const *end)
+ {
+ try {
+ return cvt_to_->std(cvt_from_->icu_checked(begin,end));
+ }
+ catch(std::exception const &/*e*/) {
+ throw conversion_error();
+ }
+ }
+
+ private:
+
+ typedef impl_icu::icu_std_converter<CharType> from_type;
+ typedef impl_icu::icu_std_converter<char> to_type;
+
+ hold_ptr<from_type> cvt_from_;
+ hold_ptr<to_type> cvt_to_;
+
+ };
+
+ class uconv_between : public converter_between {
+ public:
+ virtual bool open(char const *to_charset,char const *from_charset,method_type how)
+ {
+ close();
+ try {
+ cvt_from_.reset(new from_type(from_charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
+ cvt_to_.reset(new to_type(to_charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop));
+ }
+ catch(std::exception const &/*e*/) {
+ close();
+ return false;
+ }
+ return true;
+ }
+ void close()
+ {
+ cvt_from_.reset();
+ cvt_to_.reset();
+ }
+
+ virtual std::string convert(char const *begin,char const *end)
+ {
+ try {
+ return cvt_to_->std(cvt_from_->icu(begin,end));
+ }
+ catch(std::exception const &/*e*/) {
+ throw conversion_error();
+ }
+ }
+
+ private:
+
+ typedef impl_icu::icu_std_converter<char> from_type;
+ typedef impl_icu::icu_std_converter<char> to_type;
+
+ hold_ptr<from_type> cvt_from_;
+ hold_ptr<to_type> cvt_to_;
+
+ };
+
+
+} // impl
+} // conv
+} // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+#endif
diff --git a/src/boost/libs/locale/src/encoding/wconv_codepage.ipp b/src/boost/libs/locale/src/encoding/wconv_codepage.ipp
new file mode 100644
index 000000000..4ab9ece08
--- /dev/null
+++ b/src/boost/libs/locale/src/encoding/wconv_codepage.ipp
@@ -0,0 +1,539 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_LOCALE_IMPL_WCONV_CODEPAGE_HPP
+#define BOOST_LOCALE_IMPL_WCONV_CODEPAGE_HPP
+
+
+#include <boost/locale/encoding.hpp>
+#include <algorithm>
+#include <cstring>
+#include <string>
+#include "conv.hpp"
+
+#ifndef NOMINMAX
+# define NOMINMAX
+#endif
+#include <windows.h>
+#include <vector>
+
+
+namespace boost {
+namespace locale {
+namespace conv {
+namespace impl {
+
+ struct windows_encoding {
+ char const *name;
+ unsigned codepage;
+ unsigned was_tested;
+ };
+
+ bool operator<(windows_encoding const &l,windows_encoding const &r)
+ {
+ return strcmp(l.name,r.name) < 0;
+ }
+
+ windows_encoding all_windows_encodings[] = {
+ { "big5", 950, 0 },
+ { "cp1250", 1250, 0 },
+ { "cp1251", 1251, 0 },
+ { "cp1252", 1252, 0 },
+ { "cp1253", 1253, 0 },
+ { "cp1254", 1254, 0 },
+ { "cp1255", 1255, 0 },
+ { "cp1256", 1256, 0 },
+ { "cp1257", 1257, 0 },
+ { "cp874", 874, 0 },
+ { "cp932", 932, 0 },
+ { "cp936", 936, 0 },
+ { "eucjp", 20932, 0 },
+ { "euckr", 51949, 0 },
+ { "gb18030", 54936, 0 },
+ { "gb2312", 20936, 0 },
+ { "gbk", 936, 0 },
+ { "iso2022jp", 50220, 0 },
+ { "iso2022kr", 50225, 0 },
+ { "iso88591", 28591, 0 },
+ { "iso885913", 28603, 0 },
+ { "iso885915", 28605, 0 },
+ { "iso88592", 28592, 0 },
+ { "iso88593", 28593, 0 },
+ { "iso88594", 28594, 0 },
+ { "iso88595", 28595, 0 },
+ { "iso88596", 28596, 0 },
+ { "iso88597", 28597, 0 },
+ { "iso88598", 28598, 0 },
+ { "iso88599", 28599, 0 },
+ { "koi8r", 20866, 0 },
+ { "koi8u", 21866, 0 },
+ { "ms936", 936, 0 },
+ { "shiftjis", 932, 0 },
+ { "sjis", 932, 0 },
+ { "usascii", 20127, 0 },
+ { "utf8", 65001, 0 },
+ { "windows1250", 1250, 0 },
+ { "windows1251", 1251, 0 },
+ { "windows1252", 1252, 0 },
+ { "windows1253", 1253, 0 },
+ { "windows1254", 1254, 0 },
+ { "windows1255", 1255, 0 },
+ { "windows1256", 1256, 0 },
+ { "windows1257", 1257, 0 },
+ { "windows874", 874, 0 },
+ { "windows932", 932, 0 },
+ { "windows936", 936, 0 },
+ };
+
+ size_t remove_substitutions(std::vector<char> &v)
+ {
+ if(std::find(v.begin(),v.end(),0) == v.end()) {
+ return v.size();
+ }
+ std::vector<char> v2;
+ v2.reserve(v.size());
+ for(unsigned i=0;i<v.size();i++) {
+ if(v[i]!=0)
+ v2.push_back(v[i]);
+ }
+ v.swap(v2);
+ return v.size();
+ }
+
+ void multibyte_to_wide_one_by_one(int codepage,char const *begin,char const *end,std::vector<wchar_t> &buf)
+ {
+ buf.reserve(end-begin);
+ while(begin!=end) {
+ wchar_t wide_buf[4];
+ int n = 0;
+ int len = IsDBCSLeadByteEx(codepage,*begin) ? 2 : 1;
+ if(len == 2 && begin+1==end)
+ return;
+ n = MultiByteToWideChar(codepage,MB_ERR_INVALID_CHARS,begin,len,wide_buf,4);
+ for(int i=0;i<n;i++)
+ buf.push_back(wide_buf[i]);
+ begin+=len;
+ }
+ }
+
+
+ void multibyte_to_wide(int codepage,char const *begin,char const *end,bool do_skip,std::vector<wchar_t> &buf)
+ {
+ if(begin==end)
+ return;
+ int n = MultiByteToWideChar(codepage,MB_ERR_INVALID_CHARS,begin,end-begin,0,0);
+ if(n == 0) {
+ if(do_skip) {
+ multibyte_to_wide_one_by_one(codepage,begin,end,buf);
+ return;
+ }
+ throw conversion_error();
+ }
+
+ buf.resize(n,0);
+ if(MultiByteToWideChar(codepage,MB_ERR_INVALID_CHARS,begin,end-begin,&buf.front(),buf.size())==0)
+ throw conversion_error();
+ }
+
+ void wide_to_multibyte_non_zero(int codepage,wchar_t const *begin,wchar_t const *end,bool do_skip,std::vector<char> &buf)
+ {
+ if(begin==end)
+ return;
+ BOOL substitute = FALSE;
+ BOOL *substitute_ptr = codepage == 65001 || codepage == 65000 ? 0 : &substitute;
+ char subst_char = 0;
+ char *subst_char_ptr = codepage == 65001 || codepage == 65000 ? 0 : &subst_char;
+
+ int n = WideCharToMultiByte(codepage,0,begin,end-begin,0,0,subst_char_ptr,substitute_ptr);
+ buf.resize(n);
+
+ if(WideCharToMultiByte(codepage,0,begin,end-begin,&buf[0],n,subst_char_ptr,substitute_ptr)==0)
+ throw conversion_error();
+ if(substitute) {
+ if(do_skip)
+ remove_substitutions(buf);
+ else
+ throw conversion_error();
+ }
+ }
+
+ void wide_to_multibyte(int codepage,wchar_t const *begin,wchar_t const *end,bool do_skip,std::vector<char> &buf)
+ {
+ if(begin==end)
+ return;
+ buf.reserve(end-begin);
+ wchar_t const *e = std::find(begin,end,L'\0');
+ wchar_t const *b = begin;
+ for(;;) {
+ std::vector<char> tmp;
+ wide_to_multibyte_non_zero(codepage,b,e,do_skip,tmp);
+ size_t osize = buf.size();
+ buf.resize(osize+tmp.size());
+ std::copy(tmp.begin(),tmp.end(),buf.begin()+osize);
+ if(e!=end) {
+ buf.push_back('\0');
+ b=e+1;
+ e=std::find(b,end,L'0');
+ }
+ else
+ break;
+ }
+ }
+
+
+ int encoding_to_windows_codepage(char const *ccharset)
+ {
+ std::string charset = normalize_encoding(ccharset);
+ windows_encoding ref;
+ ref.name = charset.c_str();
+ size_t n = sizeof(all_windows_encodings)/sizeof(all_windows_encodings[0]);
+ windows_encoding *begin = all_windows_encodings;
+ windows_encoding *end = all_windows_encodings + n;
+ windows_encoding *ptr = std::lower_bound(begin,end,ref);
+ if(ptr!=end && strcmp(ptr->name,charset.c_str())==0) {
+ if(ptr->was_tested) {
+ return ptr->codepage;
+ }
+ else if(IsValidCodePage(ptr->codepage)) {
+ // the thread safety is not an issue, maximum
+ // it would be checked more then once
+ ptr->was_tested=1;
+ return ptr->codepage;
+ }
+ else {
+ return -1;
+ }
+ }
+ return -1;
+
+ }
+
+ template<typename CharType>
+ bool validate_utf16(CharType const *str,unsigned len)
+ {
+ CharType const *begin = str;
+ CharType const *end = str+len;
+ while(begin!=end) {
+ utf::code_point c = utf::utf_traits<CharType,2>::template decode<CharType const *>(begin,end);
+ if(c==utf::illegal || c==utf::incomplete)
+ return false;
+ }
+ return true;
+ }
+
+ template<typename CharType,typename OutChar>
+ void clean_invalid_utf16(CharType const *str,unsigned len,std::vector<OutChar> &out)
+ {
+ out.reserve(len);
+ for(unsigned i=0;i<len;i++) {
+ uint16_t c = static_cast<uint16_t>(str[i]);
+
+ if(0xD800 <= c && c<= 0xDBFF) {
+ i++;
+ if(i>=len)
+ return;
+ uint16_t c2=static_cast<uint16_t>(str[i]);
+ if(0xDC00 <= c2 && c2 <= 0xDFFF) {
+ out.push_back(static_cast<OutChar>(c));
+ out.push_back(static_cast<OutChar>(c2));
+ }
+ }
+ else if(0xDC00 <= c && c <=0xDFFF)
+ continue;
+ else
+ out.push_back(static_cast<OutChar>(c));
+ }
+ }
+
+
+ class wconv_between : public converter_between {
+ public:
+ wconv_between() :
+ how_(skip),
+ to_code_page_ (-1),
+ from_code_page_ ( -1)
+ {
+ }
+ bool open(char const *to_charset,char const *from_charset,method_type how)
+ {
+ how_ = how;
+ to_code_page_ = encoding_to_windows_codepage(to_charset);
+ from_code_page_ = encoding_to_windows_codepage(from_charset);
+ if(to_code_page_ == -1 || from_code_page_ == -1)
+ return false;
+ return true;
+ }
+ virtual std::string convert(char const *begin,char const *end)
+ {
+ if(to_code_page_ == 65001 && from_code_page_ == 65001)
+ return utf_to_utf<char>(begin,end,how_);
+
+ std::string res;
+
+ std::vector<wchar_t> tmp; // buffer for mb2w
+ std::wstring tmps; // buffer for utf_to_utf
+ wchar_t const *wbegin=0;
+ wchar_t const *wend=0;
+
+ if(from_code_page_ == 65001) {
+ tmps = utf_to_utf<wchar_t>(begin,end,how_);
+ if(tmps.empty())
+ return res;
+ wbegin = tmps.c_str();
+ wend = wbegin + tmps.size();
+ }
+ else {
+ multibyte_to_wide(from_code_page_,begin,end,how_ == skip,tmp);
+ if(tmp.empty())
+ return res;
+ wbegin = &tmp[0];
+ wend = wbegin + tmp.size();
+ }
+
+ if(to_code_page_ == 65001) {
+ return utf_to_utf<char>(wbegin,wend,how_);
+ }
+
+ std::vector<char> ctmp;
+ wide_to_multibyte(to_code_page_,wbegin,wend,how_ == skip,ctmp);
+ if(ctmp.empty())
+ return res;
+ res.assign(&ctmp.front(),ctmp.size());
+ return res;
+ }
+ private:
+ method_type how_;
+ int to_code_page_;
+ int from_code_page_;
+ };
+
+ template<typename CharType,int size = sizeof(CharType) >
+ class wconv_to_utf;
+
+ template<typename CharType,int size = sizeof(CharType) >
+ class wconv_from_utf;
+
+ template<>
+ class wconv_to_utf<char,1> : public converter_to_utf<char> , public wconv_between {
+ public:
+ virtual bool open(char const *cs,method_type how)
+ {
+ return wconv_between::open("UTF-8",cs,how);
+ }
+ virtual std::string convert(char const *begin,char const *end)
+ {
+ return wconv_between::convert(begin,end);
+ }
+ };
+
+ template<>
+ class wconv_from_utf<char,1> : public converter_from_utf<char> , public wconv_between {
+ public:
+ virtual bool open(char const *cs,method_type how)
+ {
+ return wconv_between::open(cs,"UTF-8",how);
+ }
+ virtual std::string convert(char const *begin,char const *end)
+ {
+ return wconv_between::convert(begin,end);
+ }
+ };
+
+ template<typename CharType>
+ class wconv_to_utf<CharType,2> : public converter_to_utf<CharType> {
+ public:
+ typedef CharType char_type;
+
+ typedef std::basic_string<char_type> string_type;
+
+ wconv_to_utf() :
+ how_(skip),
+ code_page_(-1)
+ {
+ }
+
+ virtual bool open(char const *charset,method_type how)
+ {
+ how_ = how;
+ code_page_ = encoding_to_windows_codepage(charset);
+ return code_page_ != -1;
+ }
+
+ virtual string_type convert(char const *begin,char const *end)
+ {
+ if(code_page_ == 65001) {
+ return utf_to_utf<char_type>(begin,end,how_);
+ }
+ std::vector<wchar_t> tmp;
+ multibyte_to_wide(code_page_,begin,end,how_ == skip,tmp);
+ string_type res;
+ if(!tmp.empty())
+ res.assign(reinterpret_cast<char_type *>(&tmp.front()),tmp.size());
+ return res;
+ }
+
+ private:
+ method_type how_;
+ int code_page_;
+ };
+
+ template<typename CharType>
+ class wconv_from_utf<CharType,2> : public converter_from_utf<CharType> {
+ public:
+ typedef CharType char_type;
+
+ typedef std::basic_string<char_type> string_type;
+
+ wconv_from_utf() :
+ how_(skip),
+ code_page_(-1)
+ {
+ }
+
+ virtual bool open(char const *charset,method_type how)
+ {
+ how_ = how;
+ code_page_ = encoding_to_windows_codepage(charset);
+ return code_page_ != -1;
+ }
+
+ virtual std::string convert(CharType const *begin,CharType const *end)
+ {
+ if(code_page_ == 65001) {
+ return utf_to_utf<char>(begin,end,how_);
+ }
+ wchar_t const *wbegin = 0;
+ wchar_t const *wend = 0;
+ std::vector<wchar_t> buffer; // if needed
+ if(begin==end)
+ return std::string();
+ if(validate_utf16(begin,end-begin)) {
+ wbegin = reinterpret_cast<wchar_t const *>(begin);
+ wend = reinterpret_cast<wchar_t const *>(end);
+ }
+ else {
+ if(how_ == stop) {
+ throw conversion_error();
+ }
+ else {
+ clean_invalid_utf16(begin,end-begin,buffer);
+ if(!buffer.empty()) {
+ wbegin = &buffer[0];
+ wend = wbegin + buffer.size();
+ }
+ }
+ }
+ std::string res;
+ if(wbegin==wend)
+ return res;
+ std::vector<char> ctmp;
+ wide_to_multibyte(code_page_,wbegin,wend,how_ == skip,ctmp);
+ if(ctmp.empty())
+ return res;
+ res.assign(&ctmp.front(),ctmp.size());
+ return res;
+ }
+
+ private:
+ method_type how_;
+ int code_page_;
+ };
+
+
+
+ template<typename CharType>
+ class wconv_to_utf<CharType,4> : public converter_to_utf<CharType> {
+ public:
+ typedef CharType char_type;
+
+ typedef std::basic_string<char_type> string_type;
+
+ wconv_to_utf() :
+ how_(skip),
+ code_page_(-1)
+ {
+ }
+
+ virtual bool open(char const *charset,method_type how)
+ {
+ how_ = how;
+ code_page_ = encoding_to_windows_codepage(charset);
+ return code_page_ != -1;
+ }
+
+ virtual string_type convert(char const *begin,char const *end)
+ {
+ if(code_page_ == 65001) {
+ return utf_to_utf<char_type>(begin,end,how_);
+ }
+ std::vector<wchar_t> buf;
+ multibyte_to_wide(code_page_,begin,end,how_ == skip,buf);
+
+ if(buf.empty())
+ return string_type();
+
+ return utf_to_utf<CharType>(&buf[0],&buf[0]+buf.size(),how_);
+ }
+ private:
+ method_type how_;
+ int code_page_;
+ };
+
+ template<typename CharType>
+ class wconv_from_utf<CharType,4> : public converter_from_utf<CharType> {
+ public:
+ typedef CharType char_type;
+
+ typedef std::basic_string<char_type> string_type;
+
+ wconv_from_utf() :
+ how_(skip),
+ code_page_(-1)
+ {
+ }
+
+ virtual bool open(char const *charset,method_type how)
+ {
+ how_ = how;
+ code_page_ = encoding_to_windows_codepage(charset);
+ return code_page_ != -1;
+ }
+
+ virtual std::string convert(CharType const *begin,CharType const *end)
+ {
+ if(code_page_ == 65001) {
+ return utf_to_utf<char>(begin,end,how_);
+ }
+ std::wstring tmp = utf_to_utf<wchar_t>(begin,end,how_);
+
+ std::vector<char> ctmp;
+ wide_to_multibyte(code_page_,tmp.c_str(),tmp.c_str()+tmp.size(),how_ == skip,ctmp);
+ std::string res;
+ if(ctmp.empty())
+ return res;
+ res.assign(&ctmp.front(),ctmp.size());
+ return res;
+
+ }
+
+ private:
+ method_type how_;
+ int code_page_;
+ };
+
+
+
+
+
+} // impl
+} // conv
+} // locale
+} // boost
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/all_generator.hpp b/src/boost/libs/locale/src/icu/all_generator.hpp
new file mode 100644
index 000000000..ca8f26d63
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/all_generator.hpp
@@ -0,0 +1,30 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_ALL_GENERATOR_HPP
+#define BOOST_LOCALE_IMPL_ALL_GENERATOR_HPP
+
+#include <boost/locale/generator.hpp>
+
+namespace boost {
+ namespace locale {
+ namespace impl_icu {
+ struct cdata;
+ std::locale create_convert(std::locale const &,cdata const &,character_facet_type); // ok
+ std::locale create_collate(std::locale const &,cdata const &,character_facet_type); // ok
+ std::locale create_formatting(std::locale const &,cdata const &,character_facet_type); // ok
+ std::locale create_parsing(std::locale const &,cdata const &,character_facet_type); // ok
+ std::locale create_codecvt(std::locale const &,std::string const &encoding,character_facet_type); // ok
+ std::locale create_boundary(std::locale const &,cdata const &,character_facet_type); // ok
+ std::locale create_calendar(std::locale const &,cdata const &); // ok
+
+ }
+ }
+}
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/boundary.cpp b/src/boost/libs/locale/src/icu/boundary.cpp
new file mode 100644
index 000000000..8d2651042
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/boundary.cpp
@@ -0,0 +1,231 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/boundary.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/hold_ptr.hpp>
+#include <unicode/uversion.h>
+#if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 306
+#include <unicode/utext.h>
+#endif
+#include <unicode/brkiter.h>
+#include <unicode/rbbi.h>
+
+#include "cdata.hpp"
+#include "all_generator.hpp"
+#include "icu_util.hpp"
+#include "uconv.hpp"
+
+namespace boost {
+namespace locale {
+namespace boundary {
+namespace impl_icu {
+
+using namespace boost::locale::impl_icu;
+
+index_type map_direct(boundary_type t,icu::BreakIterator *it,int reserve)
+{
+ index_type indx;
+ indx.reserve(reserve);
+#if U_ICU_VERSION_MAJOR_NUM >= 52
+ icu::BreakIterator *rbbi=it;
+#else
+ icu::RuleBasedBreakIterator *rbbi=dynamic_cast<icu::RuleBasedBreakIterator *>(it);
+#endif
+
+ indx.push_back(break_info());
+ it->first();
+ int pos=0;
+ while((pos=it->next())!=icu::BreakIterator::DONE) {
+ indx.push_back(break_info(pos));
+ /// Character does not have any specific break types
+ if(t!=character && rbbi) {
+ //
+ // There is a collapse for MSVC: int32_t defined by both boost::cstdint and icu...
+ // So need to pick one ;(
+ //
+ std::vector< ::int32_t> buffer;
+ ::int32_t membuf[8]={0}; // try not to use memory allocation if possible
+ ::int32_t *buf=membuf;
+
+ UErrorCode err=U_ZERO_ERROR;
+ int n = rbbi->getRuleStatusVec(buf,8,err);
+
+ if(err == U_BUFFER_OVERFLOW_ERROR) {
+ buf=&buffer.front();
+ buffer.resize(n,0);
+ n = rbbi->getRuleStatusVec(buf,buffer.size(),err);
+ }
+
+ check_and_throw_icu_error(err);
+
+ for(int i=0;i<n;i++) {
+ switch(t) {
+ case word:
+ if(UBRK_WORD_NONE<=buf[i] && buf[i]<UBRK_WORD_NONE_LIMIT)
+ indx.back().rule |= word_none;
+ else if(UBRK_WORD_NUMBER<=buf[i] && buf[i]<UBRK_WORD_NUMBER_LIMIT)
+ indx.back().rule |= word_number;
+ else if(UBRK_WORD_LETTER<=buf[i] && buf[i]<UBRK_WORD_LETTER_LIMIT)
+ indx.back().rule |= word_letter;
+ else if(UBRK_WORD_KANA<=buf[i] && buf[i]<UBRK_WORD_KANA_LIMIT)
+ indx.back().rule |= word_kana;
+ else if(UBRK_WORD_IDEO<=buf[i] && buf[i]<UBRK_WORD_IDEO_LIMIT)
+ indx.back().rule |= word_ideo;
+ break;
+
+ case line:
+ if(UBRK_LINE_SOFT<=buf[i] && buf[i]<UBRK_LINE_SOFT_LIMIT)
+ indx.back().rule |= line_soft;
+ else if(UBRK_LINE_HARD<=buf[i] && buf[i]<UBRK_LINE_HARD_LIMIT)
+ indx.back().rule |= line_hard;
+ break;
+
+ case sentence:
+ if(UBRK_SENTENCE_TERM<=buf[i] && buf[i]<UBRK_SENTENCE_TERM_LIMIT)
+ indx.back().rule |= sentence_term;
+ else if(UBRK_SENTENCE_SEP<=buf[i] && buf[i]<UBRK_SENTENCE_SEP_LIMIT)
+ indx.back().rule |= sentence_sep;
+ break;
+ default:
+ ;
+ }
+ }
+ }
+ else {
+ indx.back().rule |=character_any; // Baisc mark... for character
+ }
+ }
+ return indx;
+}
+
+icu::BreakIterator *get_iterator(boundary_type t,icu::Locale const &loc)
+{
+ UErrorCode err=U_ZERO_ERROR;
+ hold_ptr<icu::BreakIterator> bi;
+ switch(t) {
+ case character:
+ bi.reset(icu::BreakIterator::createCharacterInstance(loc,err));
+ break;
+ case word:
+ bi.reset(icu::BreakIterator::createWordInstance(loc,err));
+ break;
+ case sentence:
+ bi.reset(icu::BreakIterator::createSentenceInstance(loc,err));
+ break;
+ case line:
+ bi.reset(icu::BreakIterator::createLineInstance(loc,err));
+ break;
+ default:
+ throw std::runtime_error("Invalid iteration type");
+ }
+ check_and_throw_icu_error(err);
+ if(!bi.get())
+ throw std::runtime_error("Failed to create break iterator");
+ return bi.release();
+}
+
+
+template<typename CharType>
+index_type do_map(boundary_type t,CharType const *begin,CharType const *end,icu::Locale const &loc,std::string const &encoding)
+{
+ index_type indx;
+ hold_ptr<icu::BreakIterator> bi(get_iterator(t,loc));
+
+#if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 306
+ UErrorCode err=U_ZERO_ERROR;
+ if(sizeof(CharType) == 2 || (sizeof(CharType)==1 && encoding=="UTF-8"))
+ {
+ UText *ut=0;
+ try {
+ if(sizeof(CharType)==1)
+ ut=utext_openUTF8(0,reinterpret_cast<char const *>(begin),end-begin,&err);
+ else // sizeof(CharType)==2
+ ut=utext_openUChars(0,reinterpret_cast<UChar const *>(begin),end-begin,&err);
+
+ check_and_throw_icu_error(err);
+ err=U_ZERO_ERROR;
+ if(!ut) throw std::runtime_error("Failed to create UText");
+ bi->setText(ut,err);
+ check_and_throw_icu_error(err);
+ index_type res=map_direct(t,bi.get(),end-begin);
+ indx.swap(res);
+ }
+ catch(...) {
+ if(ut)
+ utext_close(ut);
+ throw;
+ }
+ if(ut) utext_close(ut);
+ }
+ else
+#endif
+ {
+ icu_std_converter<CharType> cvt(encoding);
+ icu::UnicodeString str=cvt.icu(begin,end);
+ bi->setText(str);
+ index_type indirect = map_direct(t,bi.get(),str.length());
+ indx=indirect;
+ for(size_t i=1;i<indirect.size();i++) {
+ size_t offset_inderect=indirect[i-1].offset;
+ size_t diff = indirect[i].offset - offset_inderect;
+ size_t offset_direct=indx[i-1].offset;
+ indx[i].offset=offset_direct + cvt.cut(str,begin,end,diff,offset_inderect,offset_direct);
+ }
+ }
+ return indx;
+} // do_map
+
+template<typename CharType>
+class boundary_indexing_impl : public boundary_indexing<CharType> {
+public:
+ boundary_indexing_impl(cdata const &data) :
+ locale_(data.locale),
+ encoding_(data.encoding)
+ {
+ }
+ index_type map(boundary_type t,CharType const *begin,CharType const *end) const
+ {
+ return do_map<CharType>(t,begin,end,locale_,encoding_);
+ }
+private:
+ icu::Locale locale_;
+ std::string encoding_;
+};
+
+
+
+} // impl_icu
+} // boundary
+
+namespace impl_icu {
+ std::locale create_boundary(std::locale const &in,cdata const &cd,character_facet_type type)
+ {
+ using namespace boost::locale::boundary::impl_icu;
+ switch(type) {
+ case char_facet:
+ return std::locale(in,new boundary_indexing_impl<char>(cd));
+ case wchar_t_facet:
+ return std::locale(in,new boundary_indexing_impl<wchar_t>(cd));
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ return std::locale(in,new boundary_indexing_impl<char16_t>(cd));
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ return std::locale(in,new boundary_indexing_impl<char32_t>(cd));
+ #endif
+ default:
+ return in;
+ }
+ }
+} // impl_icu
+
+} // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/cdata.hpp b/src/boost/libs/locale/src/icu/cdata.hpp
new file mode 100644
index 000000000..2bffeab4c
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/cdata.hpp
@@ -0,0 +1,28 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_ICU_CDATA_HPP
+#define BOOST_LOCALE_ICU_CDATA_HPP
+
+#include <unicode/locid.h>
+#include <string>
+
+namespace boost {
+ namespace locale {
+ namespace impl_icu {
+ struct cdata {
+ icu::Locale locale;
+ std::string encoding;
+ bool utf8;
+ };
+ }
+ }
+}
+
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/codecvt.cpp b/src/boost/libs/locale/src/icu/codecvt.cpp
new file mode 100644
index 000000000..2cecdb7dd
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/codecvt.cpp
@@ -0,0 +1,159 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/encoding.hpp>
+#include <boost/locale/encoding_errors.hpp>
+#include "../encoding/conv.hpp"
+#include "all_generator.hpp"
+#include "uconv.hpp"
+#include <unicode/ucnv.h>
+#include <unicode/ucnv_err.h>
+#include <boost/locale/util.hpp>
+#include <boost/locale/hold_ptr.hpp>
+#include "codecvt.hpp"
+
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4244) // loose data
+#endif
+
+#include "icu_util.hpp"
+#include <vector>
+namespace boost {
+namespace locale {
+namespace impl_icu {
+ class uconv_converter : public util::base_converter {
+ public:
+
+ uconv_converter(std::string const &encoding) :
+ encoding_(encoding)
+ {
+ UErrorCode err=U_ZERO_ERROR;
+
+ // No need to check err each time, this
+ // is how ICU works.
+ cvt_ = ucnv_open(encoding.c_str(),&err);
+ ucnv_setFromUCallBack(cvt_,UCNV_FROM_U_CALLBACK_STOP,0,0,0,&err);
+ ucnv_setToUCallBack(cvt_,UCNV_TO_U_CALLBACK_STOP,0,0,0,&err);
+
+ if(!cvt_ || U_FAILURE(err)) {
+ if(cvt_)
+ ucnv_close(cvt_);
+ throw conv::invalid_charset_error(encoding);
+ }
+
+ max_len_ = ucnv_getMaxCharSize(cvt_);
+ }
+
+ virtual ~uconv_converter()
+ {
+ ucnv_close(cvt_);
+ }
+
+ virtual bool is_thread_safe() const
+ {
+ return false;
+ }
+
+ virtual uconv_converter *clone() const
+ {
+ return new uconv_converter(encoding_);
+ }
+
+ uint32_t to_unicode(char const *&begin,char const *end)
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ char const *tmp = begin;
+ UChar32 c=ucnv_getNextUChar(cvt_,&tmp,end,&err);
+ ucnv_reset(cvt_);
+ if(err == U_TRUNCATED_CHAR_FOUND) {
+ return incomplete;
+ }
+ if(U_FAILURE(err)) {
+ return illegal;
+ }
+
+ begin = tmp;
+ return c;
+ }
+
+ uint32_t from_unicode(uint32_t u,char *begin,char const *end)
+ {
+ UChar code_point[2]={0};
+ int len;
+ if(u<=0xFFFF) {
+ if(0xD800 <=u && u<= 0xDFFF) // No surragates
+ return illegal;
+ code_point[0]=u;
+ len=1;
+ }
+ else {
+ u-=0x10000;
+ code_point[0]=0xD800 | (u>>10);
+ code_point[1]=0xDC00 | (u & 0x3FF);
+ len=2;
+ }
+ UErrorCode err=U_ZERO_ERROR;
+ int olen = ucnv_fromUChars(cvt_,begin,end-begin,code_point,len,&err);
+ ucnv_reset(cvt_);
+ if(err == U_BUFFER_OVERFLOW_ERROR)
+ return incomplete;
+ if(U_FAILURE(err))
+ return illegal;
+ return olen;
+ }
+
+ virtual int max_len() const
+ {
+ return max_len_;
+ }
+
+ private:
+ std::string encoding_;
+ UConverter *cvt_;
+ int max_len_;
+ };
+
+ util::base_converter *create_uconv_converter(std::string const &encoding)
+ {
+ hold_ptr<util::base_converter> cvt;
+ try {
+ cvt.reset(new uconv_converter(encoding));
+ }
+ catch(std::exception const &/*e*/)
+ {
+ // no encoding so we return empty pointer
+ }
+ return cvt.release();
+ }
+
+ std::locale create_codecvt(std::locale const &in,std::string const &encoding,character_facet_type type)
+ {
+ if(conv::impl::normalize_encoding(encoding.c_str())=="utf8")
+ return util::create_utf8_codecvt(in,type);
+
+ try {
+ return util::create_simple_codecvt(in,encoding,type);
+ }
+ catch(boost::locale::conv::invalid_charset_error const &) {
+ hold_ptr<util::base_converter> cvt;
+ try {
+ cvt.reset(create_uconv_converter(encoding));
+ }
+ catch(std::exception const &/*e*/)
+ {
+ cvt.reset(new util::base_converter());
+ }
+ return util::create_codecvt_from_pointer(in,cvt.release(),type);
+ }
+ }
+
+} // impl_icu
+} // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/codecvt.hpp b/src/boost/libs/locale/src/icu/codecvt.hpp
new file mode 100644
index 000000000..1e3987901
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/codecvt.hpp
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_ICU_CODECVT_HPP
+#define BOOST_LOCALE_IMPL_ICU_CODECVT_HPP
+#include <boost/locale/config.hpp>
+#include <boost/locale/util.hpp>
+#include <memory>
+namespace boost {
+namespace locale {
+namespace impl_icu {
+ BOOST_LOCALE_DECL
+ util::base_converter *create_uconv_converter(std::string const &encoding);
+
+} // impl_icu
+} // locale
+} // boost
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/collator.cpp b/src/boost/libs/locale/src/icu/collator.cpp
new file mode 100644
index 000000000..7f1ea6ae5
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/collator.cpp
@@ -0,0 +1,201 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/collator.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/thread.hpp>
+#include <vector>
+#include <limits>
+
+#include "cdata.hpp"
+#include "all_generator.hpp"
+#include "uconv.hpp"
+#include "../shared/mo_hash.hpp"
+
+#include <unicode/coll.h>
+#if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 402
+# include <unicode/stringpiece.h>
+#endif
+
+namespace boost {
+ namespace locale {
+ namespace impl_icu {
+ template<typename CharType>
+ class collate_impl : public collator<CharType>
+ {
+ public:
+ typedef typename collator<CharType>::level_type level_type;
+ level_type limit(level_type level) const
+ {
+ if(level < 0)
+ level=collator_base::primary;
+ else if(level >= level_count)
+ level = static_cast<level_type>(level_count - 1);
+ return level;
+ }
+
+ #if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 402
+ int do_utf8_compare( level_type level,
+ char const *b1,char const *e1,
+ char const *b2,char const *e2,
+ UErrorCode &status) const
+ {
+ icu::StringPiece left (b1,e1-b1);
+ icu::StringPiece right(b2,e2-b2);
+ return get_collator(level)->compareUTF8(left,right,status);
+
+ }
+ #endif
+
+ int do_ustring_compare( level_type level,
+ CharType const *b1,CharType const *e1,
+ CharType const *b2,CharType const *e2,
+ UErrorCode &status) const
+ {
+ icu::UnicodeString left=cvt_.icu(b1,e1);
+ icu::UnicodeString right=cvt_.icu(b2,e2);
+ return get_collator(level)->compare(left,right,status);
+ }
+
+ int do_real_compare(level_type level,
+ CharType const *b1,CharType const *e1,
+ CharType const *b2,CharType const *e2,
+ UErrorCode &status) const
+ {
+ return do_ustring_compare(level,b1,e1,b2,e2,status);
+ }
+
+ virtual int do_compare( level_type level,
+ CharType const *b1,CharType const *e1,
+ CharType const *b2,CharType const *e2) const
+ {
+ UErrorCode status=U_ZERO_ERROR;
+
+ int res = do_real_compare(level,b1,e1,b2,e2,status);
+
+ if(U_FAILURE(status))
+ throw std::runtime_error(std::string("Collation failed:") + u_errorName(status));
+ if(res < 0)
+ return -1;
+ else if(res > 0)
+ return 1;
+ return 0;
+ }
+
+ std::vector<uint8_t> do_basic_transform(level_type level,CharType const *b,CharType const *e) const
+ {
+ icu::UnicodeString str=cvt_.icu(b,e);
+ std::vector<uint8_t> tmp;
+ tmp.resize(str.length());
+ icu::Collator *collate = get_collator(level);
+ int len = collate->getSortKey(str,&tmp[0],tmp.size());
+ if(len > int(tmp.size())) {
+ tmp.resize(len);
+ collate->getSortKey(str,&tmp[0],tmp.size());
+ }
+ else
+ tmp.resize(len);
+ return tmp;
+ }
+ std::basic_string<CharType> do_transform(level_type level,CharType const *b,CharType const *e) const
+ {
+ std::vector<uint8_t> tmp = do_basic_transform(level,b,e);
+ return std::basic_string<CharType>(tmp.begin(),tmp.end());
+ }
+
+ long do_hash(level_type level,CharType const *b,CharType const *e) const
+ {
+ std::vector<uint8_t> tmp = do_basic_transform(level,b,e);
+ tmp.push_back(0);
+ return gnu_gettext::pj_winberger_hash_function(reinterpret_cast<char *>(&tmp.front()));
+ }
+
+ collate_impl(cdata const &d) :
+ cvt_(d.encoding),
+ locale_(d.locale),
+ is_utf8_(d.utf8)
+ {
+
+ }
+ icu::Collator *get_collator(level_type ilevel) const
+ {
+ int l = limit(ilevel);
+ static const icu::Collator::ECollationStrength levels[level_count] =
+ {
+ icu::Collator::PRIMARY,
+ icu::Collator::SECONDARY,
+ icu::Collator::TERTIARY,
+ icu::Collator::QUATERNARY,
+ icu::Collator::IDENTICAL
+ };
+
+ icu::Collator *col = collates_[l].get();
+ if(col)
+ return col;
+
+ UErrorCode status=U_ZERO_ERROR;
+
+ collates_[l].reset(icu::Collator::createInstance(locale_,status));
+
+ if(U_FAILURE(status))
+ throw std::runtime_error(std::string("Creation of collate failed:") + u_errorName(status));
+
+ collates_[l]->setStrength(levels[l]);
+ return collates_[l].get();
+ }
+
+ private:
+ static const int level_count = 5;
+ icu_std_converter<CharType> cvt_;
+ icu::Locale locale_;
+ mutable boost::thread_specific_ptr<icu::Collator> collates_[level_count];
+ bool is_utf8_;
+ };
+
+
+ #if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 402
+ template<>
+ int collate_impl<char>::do_real_compare(
+ level_type level,
+ char const *b1,char const *e1,
+ char const *b2,char const *e2,
+ UErrorCode &status) const
+ {
+ if(is_utf8_)
+ return do_utf8_compare(level,b1,e1,b2,e2,status);
+ else
+ return do_ustring_compare(level,b1,e1,b2,e2,status);
+ }
+ #endif
+
+ std::locale create_collate(std::locale const &in,cdata const &cd,character_facet_type type)
+ {
+ switch(type) {
+ case char_facet:
+ return std::locale(in,new collate_impl<char>(cd));
+ case wchar_t_facet:
+ return std::locale(in,new collate_impl<wchar_t>(cd));
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ return std::locale(in,new collate_impl<char16_t>(cd));
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ return std::locale(in,new collate_impl<char32_t>(cd));
+ #endif
+ default:
+ return in;
+ }
+ }
+
+ } /// impl_icu
+
+ } // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/conversion.cpp b/src/boost/libs/locale/src/icu/conversion.cpp
new file mode 100644
index 000000000..193d64714
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/conversion.cpp
@@ -0,0 +1,212 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/conversion.hpp>
+#include "all_generator.hpp"
+#include <unicode/normlzr.h>
+#include <unicode/ustring.h>
+#include <unicode/locid.h>
+#include <unicode/uversion.h>
+#if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 308
+#include <unicode/ucasemap.h>
+#define WITH_CASE_MAPS
+#endif
+
+
+#include "cdata.hpp"
+#include "uconv.hpp"
+
+#include <vector>
+
+namespace boost {
+namespace locale {
+namespace impl_icu {
+
+
+ namespace {
+ void normalize_string(icu::UnicodeString &str,int flags)
+ {
+ UErrorCode code=U_ZERO_ERROR;
+ UNormalizationMode mode=UNORM_DEFAULT;
+ switch(flags) {
+ case norm_nfd:
+ mode=UNORM_NFD;
+ break;
+ case norm_nfc:
+ mode=UNORM_NFC;
+ break;
+ case norm_nfkd:
+ mode=UNORM_NFKD;
+ break;
+ case norm_nfkc:
+ mode=UNORM_NFKC;
+ break;
+ }
+ icu::UnicodeString tmp;
+ icu::Normalizer::normalize(str,mode,0,tmp,code);
+
+ check_and_throw_icu_error(code);
+
+ str=tmp;
+ }
+ }
+
+
+ template<typename CharType>
+ class converter_impl : public converter<CharType> {
+ public:
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+
+ converter_impl(cdata const &d) :
+ locale_(d.locale),
+ encoding_(d.encoding)
+ {
+ }
+
+ virtual string_type convert(converter_base::conversion_type how,char_type const *begin,char_type const *end,int flags = 0) const
+ {
+ icu_std_converter<char_type> cvt(encoding_);
+ icu::UnicodeString str=cvt.icu(begin,end);
+ switch(how) {
+ case converter_base::normalization:
+ normalize_string(str,flags);
+ break;
+ case converter_base::upper_case:
+ str.toUpper(locale_);
+ break;
+ case converter_base::lower_case:
+ str.toLower(locale_);
+ break;
+ case converter_base::title_case:
+ str.toTitle(0,locale_);
+ break;
+ case converter_base::case_folding:
+ str.foldCase();
+ break;
+ default:
+ ;
+ }
+ return cvt.std(str);
+ }
+
+ private:
+ icu::Locale locale_;
+ std::string encoding_;
+ }; // converter_impl
+
+ #ifdef WITH_CASE_MAPS
+ class raii_casemap {
+ raii_casemap(raii_casemap const &);
+ void operator = (raii_casemap const&);
+ public:
+ raii_casemap(std::string const &locale_id) :
+ map_(0)
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ map_ = ucasemap_open(locale_id.c_str(),0,&err);
+ check_and_throw_icu_error(err);
+ if(!map_)
+ throw std::runtime_error("Failed to create UCaseMap");
+ }
+ template<typename Conv>
+ std::string convert(Conv func,char const *begin,char const *end) const
+ {
+ std::vector<char> buf((end-begin)*11/10+1);
+ UErrorCode err=U_ZERO_ERROR;
+ int size = func(map_,&buf.front(),buf.size(),begin,end-begin,&err);
+ if(err == U_BUFFER_OVERFLOW_ERROR) {
+ err = U_ZERO_ERROR;
+ buf.resize(size+1);
+ size = func(map_,&buf.front(),buf.size(),begin,end-begin,&err);
+ }
+ check_and_throw_icu_error(err);
+ return std::string(&buf.front(),size);
+ }
+ ~raii_casemap()
+ {
+ ucasemap_close(map_);
+ }
+ private:
+ UCaseMap *map_;
+ };
+
+ class utf8_converter_impl : public converter<char> {
+ public:
+
+ utf8_converter_impl(cdata const &d) :
+ locale_id_(d.locale.getName()),
+ map_(locale_id_)
+ {
+ }
+
+ virtual std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int flags = 0) const
+ {
+
+ if(how == converter_base::normalization) {
+ icu_std_converter<char> cvt("UTF-8");
+ icu::UnicodeString str=cvt.icu(begin,end);
+ normalize_string(str,flags);
+ return cvt.std(str);
+ }
+
+ switch(how)
+ {
+ case converter_base::upper_case:
+ return map_.convert(ucasemap_utf8ToUpper,begin,end);
+ case converter_base::lower_case:
+ return map_.convert(ucasemap_utf8ToLower,begin,end);
+ case converter_base::title_case:
+ {
+ // Non-const method, so need to create a separate map
+ raii_casemap map(locale_id_);
+ return map.convert(ucasemap_utf8ToTitle,begin,end);
+ }
+ case converter_base::case_folding:
+ return map_.convert(ucasemap_utf8FoldCase,begin,end);
+ default:
+ return std::string(begin,end-begin);
+ }
+ }
+ private:
+ std::string locale_id_;
+ raii_casemap map_;
+ }; // converter_impl
+
+#endif // WITH_CASE_MAPS
+
+ std::locale create_convert(std::locale const &in,cdata const &cd,character_facet_type type)
+ {
+ switch(type) {
+ case char_facet:
+ #ifdef WITH_CASE_MAPS
+ if(cd.utf8)
+ return std::locale(in,new utf8_converter_impl(cd));
+ #endif
+ return std::locale(in,new converter_impl<char>(cd));
+ case wchar_t_facet:
+ return std::locale(in,new converter_impl<wchar_t>(cd));
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ return std::locale(in,new converter_impl<char16_t>(cd));
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ return std::locale(in,new converter_impl<char32_t>(cd));
+ #endif
+ default:
+ return in;
+ }
+ }
+
+
+} // impl_icu
+} // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/date_time.cpp b/src/boost/libs/locale/src/icu/date_time.cpp
new file mode 100644
index 000000000..1c872c37e
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/date_time.cpp
@@ -0,0 +1,292 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/date_time_facet.hpp>
+#include <boost/locale/date_time.hpp>
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/hold_ptr.hpp>
+#include "all_generator.hpp"
+
+#include <boost/thread.hpp>
+#include <unicode/calendar.h>
+#include <unicode/gregocal.h>
+#include <unicode/utypes.h>
+
+#include <memory>
+#include <math.h>
+
+#include "cdata.hpp"
+#include "uconv.hpp"
+#include "time_zone.hpp"
+
+#include <iostream>
+
+
+namespace boost {
+namespace locale {
+namespace impl_icu {
+
+ static void check_and_throw_dt(UErrorCode &e)
+ {
+ if(U_FAILURE(e)) {
+ throw date_time_error(u_errorName(e));
+ }
+ }
+ using period::marks::period_mark;
+
+ static UCalendarDateFields to_icu(period::marks::period_mark f)
+ {
+ using namespace period::marks;
+
+ switch(f) {
+ case era: return UCAL_ERA;
+ case year: return UCAL_YEAR;
+ case extended_year: return UCAL_EXTENDED_YEAR;
+ case month: return UCAL_MONTH;
+ case day: return UCAL_DATE;
+ case day_of_year: return UCAL_DAY_OF_YEAR;
+ case day_of_week: return UCAL_DAY_OF_WEEK;
+ case day_of_week_in_month: return UCAL_DAY_OF_WEEK_IN_MONTH;
+ case day_of_week_local: return UCAL_DOW_LOCAL;
+ case hour: return UCAL_HOUR_OF_DAY;
+ case hour_12: return UCAL_HOUR;
+ case am_pm: return UCAL_AM_PM;
+ case minute: return UCAL_MINUTE;
+ case second: return UCAL_SECOND;
+ case week_of_year: return UCAL_WEEK_OF_YEAR;
+ case week_of_month: return UCAL_WEEK_OF_MONTH;
+ default:
+ throw std::invalid_argument("Invalid date_time period type");
+ }
+ }
+
+
+ class calendar_impl : public abstract_calendar {
+ public:
+
+ calendar_impl(cdata const &dat)
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ calendar_.reset(icu::Calendar::createInstance(dat.locale,err));
+ check_and_throw_dt(err);
+ #if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM < 402
+ // workaround old/invalid data, it should be 4 in general
+ calendar_->setMinimalDaysInFirstWeek(4);
+ #endif
+ encoding_ = dat.encoding;
+ }
+ calendar_impl(calendar_impl const &other)
+ {
+ calendar_.reset(other.calendar_->clone());
+ encoding_ = other.encoding_;
+ }
+
+ calendar_impl *clone() const
+ {
+ return new calendar_impl(*this);
+ }
+
+ void set_value(period::marks::period_mark p,int value)
+ {
+ calendar_->set(to_icu(p),int32_t(value));
+ }
+
+ int get_value(period::marks::period_mark p,value_type type) const
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ int v=0;
+ if(p==period::marks::first_day_of_week) {
+ guard l(lock_);
+ v=calendar_->getFirstDayOfWeek(err);
+ }
+ else {
+ UCalendarDateFields uper=to_icu(p);
+ guard l(lock_);
+ switch(type) {
+ case absolute_minimum:
+ v=calendar_->getMinimum(uper);
+ break;
+ case actual_minimum:
+ v=calendar_->getActualMinimum(uper,err);
+ break;
+ case greatest_minimum:
+ v=calendar_->getGreatestMinimum(uper);
+ break;
+ case current:
+ v=calendar_->get(uper,err);
+ break;
+ case least_maximum:
+ v=calendar_->getLeastMaximum(uper);
+ break;
+ case actual_maximum:
+ v=calendar_->getActualMaximum(uper,err);
+ break;
+ case absolute_maximum:
+ v=calendar_->getMaximum(uper);
+ break;
+ }
+ }
+ check_and_throw_dt(err);
+ return v;
+ }
+
+ virtual void set_time(posix_time const &p)
+ {
+ double utime = p.seconds * 1000.0 + p.nanoseconds / 1000000.0;
+ UErrorCode code=U_ZERO_ERROR;
+ calendar_->setTime(utime,code);
+ check_and_throw_dt(code);
+ }
+ virtual void normalize()
+ {
+ // Can't call complete() explicitly (protected)
+ // calling get wich calls complete
+ UErrorCode code=U_ZERO_ERROR;
+ calendar_->get(UCAL_YEAR,code);
+ check_and_throw_dt(code);
+ }
+ virtual posix_time get_time() const
+ {
+
+ UErrorCode code=U_ZERO_ERROR;
+ double rtime = 0;
+ {
+ guard l(lock_);
+ rtime = calendar_->getTime(code);
+ }
+ check_and_throw_dt(code);
+ rtime/=1000.0;
+ double secs = floor(rtime);
+ posix_time res;
+ res.seconds = static_cast<int64_t>(secs);
+ res.nanoseconds = static_cast<uint32_t>((rtime - secs) / 1e9);
+ if(res.nanoseconds > 999999999)
+ res.nanoseconds = 999999999;
+ return res;
+ }
+ virtual void set_option(calendar_option_type opt,int /*v*/)
+ {
+ switch(opt) {
+ case is_gregorian:
+ throw date_time_error("is_gregorian is not settable options for calendar");
+ case is_dst:
+ throw date_time_error("is_dst is not settable options for calendar");
+ default:
+ ;
+ }
+ }
+ virtual int get_option(calendar_option_type opt) const
+ {
+ switch(opt) {
+ case is_gregorian:
+ return dynamic_cast<icu::GregorianCalendar const *>(calendar_.get())!=0;
+ case is_dst:
+ {
+ guard l(lock_);
+ UErrorCode err = U_ZERO_ERROR;
+ bool res = ( calendar_->inDaylightTime(err) != 0 );
+ check_and_throw_dt(err);
+ return res;
+ }
+ default:
+ return 0;
+ }
+ }
+ virtual void adjust_value(period::marks::period_mark p,update_type u,int difference)
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ switch(u) {
+ case move:
+ calendar_->add(to_icu(p),difference,err);
+ break;
+ case roll:
+ calendar_->roll(to_icu(p),difference,err);
+ break;
+ }
+ check_and_throw_dt(err);
+ }
+ virtual int difference(abstract_calendar const *other_ptr,period::marks::period_mark p) const
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ double other_time = 0;
+ //
+ // fieldDifference has side effect of moving calendar (WTF?)
+ // So we clone it for performing this operation
+ //
+ hold_ptr<icu::Calendar> self(calendar_->clone());
+
+ calendar_impl const *other_cal=dynamic_cast<calendar_impl const *>(other_ptr);
+ if(other_cal){
+ guard l(other_cal->lock_);
+ other_time = other_cal->calendar_->getTime(err);
+ check_and_throw_dt(err);
+ }
+ else {
+ posix_time p = other_ptr->get_time();
+ other_time = p.seconds * 1000.0 + p.nanoseconds / 1000000.0;
+ }
+
+ int diff = self->fieldDifference(other_time,to_icu(p),err);
+
+ check_and_throw_dt(err);
+ return diff;
+ }
+ virtual void set_timezone(std::string const &tz)
+ {
+ calendar_->adoptTimeZone(get_time_zone(tz));
+ }
+ virtual std::string get_timezone() const
+ {
+ icu::UnicodeString tz;
+ calendar_->getTimeZone().getID(tz);
+ icu_std_converter<char> cvt(encoding_);
+ return cvt.std(tz);
+ }
+ virtual bool same(abstract_calendar const *other) const
+ {
+ calendar_impl const *oc=dynamic_cast<calendar_impl const *>(other);
+ if(!oc)
+ return false;
+ return calendar_->isEquivalentTo(*oc->calendar_)!=0;
+ }
+
+ private:
+ typedef boost::unique_lock<boost::mutex> guard;
+ mutable boost::mutex lock_;
+ std::string encoding_;
+ hold_ptr<icu::Calendar> calendar_;
+ };
+
+ class icu_calendar_facet : public calendar_facet {
+ public:
+ icu_calendar_facet(cdata const &d,size_t refs = 0) :
+ calendar_facet(refs),
+ data_(d)
+ {
+ }
+ virtual abstract_calendar *create_calendar() const
+ {
+ return new calendar_impl(data_);
+ }
+ private:
+ cdata data_;
+ };
+
+ std::locale create_calendar(std::locale const &in,cdata const &d)
+ {
+ return std::locale(in,new icu_calendar_facet(d));
+ }
+
+} // impl_icu
+} // locale
+} // boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/icu/formatter.cpp b/src/boost/libs/locale/src/icu/formatter.cpp
new file mode 100644
index 000000000..2af18eee9
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/formatter.cpp
@@ -0,0 +1,618 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/formatting.hpp>
+#include "formatter.hpp"
+#include <boost/locale/info.hpp>
+#include "uconv.hpp"
+
+
+#include <unicode/numfmt.h>
+#include <unicode/rbnf.h>
+#include <unicode/datefmt.h>
+#include <unicode/smpdtfmt.h>
+#include <unicode/decimfmt.h>
+
+#include <limits>
+
+#include <iostream>
+
+#include "predefined_formatters.hpp"
+#include "time_zone.hpp"
+
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4244) // lose data
+#endif
+
+
+namespace boost {
+namespace locale {
+ namespace impl_icu {
+
+
+ std::locale::id icu_formatters_cache::id;
+
+ namespace {
+ struct init { init() { std::has_facet<icu_formatters_cache>(std::locale::classic()); } } instance;
+ }
+
+
+ template<typename CharType>
+ class number_format : public formatter<CharType> {
+ public:
+ typedef CharType char_type;
+ typedef std::basic_string<CharType> string_type;
+
+ virtual string_type format(double value,size_t &code_points) const
+ {
+ icu::UnicodeString tmp;
+ icu_fmt_->format(value,tmp);
+ code_points=tmp.countChar32();
+ return cvt_.std(tmp);
+ }
+ virtual string_type format(int64_t value,size_t &code_points) const
+ {
+ icu::UnicodeString tmp;
+ icu_fmt_->format(static_cast< ::int64_t>(value),tmp);
+ code_points=tmp.countChar32();
+ return cvt_.std(tmp);
+ }
+
+ virtual string_type format(int32_t value,size_t &code_points) const
+ {
+ icu::UnicodeString tmp;
+ #ifdef __SUNPRO_CC
+ icu_fmt_->format(static_cast<int>(value),tmp);
+ #else
+ icu_fmt_->format(::int32_t(value),tmp);
+ #endif
+ code_points=tmp.countChar32();
+ return cvt_.std(tmp);
+ }
+
+ virtual size_t parse(string_type const &str,double &value) const
+ {
+ return do_parse(str,value);
+ }
+
+ virtual size_t parse(string_type const &str,int64_t &value) const
+ {
+ return do_parse(str,value);
+ }
+ virtual size_t parse(string_type const &str,int32_t &value) const
+ {
+ return do_parse(str,value);
+ }
+
+ number_format(icu::NumberFormat *fmt,std::string codepage) :
+ cvt_(codepage),
+ icu_fmt_(fmt)
+ {
+ }
+
+ private:
+
+ bool get_value(double &v,icu::Formattable &fmt) const
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ v=fmt.getDouble(err);
+ if(U_FAILURE(err))
+ return false;
+ return true;
+ }
+
+ bool get_value(int64_t &v,icu::Formattable &fmt) const
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ v=fmt.getInt64(err);
+ if(U_FAILURE(err))
+ return false;
+ return true;
+ }
+
+ bool get_value(int32_t &v,icu::Formattable &fmt) const
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ v=fmt.getLong(err);
+ if(U_FAILURE(err))
+ return false;
+ return true;
+ }
+
+ template<typename ValueType>
+ size_t do_parse(string_type const &str,ValueType &v) const
+ {
+ icu::Formattable val;
+ icu::ParsePosition pp;
+ icu::UnicodeString tmp = cvt_.icu(str.data(),str.data()+str.size());
+
+ icu_fmt_->parse(tmp,val,pp);
+
+ ValueType tmp_v;
+
+ if(pp.getIndex() == 0 || !get_value(tmp_v,val))
+ return 0;
+ size_t cut = cvt_.cut(tmp,str.data(),str.data()+str.size(),pp.getIndex());
+ if(cut==0)
+ return 0;
+ v=tmp_v;
+ return cut;
+ }
+
+ icu_std_converter<CharType> cvt_;
+ icu::NumberFormat *icu_fmt_;
+ };
+
+
+ template<typename CharType>
+ class date_format : public formatter<CharType> {
+ public:
+ typedef CharType char_type;
+ typedef std::basic_string<CharType> string_type;
+
+ virtual string_type format(double value,size_t &code_points) const
+ {
+ return do_format(value,code_points);
+ }
+ virtual string_type format(int64_t value,size_t &code_points) const
+ {
+ return do_format(value,code_points);
+ }
+
+ virtual string_type format(int32_t value,size_t &code_points) const
+ {
+ return do_format(value,code_points);
+ }
+
+ virtual size_t parse(string_type const &str,double &value) const
+ {
+ return do_parse(str,value);
+ }
+ virtual size_t parse(string_type const &str,int64_t &value) const
+ {
+ return do_parse(str,value);
+ }
+ virtual size_t parse(string_type const &str,int32_t &value) const
+ {
+ return do_parse(str,value);
+ }
+
+ date_format(icu::DateFormat *fmt,bool transfer_owneship,std::string codepage) :
+ cvt_(codepage)
+ {
+ if(transfer_owneship) {
+ aicu_fmt_.reset(fmt);
+ icu_fmt_ = aicu_fmt_.get();
+ }
+ else {
+ icu_fmt_ = fmt;
+ }
+ }
+
+ private:
+
+ template<typename ValueType>
+ size_t do_parse(string_type const &str,ValueType &value) const
+ {
+ icu::ParsePosition pp;
+ icu::UnicodeString tmp = cvt_.icu(str.data(),str.data() + str.size());
+
+ UDate udate = icu_fmt_->parse(tmp,pp);
+ if(pp.getIndex() == 0)
+ return 0;
+ double date = udate / 1000.0;
+ typedef std::numeric_limits<ValueType> limits_type;
+ if(date > limits_type::max() || date < limits_type::min())
+ return 0;
+ size_t cut = cvt_.cut(tmp,str.data(),str.data()+str.size(),pp.getIndex());
+ if(cut==0)
+ return 0;
+ value=static_cast<ValueType>(date);
+ return cut;
+
+ }
+
+ string_type do_format(double value,size_t &codepoints) const
+ {
+ UDate date = value * 1000.0; /// UDate is time_t in miliseconds
+ icu::UnicodeString tmp;
+ icu_fmt_->format(date,tmp);
+ codepoints=tmp.countChar32();
+ return cvt_.std(tmp);
+ }
+
+ icu_std_converter<CharType> cvt_;
+ hold_ptr<icu::DateFormat> aicu_fmt_;
+ icu::DateFormat *icu_fmt_;
+ };
+
+ icu::UnicodeString strftime_to_icu_full(icu::DateFormat *dfin,char const *alt)
+ {
+ hold_ptr<icu::DateFormat> df(dfin);
+ icu::SimpleDateFormat *sdf=dynamic_cast<icu::SimpleDateFormat *>(df.get());
+ icu::UnicodeString tmp;
+ if(sdf) {
+ sdf->toPattern(tmp);
+ }
+ else {
+ tmp=alt;
+ }
+ return tmp;
+
+ }
+
+ icu::UnicodeString strftime_to_icu_symbol(char c,icu::Locale const &locale,icu_formatters_cache const *cache=0)
+ {
+ switch(c) {
+ case 'a': // Abbr Weekday
+ return "EE";
+ case 'A': // Full Weekday
+ return "EEEE";
+ case 'b': // Abbr Month
+ return "MMM";
+ case 'B': // Full Month
+ return "MMMM";
+ case 'c': // DateTile Full
+ {
+ if(cache)
+ return cache->date_time_format_[1][1];
+ return strftime_to_icu_full(
+ icu::DateFormat::createDateTimeInstance(icu::DateFormat::kFull,icu::DateFormat::kFull,locale),
+ "yyyy-MM-dd HH:mm:ss"
+ );
+ }
+ // not supported by ICU ;(
+ // case 'C': // Century -> 1980 -> 19
+ // retur
+ case 'd': // Day of Month [01,31]
+ return "dd";
+ case 'D': // %m/%d/%y
+ return "MM/dd/yy";
+ case 'e': // Day of Month [1,31]
+ return "d";
+ case 'h': // == b
+ return "MMM";
+ case 'H': // 24 clock hour 00,23
+ return "HH";
+ case 'I': // 12 clock hour 01,12
+ return "hh";
+ case 'j': // day of year 001,366
+ return "D";
+ case 'm': // month as [01,12]
+ return "MM";
+ case 'M': // minute [00,59]
+ return "mm";
+ case 'n': // \n
+ return "\n";
+ case 'p': // am-pm
+ return "a";
+ case 'r': // time with AM/PM %I:%M:%S %p
+ return "hh:mm:ss a";
+ case 'R': // %H:%M
+ return "HH:mm";
+ case 'S': // second [00,61]
+ return "ss";
+ case 't': // \t
+ return "\t";
+ case 'T': // %H:%M:%S
+ return "HH:mm:ss";
+/* case 'u': // weekday 1,7 1=Monday
+ case 'U': // week number of year [00,53] Sunday first
+ case 'V': // week number of year [01,53] Moday first
+ case 'w': // weekday 0,7 0=Sunday
+ case 'W': // week number of year [00,53] Moday first, */
+ case 'x': // Date
+ {
+ if(cache)
+ return cache->date_format_[1];
+ return strftime_to_icu_full(
+ icu::DateFormat::createDateInstance(icu::DateFormat::kMedium,locale),
+ "yyyy-MM-dd"
+ );
+ }
+ case 'X': // Time
+ {
+ if(cache)
+ return cache->time_format_[1];
+ return strftime_to_icu_full(
+ icu::DateFormat::createTimeInstance(icu::DateFormat::kMedium,locale),
+ "HH:mm:ss"
+ );
+ }
+ case 'y': // Year [00-99]
+ return "yy";
+ case 'Y': // Year 1998
+ return "yyyy";
+ case 'Z': // timezone
+ return "vvvv";
+ case '%': // %
+ return "%";
+ default:
+ return "";
+ }
+ }
+
+ icu::UnicodeString strftime_to_icu(icu::UnicodeString const &ftime,icu::Locale const &locale)
+ {
+ unsigned len=ftime.length();
+ icu::UnicodeString result;
+ bool escaped=false;
+ for(unsigned i=0;i<len;i++) {
+ UChar c=ftime[i];
+ if(c=='%') {
+ i++;
+ c=ftime[i];
+ if(c=='E' || c=='O') {
+ i++;
+ c=ftime[i];
+ }
+ if(escaped) {
+ result+="'";
+ escaped=false;
+ }
+ result+=strftime_to_icu_symbol(c,locale);
+ }
+ else if(c=='\'') {
+ result+="''";
+ }
+ else {
+ if(!escaped) {
+ result+="'";
+ escaped=true;
+ }
+ result+=c;
+ }
+ }
+ if(escaped)
+ result+="'";
+ return result;
+ }
+
+ template<typename CharType>
+ formatter<CharType> *generate_formatter(
+ std::ios_base &ios,
+ icu::Locale const &locale,
+ std::string const &encoding)
+ {
+ using namespace boost::locale::flags;
+
+ hold_ptr<formatter<CharType> > fmt;
+ ios_info &info=ios_info::get(ios);
+ uint64_t disp = info.display_flags();
+
+ icu_formatters_cache const &cache = std::use_facet<icu_formatters_cache>(ios.getloc());
+
+
+ if(disp == posix)
+ return fmt.release();
+
+ UErrorCode err=U_ZERO_ERROR;
+
+ switch(disp) {
+ case number:
+ {
+ std::ios_base::fmtflags how = (ios.flags() & std::ios_base::floatfield);
+ icu::NumberFormat *nf = 0;
+
+ if(how == std::ios_base::scientific)
+ nf = cache.number_format(icu_formatters_cache::fmt_sci);
+ else
+ nf = cache.number_format(icu_formatters_cache::fmt_number);
+
+ nf->setMaximumFractionDigits(ios.precision());
+ if(how == std::ios_base::scientific || how == std::ios_base::fixed ) {
+ nf->setMinimumFractionDigits(ios.precision());
+ }
+ else {
+ nf->setMinimumFractionDigits(0);
+ }
+ fmt.reset(new number_format<CharType>(nf,encoding));
+ }
+ break;
+ case currency:
+ {
+ icu::NumberFormat *nf;
+
+ uint64_t curr = info.currency_flags();
+
+ if(curr == currency_default || curr == currency_national)
+ nf = cache.number_format(icu_formatters_cache::fmt_curr_nat);
+ else
+ nf = cache.number_format(icu_formatters_cache::fmt_curr_iso);
+
+ fmt.reset(new number_format<CharType>(nf,encoding));
+ }
+ break;
+ case percent:
+ {
+ icu::NumberFormat *nf = cache.number_format(icu_formatters_cache::fmt_per);
+ nf->setMaximumFractionDigits(ios.precision());
+ std::ios_base::fmtflags how = (ios.flags() & std::ios_base::floatfield);
+ if(how == std::ios_base::scientific || how == std::ios_base::fixed ) {
+ nf->setMinimumFractionDigits(ios.precision());
+ }
+ else {
+ nf->setMinimumFractionDigits(0);
+ }
+ fmt.reset(new number_format<CharType>(nf,encoding));
+
+ }
+ break;
+ case spellout:
+ fmt.reset(new number_format<CharType>(cache.number_format(icu_formatters_cache::fmt_spell),encoding));
+ break;
+ case ordinal:
+ fmt.reset(new number_format<CharType>(cache.number_format(icu_formatters_cache::fmt_ord),encoding));
+ break;
+ case date:
+ case time:
+ case datetime:
+ case strftime:
+ {
+ using namespace flags;
+ hold_ptr<icu::DateFormat> adf;
+ icu::DateFormat *df = 0;
+ icu::SimpleDateFormat *sdf = cache.date_formatter();
+ // try to use cached first
+ if(sdf) {
+ int tmf=info.time_flags();
+ switch(tmf) {
+ case time_short:
+ tmf=0;
+ break;
+ case time_long:
+ tmf=2;
+ break;
+ case time_full:
+ tmf=3;
+ break;
+ case time_default:
+ case time_medium:
+ default:
+ tmf=1;
+ }
+ int dtf=info.date_flags();
+ switch(dtf) {
+ case date_short:
+ dtf=0;
+ break;
+ case date_long:
+ dtf=2;
+ break;
+ case date_full:
+ dtf=3;
+ break;
+ case date_default:
+ case date_medium:
+ default:
+ dtf=1;
+ }
+
+ icu::UnicodeString pattern;
+ switch(disp) {
+ case date:
+ pattern = cache.date_format_[dtf];
+ break;
+ case time:
+ pattern = cache.time_format_[tmf];
+ break;
+ case datetime:
+ pattern = cache.date_time_format_[dtf][tmf];
+ break;
+ case strftime:
+ {
+ if( !cache.date_format_[1].isEmpty()
+ && !cache.time_format_[1].isEmpty()
+ && !cache.date_time_format_[1][1].isEmpty())
+ {
+ icu_std_converter<CharType> cvt_(encoding);
+ std::basic_string<CharType> const &f=info.date_time_pattern<CharType>();
+ pattern = strftime_to_icu(cvt_.icu(f.c_str(),f.c_str()+f.size()),locale);
+ }
+ }
+ break;
+ }
+ if(!pattern.isEmpty()) {
+ sdf->applyPattern(pattern);
+ df = sdf;
+ sdf = 0;
+ }
+ sdf = 0;
+ }
+
+ if(!df) {
+ icu::DateFormat::EStyle dstyle = icu::DateFormat::kDefault;
+ icu::DateFormat::EStyle tstyle = icu::DateFormat::kDefault;
+
+ switch(info.time_flags()) {
+ case time_short: tstyle=icu::DateFormat::kShort; break;
+ case time_medium: tstyle=icu::DateFormat::kMedium; break;
+ case time_long: tstyle=icu::DateFormat::kLong; break;
+ case time_full: tstyle=icu::DateFormat::kFull; break;
+ }
+ switch(info.date_flags()) {
+ case date_short: dstyle=icu::DateFormat::kShort; break;
+ case date_medium: dstyle=icu::DateFormat::kMedium; break;
+ case date_long: dstyle=icu::DateFormat::kLong; break;
+ case date_full: dstyle=icu::DateFormat::kFull; break;
+ }
+
+ if(disp==date)
+ adf.reset(icu::DateFormat::createDateInstance(dstyle,locale));
+ else if(disp==time)
+ adf.reset(icu::DateFormat::createTimeInstance(tstyle,locale));
+ else if(disp==datetime)
+ adf.reset(icu::DateFormat::createDateTimeInstance(dstyle,tstyle,locale));
+ else {// strftime
+ icu_std_converter<CharType> cvt_(encoding);
+ std::basic_string<CharType> const &f=info.date_time_pattern<CharType>();
+ icu::UnicodeString fmt = strftime_to_icu(cvt_.icu(f.data(),f.data()+f.size()),locale);
+ adf.reset(new icu::SimpleDateFormat(fmt,locale,err));
+ }
+ if(U_FAILURE(err))
+ return fmt.release();
+ df = adf.get();
+ }
+
+ df->adoptTimeZone(get_time_zone(info.time_zone()));
+
+ // Depending if we own formatter or not
+ if(adf.get())
+ fmt.reset(new date_format<CharType>(adf.release(),true,encoding));
+ else
+ fmt.reset(new date_format<CharType>(df,false,encoding));
+ }
+ break;
+ }
+
+ return fmt.release();
+ }
+
+
+
+ template<>
+ formatter<char> *formatter<char>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e)
+ {
+ return generate_formatter<char>(ios,l,e);
+ }
+
+ template<>
+ formatter<wchar_t> *formatter<wchar_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e)
+ {
+ return generate_formatter<wchar_t>(ios,l,e);
+ }
+
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ template<>
+ formatter<char16_t> *formatter<char16_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e)
+ {
+ return generate_formatter<char16_t>(ios,l,e);
+ }
+
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ template<>
+ formatter<char32_t> *formatter<char32_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e)
+ {
+ return generate_formatter<char32_t>(ios,l,e);
+ }
+
+ #endif
+
+} // impl_icu
+
+} // locale
+} // boost
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+
+
diff --git a/src/boost/libs/locale/src/icu/formatter.hpp b/src/boost/libs/locale/src/icu/formatter.hpp
new file mode 100644
index 000000000..30414dc56
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/formatter.hpp
@@ -0,0 +1,132 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_FORMATTER_HPP_INCLUDED
+#define BOOST_LOCALE_FORMATTER_HPP_INCLUDED
+
+#include <string>
+#include <memory>
+#include <boost/cstdint.hpp>
+#include <boost/locale/config.hpp>
+#include <unicode/locid.h>
+
+namespace boost {
+namespace locale {
+namespace impl_icu {
+
+ ///
+ /// \brief Special base polymorphic class that is used as a character type independent base for all formatter classes
+ ///
+
+ class base_formatter {
+ public:
+ virtual ~base_formatter()
+ {
+ }
+ };
+
+ ///
+ /// \brief A class that is used for formatting numbers, currency and dates/times
+ ///
+ template<typename CharType>
+ class formatter : public base_formatter {
+ public:
+ typedef CharType char_type;
+ typedef std::basic_string<CharType> string_type;
+
+ ///
+ /// Format the value and return the number of Unicode code points
+ ///
+ virtual string_type format(double value,size_t &code_points) const = 0;
+ ///
+ /// Format the value and return the number of Unicode code points
+ ///
+ virtual string_type format(int64_t value,size_t &code_points) const = 0;
+ ///
+ /// Format the value and return the number of Unicode code points
+ ///
+ virtual string_type format(int32_t value,size_t &code_points) const = 0;
+
+ ///
+ /// Parse the string and return the number of used characters. If it returns 0
+ /// then parsing failed.
+ ///
+ virtual size_t parse(string_type const &str,double &value) const = 0;
+ ///
+ /// Parse the string and return the number of used characters. If it returns 0
+ /// then parsing failed.
+ ///
+ virtual size_t parse(string_type const &str,int64_t &value) const = 0;
+ ///
+ /// Parse the string and return the number of used characters. If it returns 0
+ /// then parsing failed.
+ ///
+ virtual size_t parse(string_type const &str,int32_t &value) const = 0;
+
+ ///
+ /// Get formatter for the current state of ios_base -- flags and locale,
+ /// NULL may be returned if an invalid combination of flags is provided or this type
+ /// of formatting is not supported by locale. See: create
+ ///
+ /// Note: formatter is cached. If \a ios is not changed (no flags or locale changed)
+ /// the formatter would remain the same. Otherwise it would be rebuild and cached
+ /// for future use. It is useful for saving time for generation
+ /// of multiple values with same locale.
+ ///
+ /// For example, this code:
+ ///
+ /// \code
+ /// std::cout << as::spellout;
+ /// for(int i=1;i<=10;i++)
+ /// std::cout << i <<std::endl;
+ /// \endcode
+ ///
+ /// Would create a new spelling formatter only once.
+ ///
+ static formatter *create(std::ios_base &ios,icu::Locale const &l,std::string const &enc);
+
+ virtual ~formatter()
+ {
+ }
+ }; // class formatter
+
+ ///
+ /// Specialization for real implementation
+ ///
+ template<>
+ formatter<char> *formatter<char>::create(std::ios_base &ios,icu::Locale const &l,std::string const &enc);
+
+ ///
+ /// Specialization for real implementation
+ ///
+ template<>
+ formatter<wchar_t> *formatter<wchar_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e);
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ ///
+ /// Specialization for real implementation
+ ///
+ template<>
+ formatter<char16_t> *formatter<char16_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e);
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ ///
+ /// Specialization for real implementation
+ ///
+ template<>
+ formatter<char32_t> *formatter<char32_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e);
+ #endif
+
+} // namespace impl_icu
+} // namespace locale
+} // namespace boost
+
+
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/icu_backend.cpp b/src/boost/libs/locale/src/icu/icu_backend.cpp
new file mode 100644
index 000000000..e3a5d4f58
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/icu_backend.cpp
@@ -0,0 +1,166 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/gnu_gettext.hpp>
+#include <boost/locale/util.hpp>
+#include "all_generator.hpp"
+#include "cdata.hpp"
+#include "icu_backend.hpp"
+#include "../util/locale_data.hpp"
+#include <algorithm>
+#include <iterator>
+
+#include <unicode/ucnv.h>
+
+namespace boost {
+namespace locale {
+namespace impl_icu {
+ class icu_localization_backend : public localization_backend {
+ public:
+ icu_localization_backend() :
+ invalid_(true),
+ use_ansi_encoding_(false)
+ {
+ }
+ icu_localization_backend(icu_localization_backend const &other) :
+ localization_backend(),
+ paths_(other.paths_),
+ domains_(other.domains_),
+ locale_id_(other.locale_id_),
+ invalid_(true),
+ use_ansi_encoding_(other.use_ansi_encoding_)
+ {
+ }
+ virtual icu_localization_backend *clone() const
+ {
+ return new icu_localization_backend(*this);
+ }
+
+ void set_option(std::string const &name,std::string const &value)
+ {
+ invalid_ = true;
+ if(name=="locale")
+ locale_id_ = value;
+ else if(name=="message_path")
+ paths_.push_back(value);
+ else if(name=="message_application")
+ domains_.push_back(value);
+ else if(name=="use_ansi_encoding")
+ use_ansi_encoding_ = value == "true";
+
+ }
+ void clear_options()
+ {
+ invalid_ = true;
+ use_ansi_encoding_ = false;
+ locale_id_.clear();
+ paths_.clear();
+ domains_.clear();
+ }
+
+ void prepare_data()
+ {
+ if(!invalid_)
+ return;
+ invalid_ = false;
+ real_id_ = locale_id_;
+ if(real_id_.empty()) {
+ bool utf8 = ! use_ansi_encoding_;
+ real_id_ = util::get_system_locale(utf8);
+ }
+
+ util::locale_data d;
+ d.parse(real_id_);
+
+ data_.locale = icu::Locale::createCanonical(real_id_.c_str());
+ data_.encoding = d.encoding;
+ data_.utf8 = d.utf8;
+ language_ = d.language;
+ country_ = d.country;
+ variant_ = d.variant;
+ }
+
+ virtual std::locale install(std::locale const &base,
+ locale_category_type category,
+ character_facet_type type = nochar_facet)
+ {
+ prepare_data();
+
+ switch(category) {
+ case convert_facet:
+ return create_convert(base,data_,type);
+ case collation_facet:
+ return create_collate(base,data_,type);
+ case formatting_facet:
+ return create_formatting(base,data_,type);
+ case parsing_facet:
+ return create_parsing(base,data_,type);
+ case codepage_facet:
+ return create_codecvt(base,data_.encoding,type);
+ case message_facet:
+ {
+ gnu_gettext::messages_info minf;
+ minf.language = language_;
+ minf.country = country_;
+ minf.variant = variant_;
+ minf.encoding = data_.encoding;
+ std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
+ minf.paths = paths_;
+ switch(type) {
+ case char_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
+ case wchar_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf));
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf));
+ #endif
+ default:
+ return base;
+ }
+ }
+ case boundary_facet:
+ return create_boundary(base,data_,type);
+ case calendar_facet:
+ return create_calendar(base,data_);
+ case information_facet:
+ return util::create_info(base,real_id_);
+ default:
+ return base;
+ }
+ }
+
+ private:
+
+ std::vector<std::string> paths_;
+ std::vector<std::string> domains_;
+ std::string locale_id_;
+
+ cdata data_;
+ std::string language_;
+ std::string country_;
+ std::string variant_;
+ std::string real_id_;
+ bool invalid_;
+ bool use_ansi_encoding_;
+ };
+
+ localization_backend *create_localization_backend()
+ {
+ return new icu_localization_backend();
+ }
+
+} // impl icu
+} // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/icu_backend.hpp b/src/boost/libs/locale/src/icu/icu_backend.hpp
new file mode 100644
index 000000000..d43cb2db2
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/icu_backend.hpp
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_ICU_LOCALIZATION_BACKEND_HPP
+#define BOOST_LOCALE_IMPL_ICU_LOCALIZATION_BACKEND_HPP
+namespace boost {
+ namespace locale {
+ class localization_backend;
+ namespace impl_icu {
+ localization_backend *create_localization_backend();
+ } // impl_icu
+ } // locale
+} // boost
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/icu/icu_util.hpp b/src/boost/libs/locale/src/icu/icu_util.hpp
new file mode 100644
index 000000000..4330bda6b
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/icu_util.hpp
@@ -0,0 +1,32 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_SRC_ICU_UTIL_HPP
+#define BOOST_SRC_ICU_UTIL_HPP
+#include <unicode/utypes.h>
+#include <stdexcept>
+
+namespace boost {
+namespace locale {
+namespace impl_icu {
+
+ inline void throw_icu_error(UErrorCode err)
+ {
+ throw std::runtime_error(u_errorName(err));
+ }
+
+ inline void check_and_throw_icu_error(UErrorCode err)
+ {
+ if(U_FAILURE(err))
+ throw_icu_error(err);
+ }
+} // impl
+} // locale
+} // boost
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/numeric.cpp b/src/boost/libs/locale/src/icu/numeric.cpp
new file mode 100644
index 000000000..debecfb89
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/numeric.cpp
@@ -0,0 +1,426 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <locale>
+#include <string>
+#include <ios>
+#include <limits>
+#include "formatter.hpp"
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/hold_ptr.hpp>
+#include "all_generator.hpp"
+#include "cdata.hpp"
+#include <algorithm>
+#include "predefined_formatters.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_icu {
+
+namespace details {
+ template<typename V,int n=std::numeric_limits<V>::digits,bool integer=std::numeric_limits<V>::is_integer>
+ struct cast_traits;
+
+ template<typename v>
+ struct cast_traits<v,7,true> {
+ typedef int32_t cast_type;
+ };
+ template<typename v>
+ struct cast_traits<v,8,true> {
+ typedef int32_t cast_type;
+ };
+
+ template<typename v>
+ struct cast_traits<v,15,true> {
+ typedef int32_t cast_type;
+ };
+ template<typename v>
+ struct cast_traits<v,16,true> {
+ typedef int32_t cast_type;
+ };
+ template<typename v>
+ struct cast_traits<v,31,true> {
+ typedef int32_t cast_type;
+ };
+ template<typename v>
+ struct cast_traits<v,32,true> {
+ typedef int64_t cast_type;
+ };
+ template<typename v>
+ struct cast_traits<v,63,true> {
+ typedef int64_t cast_type;
+ };
+ template<typename v>
+ struct cast_traits<v,64,true> {
+ typedef int64_t cast_type;
+ };
+ template<typename V,int u>
+ struct cast_traits<V,u,false> {
+ typedef double cast_type;
+ };
+
+ // ICU does not support uint64_t values so fallback
+ // to POSIX formatting
+ template< typename V,
+ bool Sig=std::numeric_limits<V>::is_signed,
+ bool Int=std::numeric_limits<V>::is_integer,
+ bool Big=(sizeof(V) >= 8)
+ >
+ struct use_parent_traits
+ {
+ static bool use(V /*v*/) { return false; }
+ };
+ template<typename V>
+ struct use_parent_traits<V,false,true,true>
+ {
+ static bool use(V v) { return static_cast<int64_t>(v) < 0; }
+ };
+
+}
+
+
+
+class num_base {
+protected:
+
+ template<typename ValueType>
+ static bool use_parent(std::ios_base &ios,ValueType v)
+ {
+ uint64_t flg = ios_info::get(ios).display_flags();
+ if(flg == flags::posix)
+ return true;
+ if(details::use_parent_traits<ValueType>::use(v))
+ return true;
+
+ if(!std::numeric_limits<ValueType>::is_integer)
+ return false;
+
+ if(flg == flags::number && (ios.flags() & std::ios_base::basefield) != std::ios_base::dec) {
+ return true;
+ }
+ return false;
+ }
+};
+
+
+template<typename CharType>
+class num_format : public std::num_put<CharType>, protected num_base
+{
+public:
+ typedef typename std::num_put<CharType>::iter_type iter_type;
+ typedef std::basic_string<CharType> string_type;
+ typedef CharType char_type;
+ typedef formatter<CharType> formatter_type;
+ typedef hold_ptr<formatter_type> formatter_ptr;
+
+ num_format(cdata const &d,size_t refs = 0) :
+ std::num_put<CharType>(refs),
+ loc_(d.locale),
+ enc_(d.encoding)
+ {
+ }
+protected:
+
+
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, unsigned long val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, double val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long double val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+
+ #ifndef BOOST_NO_LONG_LONG
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long long val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, unsigned long long val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ #endif
+
+
+private:
+
+
+
+ template<typename ValueType>
+ iter_type do_real_put (iter_type out, std::ios_base &ios, char_type fill, ValueType val) const
+ {
+ if(use_parent<ValueType>(ios,val))
+ return std::num_put<char_type>::do_put(out,ios,fill,val);
+
+ formatter_ptr formatter(formatter_type::create(ios,loc_,enc_));
+
+ if(formatter.get() == 0)
+ return std::num_put<char_type>::do_put(out,ios,fill,val);
+
+ size_t code_points;
+ typedef typename details::cast_traits<ValueType>::cast_type cast_type;
+ string_type const &str = formatter->format(static_cast<cast_type>(val),code_points);
+ std::streamsize on_left=0,on_right = 0,points = code_points;
+ if(points < ios.width()) {
+ std::streamsize n = ios.width() - points;
+
+ std::ios_base::fmtflags flags = ios.flags() & std::ios_base::adjustfield;
+
+ //
+ // We do not really know internal point, so we assume that it does not
+ // exist. So according to the standard field should be right aligned
+ //
+ if(flags != std::ios_base::left)
+ on_left = n;
+ on_right = n - on_left;
+ }
+ while(on_left > 0) {
+ *out++ = fill;
+ on_left--;
+ }
+ std::copy(str.begin(),str.end(),out);
+ while(on_right > 0) {
+ *out++ = fill;
+ on_right--;
+ }
+ ios.width(0);
+ return out;
+
+ }
+
+ icu::Locale loc_;
+ std::string enc_;
+
+}; /// num_format
+
+
+template<typename CharType>
+class num_parse : public std::num_get<CharType>, protected num_base
+{
+public:
+ num_parse(cdata const &d,size_t refs = 0) :
+ std::num_get<CharType>(refs),
+ loc_(d.locale),
+ enc_(d.encoding)
+ {
+ }
+protected:
+ typedef typename std::num_get<CharType>::iter_type iter_type;
+ typedef std::basic_string<CharType> string_type;
+ typedef CharType char_type;
+ typedef formatter<CharType> formatter_type;
+ typedef hold_ptr<formatter_type> formatter_ptr;
+ typedef std::basic_istream<CharType> stream_type;
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned short &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned int &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,float &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,double &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long double &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ #ifndef BOOST_NO_LONG_LONG
+ virtual iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long long &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long long &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ #endif
+
+private:
+
+
+ //
+ // This is not really an efficient solution, but it works
+ //
+ template<typename ValueType>
+ iter_type do_real_get(iter_type in,iter_type end,std::ios_base &ios,std::ios_base::iostate &err,ValueType &val) const
+ {
+ stream_type *stream_ptr = dynamic_cast<stream_type *>(&ios);
+ if(!stream_ptr || use_parent<ValueType>(ios,0)) {
+ return std::num_get<CharType>::do_get(in,end,ios,err,val);
+ }
+
+ formatter_ptr formatter(formatter_type::create(ios,loc_,enc_));
+ if(formatter.get()==0) {
+ return std::num_get<CharType>::do_get(in,end,ios,err,val);
+ }
+
+ typedef typename details::cast_traits<ValueType>::cast_type cast_type;
+ string_type tmp;
+ tmp.reserve(64);
+
+ CharType c;
+ while(in!=end && (((c=*in)<=32 && (c>0)) || c==127)) // Assuming that ASCII is a subset
+ ++in;
+
+ while(tmp.size() < 4096 && in!=end && *in!='\n') {
+ tmp += *in++;
+ }
+
+ cast_type value;
+ size_t parsed_chars;
+
+ if((parsed_chars = formatter->parse(tmp,value))==0 || !valid<ValueType>(value)) {
+ err |= std::ios_base::failbit;
+ }
+ else {
+ val=static_cast<ValueType>(value);
+ }
+
+ for(size_t n=tmp.size();n>parsed_chars;n--) {
+ stream_ptr->putback(tmp[n-1]);
+ }
+
+ in = iter_type(*stream_ptr);
+
+ if(in==end)
+ err |=std::ios_base::eofbit;
+ return in;
+ }
+
+ template<typename ValueType,typename CastedType>
+ bool valid(CastedType v) const
+ {
+ typedef std::numeric_limits<ValueType> value_limits;
+ typedef std::numeric_limits<CastedType> casted_limits;
+ if(v < 0 && value_limits::is_signed == false)
+ return false;
+
+ static const CastedType max_val = value_limits::max();
+
+ if(sizeof(CastedType) > sizeof(ValueType) && v > max_val)
+ return false;
+
+ if(value_limits::is_integer == casted_limits::is_integer) {
+ return true;
+ }
+ if(value_limits::is_integer) { // and casted is not
+ if(static_cast<CastedType>(static_cast<ValueType>(v))!=v)
+ return false;
+ }
+ return true;
+ }
+
+ icu::Locale loc_;
+ std::string enc_;
+
+};
+
+
+template<typename CharType>
+std::locale install_formatting_facets(std::locale const &in,cdata const &cd)
+{
+ std::locale tmp=std::locale(in,new num_format<CharType>(cd));
+ if(!std::has_facet<icu_formatters_cache>(in)) {
+ tmp=std::locale(tmp,new icu_formatters_cache(cd.locale));
+ }
+ return tmp;
+}
+
+template<typename CharType>
+std::locale install_parsing_facets(std::locale const &in,cdata const &cd)
+{
+ std::locale tmp=std::locale(in,new num_parse<CharType>(cd));
+ if(!std::has_facet<icu_formatters_cache>(in)) {
+ tmp=std::locale(tmp,new icu_formatters_cache(cd.locale));
+ }
+ return tmp;
+}
+
+std::locale create_formatting(std::locale const &in,cdata const &cd,character_facet_type type)
+{
+ switch(type) {
+ case char_facet:
+ return install_formatting_facets<char>(in,cd);
+ case wchar_t_facet:
+ return install_formatting_facets<wchar_t>(in,cd);
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ return install_formatting_facets<char16_t>(in,cd);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ return install_formatting_facets<char32_t>(in,cd);
+ #endif
+ default:
+ return in;
+ }
+}
+
+std::locale create_parsing(std::locale const &in,cdata const &cd,character_facet_type type)
+{
+ switch(type) {
+ case char_facet:
+ return install_parsing_facets<char>(in,cd);
+ case wchar_t_facet:
+ return install_parsing_facets<wchar_t>(in,cd);
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ return install_parsing_facets<char16_t>(in,cd);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ return install_parsing_facets<char32_t>(in,cd);
+ #endif
+ default:
+ return in;
+ }
+}
+
+
+} // impl_icu
+
+} // locale
+} //boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/predefined_formatters.hpp b/src/boost/libs/locale/src/icu/predefined_formatters.hpp
new file mode 100644
index 000000000..906dfe83e
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/predefined_formatters.hpp
@@ -0,0 +1,187 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_PREDEFINED_FORMATTERS_HPP_INCLUDED
+#define BOOST_LOCALE_PREDEFINED_FORMATTERS_HPP_INCLUDED
+
+#include <string>
+#include <memory>
+#include <boost/cstdint.hpp>
+#include <boost/thread.hpp>
+#include <boost/locale/config.hpp>
+#include <boost/locale/hold_ptr.hpp>
+
+#include <unicode/locid.h>
+#include <unicode/numfmt.h>
+#include <unicode/rbnf.h>
+#include <unicode/datefmt.h>
+#include <unicode/smpdtfmt.h>
+#include <unicode/decimfmt.h>
+
+namespace boost {
+namespace locale {
+ namespace impl_icu {
+
+ class icu_formatters_cache : public std::locale::facet {
+ public:
+
+ static std::locale::id id;
+
+ icu_formatters_cache(icu::Locale const &locale) :
+ locale_(locale)
+ {
+
+ static const icu::DateFormat::EStyle styles[4] = {
+ icu::DateFormat::kShort,
+ icu::DateFormat::kMedium,
+ icu::DateFormat::kLong,
+ icu::DateFormat::kFull
+ };
+
+
+ for(int i=0;i<4;i++) {
+ hold_ptr<icu::DateFormat> fmt(icu::DateFormat::createDateInstance(styles[i],locale));
+ icu::SimpleDateFormat *sfmt = dynamic_cast<icu::SimpleDateFormat*>(fmt.get());
+ if(sfmt) {
+ sfmt->toPattern(date_format_[i]);
+ }
+ }
+
+ for(int i=0;i<4;i++) {
+ hold_ptr<icu::DateFormat> fmt(icu::DateFormat::createTimeInstance(styles[i],locale));
+ icu::SimpleDateFormat *sfmt = dynamic_cast<icu::SimpleDateFormat*>(fmt.get());
+ if(sfmt) {
+ sfmt->toPattern(time_format_[i]);
+ }
+ }
+
+ for(int i=0;i<4;i++) {
+ for(int j=0;j<4;j++) {
+ hold_ptr<icu::DateFormat> fmt(
+ icu::DateFormat::createDateTimeInstance(styles[i],styles[j],locale));
+ icu::SimpleDateFormat *sfmt = dynamic_cast<icu::SimpleDateFormat*>(fmt.get());
+ if(sfmt) {
+ sfmt->toPattern(date_time_format_[i][j]);
+ }
+ }
+ }
+
+
+ }
+
+ typedef enum {
+ fmt_number,
+ fmt_sci,
+ fmt_curr_nat,
+ fmt_curr_iso,
+ fmt_per,
+ fmt_spell,
+ fmt_ord,
+ fmt_count
+ } fmt_type;
+
+ icu::NumberFormat *number_format(fmt_type type) const
+ {
+ icu::NumberFormat *ptr = number_format_[type].get();
+ if(ptr)
+ return ptr;
+ UErrorCode err=U_ZERO_ERROR;
+ hold_ptr<icu::NumberFormat> ap;
+
+ switch(type) {
+ case fmt_number:
+ ap.reset(icu::NumberFormat::createInstance(locale_,err));
+ break;
+ case fmt_sci:
+ ap.reset(icu::NumberFormat::createScientificInstance(locale_,err));
+ break;
+ #if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 402
+ #if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 408
+ case fmt_curr_nat:
+ ap.reset(icu::NumberFormat::createInstance(locale_,UNUM_CURRENCY,err));
+ break;
+ case fmt_curr_iso:
+ ap.reset(icu::NumberFormat::createInstance(locale_,UNUM_CURRENCY_ISO,err));
+ break;
+ #else
+ case fmt_curr_nat:
+ ap.reset(icu::NumberFormat::createInstance(locale_,icu::NumberFormat::kCurrencyStyle,err));
+ break;
+ case fmt_curr_iso:
+ ap.reset(icu::NumberFormat::createInstance(locale_,icu::NumberFormat::kIsoCurrencyStyle,err));
+ break;
+ #endif
+ #else
+ case fmt_curr_nat:
+ case fmt_curr_iso:
+ ap.reset(icu::NumberFormat::createCurrencyInstance(locale_,err));
+ break;
+ #endif
+ case fmt_per:
+ ap.reset(icu::NumberFormat::createPercentInstance(locale_,err));
+ break;
+ case fmt_spell:
+ ap.reset(new icu::RuleBasedNumberFormat(icu::URBNF_SPELLOUT,locale_,err));
+ break;
+ case fmt_ord:
+ ap.reset(new icu::RuleBasedNumberFormat(icu::URBNF_ORDINAL,locale_,err));
+ break;
+ default:
+ throw std::runtime_error("locale::internal error should not get there");
+ }
+
+ test(err);
+ ptr = ap.get();
+ number_format_[type].reset(ap.release());
+ return ptr;
+ }
+
+ void test(UErrorCode err) const
+ {
+ if(U_FAILURE(err))
+ throw std::runtime_error("Failed to create a formatter");
+ }
+
+ icu::UnicodeString date_format_[4];
+ icu::UnicodeString time_format_[4];
+ icu::UnicodeString date_time_format_[4][4];
+
+ icu::SimpleDateFormat *date_formatter() const
+ {
+ icu::SimpleDateFormat *p=date_formatter_.get();
+ if(p)
+ return p;
+
+ hold_ptr<icu::DateFormat> fmt(icu::DateFormat::createDateTimeInstance(
+ icu::DateFormat::kMedium,
+ icu::DateFormat::kMedium,
+ locale_));
+
+ if(dynamic_cast<icu::SimpleDateFormat *>(fmt.get())) {
+ p = static_cast<icu::SimpleDateFormat *>(fmt.release());
+ date_formatter_.reset(p);
+ }
+ return p;
+ }
+
+ private:
+
+ mutable boost::thread_specific_ptr<icu::NumberFormat> number_format_[fmt_count];
+ mutable boost::thread_specific_ptr<icu::SimpleDateFormat> date_formatter_;
+ icu::Locale locale_;
+ };
+
+
+
+ } // namespace impl_icu
+} // namespace locale
+} // namespace boost
+
+
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/time_zone.cpp b/src/boost/libs/locale/src/icu/time_zone.cpp
new file mode 100644
index 000000000..8276231f9
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/time_zone.cpp
@@ -0,0 +1,239 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include "time_zone.hpp"
+
+//
+// Bug - when ICU tries to find a file that is equivalent to /etc/localtime it finds /usr/share/zoneinfo/localtime
+// that is just a symbolic link to /etc/localtime.
+//
+// It started in 4.0 and was fixed in version 4.6, also the fix was backported to the 4.4 branch so it should be
+// available from 4.4.3... So we test if the workaround is required
+//
+// It is also relevant only for Linux, BSD and Apple (as I see in ICU code)
+//
+
+#if U_ICU_VERSION_MAJOR_NUM == 4 && (U_ICU_VERSION_MINOR_NUM * 100 + U_ICU_VERSION_PATCHLEVEL_NUM) <= 402
+# if defined(__linux) || defined(__FreeBSD__) || defined(__APPLE__)
+# define BOOST_LOCALE_WORKAROUND_ICU_BUG
+# endif
+#endif
+
+#ifdef BOOST_LOCALE_WORKAROUND_ICU_BUG
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fstream>
+#include <pthread.h>
+#include <string.h>
+#include <memory>
+#endif
+
+#include <boost/locale/hold_ptr.hpp>
+
+namespace boost {
+ namespace locale {
+ namespace impl_icu {
+
+ #ifndef BOOST_LOCALE_WORKAROUND_ICU_BUG
+
+ // This is normal behavior
+
+ icu::TimeZone *get_time_zone(std::string const &time_zone)
+ {
+
+ if(time_zone.empty()) {
+ return icu::TimeZone::createDefault();
+ }
+ else {
+ return icu::TimeZone::createTimeZone(time_zone.c_str());
+ }
+ }
+
+ #else
+
+ //
+ // This is a workaround for an ICU timezone detection bug.
+ // It is \b very ICU specific and should not be used
+ // in general. It is also designed to work only on
+ // specific patforms: Linux, BSD and Apple, where this bug may actually
+ // occur
+ //
+ namespace {
+
+ // Under BSD, Linux and Mac OS X dirent has normal size
+ // so no issues with readdir_r
+
+ class directory {
+ public:
+ directory(char const *name) : d(0),read_result(0)
+ {
+ d=opendir(name);
+ if(!d)
+ return;
+ }
+ ~directory()
+ {
+ if(d)
+ closedir(d);
+ }
+ bool is_open()
+ {
+ return d;
+ }
+ char const *next()
+ {
+ if(d && readdir_r(d,&de,&read_result)==0 && read_result!=0)
+ return de.d_name;
+ return 0;
+ }
+ private:
+ DIR *d;
+ struct dirent de;
+ struct dirent *read_result;
+ };
+
+ bool files_equal(std::string const &left,std::string const &right)
+ {
+ char l[256],r[256];
+ std::ifstream ls(left.c_str());
+ if(!ls)
+ return false;
+ std::ifstream rs(right.c_str());
+ if(!rs)
+ return false;
+ do {
+ ls.read(l,sizeof(l));
+ rs.read(r,sizeof(r));
+ size_t n;
+ if((n=ls.gcount())!=size_t(rs.gcount()))
+ return false;
+ if(memcmp(l,r,n)!=0)
+ return false;
+ }while(!ls.eof() || !rs.eof());
+ if(bool(ls.eof())!=bool(rs.eof()))
+ return false;
+ return true;
+ }
+
+ std::string find_file_in(std::string const &ref,size_t size,std::string const &dir)
+ {
+ directory d(dir.c_str());
+ if(!d.is_open())
+ return std::string();
+
+ char const *name=0;
+ while((name=d.next())!=0) {
+ std::string file_name = name;
+ if( file_name == "."
+ || file_name ==".."
+ || file_name=="posixrules"
+ || file_name=="localtime")
+ {
+ continue;
+ }
+ struct stat st;
+ std::string path = dir+"/"+file_name;
+ if(stat(path.c_str(),&st)==0) {
+ if(S_ISDIR(st.st_mode)) {
+ std::string res = find_file_in(ref,size,path);
+ if(!res.empty())
+ return file_name + "/" + res;
+ }
+ else {
+ if(size_t(st.st_size) == size && files_equal(path,ref)) {
+ return file_name;
+ }
+ }
+ }
+ }
+ return std::string();
+ }
+
+ // This actually emulates ICU's search
+ // algorithm... just it ignores localtime
+ std::string detect_correct_time_zone()
+ {
+
+ char const *tz_dir = "/usr/share/zoneinfo";
+ char const *tz_file = "/etc/localtime";
+
+ struct stat st;
+ if(::stat(tz_file,&st)!=0)
+ return std::string();
+ size_t size = st.st_size;
+ std::string r = find_file_in(tz_file,size,tz_dir);
+ if(r.empty())
+ return r;
+ if(r.compare(0,6,"posix/")==0 || r.compare(0,6,"right/",6)==0)
+ return r.substr(6);
+ return r;
+ }
+
+
+ //
+ // Using pthread as:
+ // - This bug is relevant for only Linux, BSD, Mac OS X and
+ // pthreads are native threading API
+ // - The dependency on boost.thread may be removed when using
+ // more recent ICU versions (so TLS would not be needed)
+ //
+ // This the dependency on Boost.Thread is eliminated
+ //
+
+ pthread_once_t init_tz = PTHREAD_ONCE_INIT;
+ std::string default_time_zone_name;
+
+ extern "C" {
+ static void init_tz_proc()
+ {
+ try {
+ default_time_zone_name = detect_correct_time_zone();
+ }
+ catch(...){}
+ }
+ }
+
+ std::string get_time_zone_name()
+ {
+ pthread_once(&init_tz,init_tz_proc);
+ return default_time_zone_name;
+ }
+
+
+ } // namespace
+
+ icu::TimeZone *get_time_zone(std::string const &time_zone)
+ {
+
+ if(!time_zone.empty()) {
+ return icu::TimeZone::createTimeZone(time_zone.c_str());
+ }
+ hold_ptr<icu::TimeZone> tz(icu::TimeZone::createDefault());
+ icu::UnicodeString id;
+ tz->getID(id);
+ // Check if there is a bug?
+ if(id != icu::UnicodeString("localtime"))
+ return tz.release();
+ // Now let's deal with the bug and run the fixed
+ // search loop as that of ICU
+ std::string real_id = get_time_zone_name();
+ if(real_id.empty()) {
+ // if we failed fallback to ICU's time zone
+ return tz.release();
+ }
+ return icu::TimeZone::createTimeZone(real_id.c_str());
+ }
+ #endif // bug workaround
+
+ }
+ }
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/time_zone.hpp b/src/boost/libs/locale/src/icu/time_zone.hpp
new file mode 100644
index 000000000..3fbeb83f4
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/time_zone.hpp
@@ -0,0 +1,26 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_ICU_GET_TIME_ZONE_HPP
+#define BOOST_LOCALE_IMPL_ICU_GET_TIME_ZONE_HPP
+
+#include <unicode/calendar.h>
+#include <string>
+
+namespace boost {
+ namespace locale {
+ namespace impl_icu {
+
+ // Provides a workaround for an ICU default timezone bug and also
+ // handles time_zone string correctly - if empty returns default
+ // otherwise returns the instance created with time_zone
+ icu::TimeZone *get_time_zone(std::string const &time_zone);
+ }
+ }
+}
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/icu/uconv.hpp b/src/boost/libs/locale/src/icu/uconv.hpp
new file mode 100644
index 000000000..f9eb2d1bd
--- /dev/null
+++ b/src/boost/libs/locale/src/icu/uconv.hpp
@@ -0,0 +1,316 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_SRC_LOCALE_ICU_UCONV_HPP
+#define BOOST_SRC_LOCALE_ICU_UCONV_HPP
+#include <unicode/unistr.h>
+#include <unicode/ucnv.h>
+#include <unicode/ustring.h>
+#include <unicode/utf.h>
+#include <unicode/utf16.h>
+
+#include <boost/locale/encoding.hpp>
+
+#include <string>
+#include <memory>
+#include "icu_util.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_icu {
+
+ typedef enum {
+ cvt_skip,
+ cvt_stop
+ } cpcvt_type;
+
+
+ template<typename CharType,int char_size = sizeof(CharType) >
+ class icu_std_converter {
+ public:
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+
+ icu_std_converter(std::string charset,cpcvt_type cv=cvt_skip);
+ icu::UnicodeString icu(char_type const *begin,char_type const *end) const;
+ string_type std(icu::UnicodeString const &str) const;
+ size_t cut(icu::UnicodeString const &str,char_type const *begin,char_type const *end,size_t n,size_t from_u=0,size_t from_c=0) const;
+ };
+
+ template<typename CharType>
+ class icu_std_converter<CharType,1> {
+ public:
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+
+
+ icu::UnicodeString icu_checked(char_type const *vb,char_type const *ve) const
+ {
+ return icu(vb,ve); // Already done
+ }
+ icu::UnicodeString icu(char_type const *vb,char_type const *ve) const
+ {
+ char const *begin=reinterpret_cast<char const *>(vb);
+ char const *end=reinterpret_cast<char const *>(ve);
+ uconv cvt(charset_,cvt_type_);
+ UErrorCode err=U_ZERO_ERROR;
+ icu::UnicodeString tmp(begin,end-begin,cvt.cvt(),err);
+ check_and_throw_icu_error(err);
+ return tmp;
+ }
+
+ string_type std(icu::UnicodeString const &str) const
+ {
+ uconv cvt(charset_,cvt_type_);
+ return cvt.go(str.getBuffer(),str.length(),max_len_);
+ }
+
+ icu_std_converter(std::string charset,cpcvt_type cvt_type = cvt_skip) :
+ charset_(charset),
+ cvt_type_(cvt_type)
+ {
+ uconv cvt(charset_,cvt_type);
+ max_len_=cvt.max_char_size();
+ }
+
+ size_t cut(icu::UnicodeString const &str,char_type const *begin,char_type const *end,
+ size_t n,size_t from_u=0,size_t from_char=0) const
+ {
+ size_t code_points = str.countChar32(from_u,n);
+ uconv cvt(charset_,cvt_type_);
+ return cvt.cut(code_points,begin+from_char,end);
+ }
+
+ struct uconv {
+ uconv(uconv const &other);
+ void operator=(uconv const &other);
+ public:
+ uconv(std::string const &charset,cpcvt_type cvt_type=cvt_skip)
+ {
+ UErrorCode err=U_ZERO_ERROR;
+ cvt_ = ucnv_open(charset.c_str(),&err);
+ if(!cvt_ || U_FAILURE(err)) {
+ if(cvt_)
+ ucnv_close(cvt_);
+ throw conv::invalid_charset_error(charset);
+ }
+
+ try {
+ if(cvt_type==cvt_skip) {
+ ucnv_setFromUCallBack(cvt_,UCNV_FROM_U_CALLBACK_SKIP,0,0,0,&err);
+ check_and_throw_icu_error(err);
+
+ err=U_ZERO_ERROR;
+ ucnv_setToUCallBack(cvt_,UCNV_TO_U_CALLBACK_SKIP,0,0,0,&err);
+ check_and_throw_icu_error(err);
+ }
+ else {
+ ucnv_setFromUCallBack(cvt_,UCNV_FROM_U_CALLBACK_STOP,0,0,0,&err);
+ check_and_throw_icu_error(err);
+
+ err=U_ZERO_ERROR;
+ ucnv_setToUCallBack(cvt_,UCNV_TO_U_CALLBACK_STOP,0,0,0,&err);
+ check_and_throw_icu_error(err);
+ }
+ }
+ catch(...) { ucnv_close(cvt_) ; throw; }
+ }
+
+ int max_char_size()
+ {
+ return ucnv_getMaxCharSize(cvt_);
+ }
+
+ string_type go(UChar const *buf,int length,int max_size)
+ {
+ string_type res;
+ res.resize(UCNV_GET_MAX_BYTES_FOR_STRING(length,max_size));
+ char *ptr=reinterpret_cast<char *>(&res[0]);
+ UErrorCode err=U_ZERO_ERROR;
+ int n = ucnv_fromUChars(cvt_,ptr,res.size(),buf,length,&err);
+ check_and_throw_icu_error(err);
+ res.resize(n);
+ return res;
+ }
+
+ size_t cut(size_t n,char_type const *begin,char_type const *end)
+ {
+ char_type const *saved = begin;
+ while(n > 0 && begin < end) {
+ UErrorCode err=U_ZERO_ERROR;
+ ucnv_getNextUChar(cvt_,&begin,end,&err);
+ if(U_FAILURE(err))
+ return 0;
+ n--;
+ }
+ return begin - saved;
+ }
+
+ UConverter *cvt() { return cvt_; }
+
+ ~uconv()
+ {
+ ucnv_close(cvt_);
+ }
+
+ private:
+ UConverter *cvt_;
+ };
+
+ private:
+ int max_len_;
+ std::string charset_;
+ cpcvt_type cvt_type_;
+ };
+
+ template<typename CharType>
+ class icu_std_converter<CharType,2> {
+ public:
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+
+
+ icu::UnicodeString icu_checked(char_type const *begin,char_type const *end) const
+ {
+ icu::UnicodeString tmp(end-begin,0,0); // make inital capacity
+ while(begin!=end) {
+ UChar cl = *begin++;
+ if(U16_IS_SINGLE(cl))
+ tmp.append(static_cast<UChar32>(cl));
+ else if(U16_IS_LEAD(cl)) {
+ if(begin==end) {
+ throw_if_needed();
+ }
+ else {
+ UChar ct=*begin++;
+ if(!U16_IS_TRAIL(ct))
+ throw_if_needed();
+ else {
+ UChar32 c=U16_GET_SUPPLEMENTARY(cl,ct);
+ tmp.append(c);
+ }
+ }
+ }
+ else
+ throw_if_needed();
+ }
+ return tmp;
+ }
+ void throw_if_needed() const
+ {
+ if(mode_ == cvt_stop)
+ throw conv::conversion_error();
+ }
+ icu::UnicodeString icu(char_type const *vb,char_type const *ve) const
+ {
+ UChar const *begin=reinterpret_cast<UChar const *>(vb);
+ UChar const *end=reinterpret_cast<UChar const *>(ve);
+ icu::UnicodeString tmp(begin,end-begin);
+ return tmp;
+
+ }
+
+ string_type std(icu::UnicodeString const &str) const
+ {
+ char_type const *ptr=reinterpret_cast<char_type const *>(str.getBuffer());
+ return string_type(ptr,str.length());
+ }
+ size_t cut(icu::UnicodeString const &/*str*/,char_type const * /*begin*/,char_type const * /*end*/,size_t n,
+ size_t /*from_u*/=0,size_t /*from_c*/=0) const
+ {
+ return n;
+ }
+
+ icu_std_converter(std::string /*charset*/,cpcvt_type mode=cvt_skip) :
+ mode_(mode)
+ {
+ }
+ private:
+ cpcvt_type mode_;
+
+ };
+
+ template<typename CharType>
+ class icu_std_converter<CharType,4> {
+ public:
+
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+
+ icu::UnicodeString icu_checked(char_type const *begin,char_type const *end) const
+ {
+ icu::UnicodeString tmp(end-begin,0,0); // make inital capacity
+ while(begin!=end) {
+ UChar32 c = static_cast<UChar32>(*begin++);
+ if(U_IS_UNICODE_CHAR(c))
+ tmp.append(c);
+ else
+ throw_if_needed();
+ }
+ return tmp;
+ }
+ void throw_if_needed() const
+ {
+ if(mode_ == cvt_stop)
+ throw conv::conversion_error();
+ }
+
+ icu::UnicodeString icu(char_type const *begin,char_type const *end) const
+ {
+ icu::UnicodeString tmp(end-begin,0,0); // make inital capacity
+ while(begin!=end) {
+ UChar32 c=static_cast<UChar32>(*begin++);
+ tmp.append(c);
+ }
+ return tmp;
+
+ }
+
+ string_type std(icu::UnicodeString const &str) const
+ {
+ string_type tmp;
+ tmp.resize(str.length());
+ UChar32 *ptr=reinterpret_cast<UChar32 *>(&tmp[0]);
+
+ #ifdef __SUNPRO_CC
+ int len=0;
+ #else
+ ::int32_t len=0;
+ #endif
+
+ UErrorCode code=U_ZERO_ERROR;
+ u_strToUTF32(ptr,tmp.size(),&len,str.getBuffer(),str.length(),&code);
+
+ check_and_throw_icu_error(code);
+
+ tmp.resize(len);
+
+ return tmp;
+ }
+
+ size_t cut(icu::UnicodeString const &str,char_type const * /*begin*/,char_type const * /*end*/,size_t n,
+ size_t from_u=0,size_t /*from_c*/=0) const
+ {
+ return str.countChar32(from_u,n);
+ }
+
+ icu_std_converter(std::string /*charset*/,cpcvt_type mode=cvt_skip) :
+ mode_(mode)
+ {
+ }
+ private:
+ cpcvt_type mode_;
+
+ };
+} /// impl_icu
+} // locale
+} // boost
+
+#endif
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/posix/all_generator.hpp b/src/boost/libs/locale/src/posix/all_generator.hpp
new file mode 100644
index 000000000..8a80e79d0
--- /dev/null
+++ b/src/boost/libs/locale/src/posix/all_generator.hpp
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_POSIX_ALL_GENERATOR_HPP
+#define BOOST_LOCALE_IMPL_POSIX_ALL_GENERATOR_HPP
+
+#include <boost/locale/generator.hpp>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <locale.h>
+
+#ifdef __APPLE__
+#include <xlocale.h>
+#endif
+
+namespace boost {
+ namespace locale {
+ namespace impl_posix {
+
+ std::locale create_convert( std::locale const &in,
+ boost::shared_ptr<locale_t> lc,
+ character_facet_type type);
+
+ std::locale create_collate( std::locale const &in,
+ boost::shared_ptr<locale_t> lc,
+ character_facet_type type);
+
+ std::locale create_formatting( std::locale const &in,
+ boost::shared_ptr<locale_t> lc,
+ character_facet_type type);
+
+ std::locale create_parsing( std::locale const &in,
+ boost::shared_ptr<locale_t> lc,
+ character_facet_type type);
+ std::locale create_codecvt( std::locale const &in,
+ std::string const &encoding,
+ character_facet_type type);
+
+ }
+ }
+}
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/posix/codecvt.cpp b/src/boost/libs/locale/src/posix/codecvt.cpp
new file mode 100644
index 000000000..897888a9c
--- /dev/null
+++ b/src/boost/libs/locale/src/posix/codecvt.cpp
@@ -0,0 +1,252 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/encoding.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/locale/hold_ptr.hpp>
+#include "../encoding/conv.hpp"
+#include <boost/locale/util.hpp>
+#include "all_generator.hpp"
+
+#include <errno.h>
+#include <algorithm>
+#include <stdexcept>
+#include <vector>
+#include "codecvt.hpp"
+
+#ifdef BOOST_LOCALE_WITH_ICONV
+#include "../util/iconv.hpp"
+#endif
+
+namespace boost {
+namespace locale {
+namespace impl_posix {
+
+#ifdef BOOST_LOCALE_WITH_ICONV
+ class mb2_iconv_converter : public util::base_converter {
+ public:
+
+ mb2_iconv_converter(std::string const &encoding) :
+ encoding_(encoding),
+ to_utf_((iconv_t)(-1)),
+ from_utf_((iconv_t)(-1))
+ {
+ iconv_t d = (iconv_t)(-1);
+ std::vector<uint32_t> first_byte_table;
+ try {
+ d = iconv_open(utf32_encoding(),encoding.c_str());
+ if(d == (iconv_t)(-1)) {
+ throw std::runtime_error("Unsupported encoding" + encoding);
+ }
+ for(unsigned c=0;c<256;c++) {
+ char ibuf[2] = { char(c) , 0 };
+ char *in = ibuf;
+ size_t insize =2;
+ uint32_t obuf[2] = {illegal,illegal};
+ char *out = reinterpret_cast<char *>(obuf);
+ size_t outsize = 8;
+ // Basic sigle codepoint conversion
+ call_iconv(d,&in,&insize,&out,&outsize);
+ if(insize == 0 && outsize == 0 && obuf[1] == 0) {
+ first_byte_table.push_back(obuf[0]);
+ continue;
+ }
+
+ // Test if this is illegal first byte or incomplete
+ in = ibuf;
+ insize = 1;
+ out = reinterpret_cast<char *>(obuf);
+ outsize = 8;
+ call_iconv(d,0,0,0,0);
+ size_t res = call_iconv(d,&in,&insize,&out,&outsize);
+
+ // Now if this single byte starts a sequence we add incomplete
+ // to know to ask that we need two bytes, othewise it may only be
+ // illegal
+
+ uint32_t point;
+ if(res == (size_t)(-1) && errno == EINVAL)
+ point = incomplete;
+ else
+ point = illegal;
+ first_byte_table.push_back(point);
+
+ }
+ }
+ catch(...) {
+ if(d!=(iconv_t)(-1))
+ iconv_close(d);
+ throw;
+ }
+ iconv_close(d);
+ first_byte_table_.reset(new std::vector<uint32_t>());
+ first_byte_table_->swap(first_byte_table);
+ }
+
+ mb2_iconv_converter(mb2_iconv_converter const &other) :
+ first_byte_table_(other.first_byte_table_),
+ encoding_(other.encoding_),
+ to_utf_((iconv_t)(-1)),
+ from_utf_((iconv_t)(-1))
+ {
+ }
+
+ virtual ~mb2_iconv_converter()
+ {
+ if(to_utf_ != (iconv_t)(-1))
+ iconv_close(to_utf_);
+ if(from_utf_ != (iconv_t)(-1))
+ iconv_close(from_utf_);
+
+ }
+
+ virtual bool is_thread_safe() const
+ {
+ return false;
+ }
+
+ virtual mb2_iconv_converter *clone() const
+ {
+ return new mb2_iconv_converter(*this);
+ }
+
+ uint32_t to_unicode(char const *&begin,char const *end)
+ {
+ if(begin == end)
+ return incomplete;
+
+ unsigned char seq0 = *begin;
+ uint32_t index = (*first_byte_table_)[seq0];
+ if(index == illegal)
+ return illegal;
+ if(index != incomplete) {
+ begin++;
+ return index;
+ }
+ else if(begin+1 == end)
+ return incomplete;
+
+ open(to_utf_,utf32_encoding(),encoding_.c_str());
+
+ // maybe illegal or may be double byte
+
+ char inseq[3] = { static_cast<char>(seq0) , begin[1], 0};
+ char *inbuf = inseq;
+ size_t insize = 3;
+ uint32_t result[2] = { illegal, illegal };
+ size_t outsize = 8;
+ char *outbuf = reinterpret_cast<char*>(result);
+ call_iconv(to_utf_,&inbuf,&insize,&outbuf,&outsize);
+ if(outsize == 0 && insize == 0 && result[1]==0 ) {
+ begin+=2;
+ return result[0];
+ }
+ return illegal;
+ }
+
+ uint32_t from_unicode(uint32_t cp,char *begin,char const *end)
+ {
+ if(cp == 0) {
+ if(begin!=end) {
+ *begin = 0;
+ return 1;
+ }
+ else {
+ return incomplete;
+ }
+ }
+
+ open(from_utf_,encoding_.c_str(),utf32_encoding());
+
+ uint32_t codepoints[2] = {cp,0};
+ char *inbuf = reinterpret_cast<char *>(codepoints);
+ size_t insize = sizeof(codepoints);
+ char outseq[3] = {0};
+ char *outbuf = outseq;
+ size_t outsize = 3;
+
+ call_iconv(from_utf_,&inbuf,&insize,&outbuf,&outsize);
+
+ if(insize != 0 || outsize > 1)
+ return illegal;
+ size_t len = 2 - outsize ;
+ size_t reminder = end - begin;
+ if(reminder < len)
+ return incomplete;
+ for(unsigned i=0;i<len;i++)
+ *begin++ = outseq[i];
+ return len;
+ }
+
+ void open(iconv_t &d,char const *to,char const *from)
+ {
+ if(d!=(iconv_t)(-1))
+ return;
+ d=iconv_open(to,from);
+ }
+
+ static char const *utf32_encoding()
+ {
+ union { char one; uint32_t value; } test;
+ test.value = 1;
+ if(test.one == 1)
+ return "UTF-32LE";
+ else
+ return "UTF-32BE";
+ }
+
+ virtual int max_len() const
+ {
+ return 2;
+ }
+
+ private:
+ boost::shared_ptr<std::vector<uint32_t> > first_byte_table_;
+ std::string encoding_;
+ iconv_t to_utf_;
+ iconv_t from_utf_;
+ };
+
+ util::base_converter *create_iconv_converter(std::string const &encoding)
+ {
+ hold_ptr<util::base_converter> cvt;
+ try {
+ cvt.reset(new mb2_iconv_converter(encoding));
+ }
+ catch(std::exception const &e) {
+ // Nothing to do, just retrun empty cvt
+ }
+ return cvt.release();
+ }
+
+#else // no iconv
+ util::base_converter *create_iconv_converter(std::string const &/*encoding*/)
+ {
+ return 0;
+ }
+#endif
+
+ std::locale create_codecvt(std::locale const &in,std::string const &encoding,character_facet_type type)
+ {
+ if(conv::impl::normalize_encoding(encoding.c_str())=="utf8")
+ return util::create_utf8_codecvt(in,type);
+
+ try {
+ return util::create_simple_codecvt(in,encoding,type);
+ }
+ catch(conv::invalid_charset_error const &) {
+ util::base_converter *cvt = create_iconv_converter(encoding);
+ return util::create_codecvt_from_pointer(in,cvt,type);
+ }
+ }
+
+} // impl_posix
+} // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/posix/codecvt.hpp b/src/boost/libs/locale/src/posix/codecvt.hpp
new file mode 100644
index 000000000..976c07e32
--- /dev/null
+++ b/src/boost/libs/locale/src/posix/codecvt.hpp
@@ -0,0 +1,28 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_POSIX_CODECVT_HPP
+#define BOOST_LOCALE_IMPL_POSIX_CODECVT_HPP
+#include <boost/locale/config.hpp>
+#include <boost/locale/util.hpp>
+
+#include <memory>
+#include <string>
+
+namespace boost {
+namespace locale {
+namespace impl_posix {
+ BOOST_LOCALE_DECL
+ util::base_converter *create_iconv_converter(std::string const &encoding);
+
+} // impl_posix
+} // locale
+} // boost
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/posix/collate.cpp b/src/boost/libs/locale/src/posix/collate.cpp
new file mode 100644
index 000000000..859bb9cf6
--- /dev/null
+++ b/src/boost/libs/locale/src/posix/collate.cpp
@@ -0,0 +1,124 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#if defined(__FreeBSD__)
+#include <xlocale.h>
+#endif
+#include <locale>
+#include <locale.h>
+#include <string.h>
+#include <wchar.h>
+#include <string>
+#include <stdexcept>
+#include <ios>
+#include <vector>
+#include <boost/locale/generator.hpp>
+#include "../shared/mo_hash.hpp"
+
+#include "all_generator.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_posix {
+
+template<typename CharType>
+struct coll_traits;
+
+template<>
+struct coll_traits<char> {
+ static size_t xfrm(char *out,char const *in,size_t n,locale_t l)
+ {
+ return strxfrm_l(out,in,n,l);
+ }
+ static size_t coll(char const *left,char const *right,locale_t l)
+ {
+ return strcoll_l(left,right,l);
+ }
+};
+
+template<>
+struct coll_traits<wchar_t> {
+ static size_t xfrm(wchar_t *out,wchar_t const *in,size_t n,locale_t l)
+ {
+ return wcsxfrm_l(out,in,n,l);
+ }
+ static size_t coll(wchar_t const *left,wchar_t const *right,locale_t l)
+ {
+ return wcscoll_l(left,right,l);
+ }
+};
+
+template<typename CharType>
+class collator : public std::collate<CharType> {
+public:
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+ collator(boost::shared_ptr<locale_t> l,size_t refs = 0) :
+ std::collate<CharType>(refs),
+ lc_(l)
+ {
+ }
+ virtual ~collator()
+ {
+ }
+ virtual int do_compare(char_type const *lb,char_type const *le,char_type const *rb,char_type const *re) const
+ {
+ string_type left(lb,le-lb);
+ string_type right(rb,re-rb);
+ int res = coll_traits<char_type>::coll(left.c_str(),right.c_str(),*lc_);
+ if(res < 0)
+ return -1;
+ if(res > 0)
+ return 1;
+ return 0;
+ }
+ virtual long do_hash(char_type const *b,char_type const *e) const
+ {
+ string_type s(do_transform(b,e));
+ char const *begin = reinterpret_cast<char const *>(s.c_str());
+ char const *end = begin + s.size() * sizeof(char_type);
+ return gnu_gettext::pj_winberger_hash_function(begin,end);
+ }
+ virtual string_type do_transform(char_type const *b,char_type const *e) const
+ {
+ string_type s(b,e-b);
+ std::vector<char_type> buf((e-b)*2+1);
+ size_t n = coll_traits<char_type>::xfrm(&buf.front(),s.c_str(),buf.size(),*lc_);
+ if(n>buf.size()) {
+ buf.resize(n);
+ coll_traits<char_type>::xfrm(&buf.front(),s.c_str(),n,*lc_);
+ }
+ return string_type(&buf.front(),n);
+ }
+private:
+ boost::shared_ptr<locale_t> lc_;
+};
+
+
+std::locale create_collate( std::locale const &in,
+ boost::shared_ptr<locale_t> lc,
+ character_facet_type type)
+{
+ switch(type) {
+ case char_facet:
+ return std::locale(in,new collator<char>(lc));
+ case wchar_t_facet:
+ return std::locale(in,new collator<wchar_t>(lc));
+ default:
+ return in;
+ }
+}
+
+
+} // impl_std
+} // locale
+} //boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/posix/converter.cpp b/src/boost/libs/locale/src/posix/converter.cpp
new file mode 100644
index 000000000..bf8bc566d
--- /dev/null
+++ b/src/boost/libs/locale/src/posix/converter.cpp
@@ -0,0 +1,165 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+
+#if defined(__FreeBSD__)
+#include <xlocale.h>
+#endif
+#include <locale>
+#include <stdexcept>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/encoding.hpp>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <string.h>
+#include <wctype.h>
+#include <ctype.h>
+#include <langinfo.h>
+#include "all_generator.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_posix {
+
+template<typename CharType>
+struct case_traits;
+
+template<>
+struct case_traits<char> {
+ static char lower(char c,locale_t lc)
+ {
+ return tolower_l(c,lc);
+ }
+ static char upper(char c,locale_t lc)
+ {
+ return toupper_l(c,lc);
+ }
+};
+
+template<>
+struct case_traits<wchar_t> {
+ static wchar_t lower(wchar_t c,locale_t lc)
+ {
+ return towlower_l(c,lc);
+ }
+ static wchar_t upper(wchar_t c,locale_t lc)
+ {
+ return towupper_l(c,lc);
+ }
+};
+
+
+template<typename CharType>
+class std_converter : public converter<CharType>
+{
+public:
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+ typedef std::ctype<char_type> ctype_type;
+ std_converter(boost::shared_ptr<locale_t> lc,size_t refs = 0) :
+ converter<CharType>(refs),
+ lc_(lc)
+ {
+ }
+ virtual string_type convert(converter_base::conversion_type how,char_type const *begin,char_type const *end,int /*flags*/ = 0) const
+ {
+ switch(how) {
+ case converter_base::upper_case:
+ {
+ string_type res;
+ res.reserve(end-begin);
+ while(begin!=end) {
+ res+=case_traits<char_type>::upper(*begin++,*lc_);
+ }
+ return res;
+ }
+ case converter_base::lower_case:
+ case converter_base::case_folding:
+ {
+ string_type res;
+ res.reserve(end-begin);
+ while(begin!=end) {
+ res+=case_traits<char_type>::lower(*begin++,*lc_);
+ }
+ return res;
+ }
+ default:
+ return string_type(begin,end-begin);
+ }
+ }
+private:
+ boost::shared_ptr<locale_t> lc_;
+};
+
+class utf8_converter : public converter<char> {
+public:
+ utf8_converter(boost::shared_ptr<locale_t> lc,size_t refs = 0) :
+ converter<char>(refs),
+ lc_(lc)
+ {
+ }
+ virtual std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int /*flags*/ = 0) const
+ {
+ switch(how) {
+ case upper_case:
+ {
+ std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8");
+ std::wstring wres;
+ wres.reserve(tmp.size());
+ for(unsigned i=0;i<tmp.size();i++)
+ wres+=towupper_l(tmp[i],*lc_);
+ return conv::from_utf<wchar_t>(wres,"UTF-8");
+ }
+
+ case lower_case:
+ case case_folding:
+ {
+ std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8");
+ std::wstring wres;
+ wres.reserve(tmp.size());
+ for(unsigned i=0;i<tmp.size();i++)
+ wres+=towlower_l(tmp[i],*lc_);
+ return conv::from_utf<wchar_t>(wres,"UTF-8");
+ }
+ default:
+ return std::string(begin,end-begin);
+ }
+ }
+private:
+ boost::shared_ptr<locale_t> lc_;
+};
+
+std::locale create_convert( std::locale const &in,
+ boost::shared_ptr<locale_t> lc,
+ character_facet_type type)
+{
+ switch(type) {
+ case char_facet:
+ {
+ std::string encoding = nl_langinfo_l(CODESET,*lc);
+ for(unsigned i=0;i<encoding.size();i++)
+ if('A'<=encoding[i] && encoding[i]<='Z')
+ encoding[i]=encoding[i]-'A'+'a';
+ if(encoding=="utf-8" || encoding=="utf8" || encoding=="utf_8") {
+ return std::locale(in,new utf8_converter(lc));
+ }
+ return std::locale(in,new std_converter<char>(lc));
+ }
+ case wchar_t_facet:
+ return std::locale(in,new std_converter<wchar_t>(lc));
+ default:
+ return in;
+ }
+}
+
+
+} // namespace impl_std
+} // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/posix/numeric.cpp b/src/boost/libs/locale/src/posix/numeric.cpp
new file mode 100644
index 000000000..2bef81e2e
--- /dev/null
+++ b/src/boost/libs/locale/src/posix/numeric.cpp
@@ -0,0 +1,514 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#if defined(__FreeBSD__)
+#include <xlocale.h>
+#endif
+#include <locale>
+#include <string>
+#include <ios>
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/encoding.hpp>
+#include <boost/shared_ptr.hpp>
+#include <sstream>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <wctype.h>
+#include <ctype.h>
+#include <langinfo.h>
+#include <monetary.h>
+#include <errno.h>
+#include "../util/numeric.hpp"
+#include "all_generator.hpp"
+
+
+#if defined(__linux) || defined(__APPLE__)
+#define BOOST_LOCALE_HAVE_WCSFTIME_L
+#endif
+
+namespace boost {
+namespace locale {
+namespace impl_posix {
+
+template<typename CharType>
+class num_format : public util::base_num_format<CharType>
+{
+public:
+ typedef typename std::num_put<CharType>::iter_type iter_type;
+ typedef std::basic_string<CharType> string_type;
+ typedef CharType char_type;
+
+ num_format(boost::shared_ptr<locale_t> lc,size_t refs = 0) :
+ util::base_num_format<CharType>(refs),
+ lc_(lc)
+ {
+ }
+protected:
+
+ virtual iter_type do_format_currency(bool intl,iter_type out,std::ios_base &/*ios*/,char_type /*fill*/,long double val) const
+ {
+ char buf[4]={};
+ char const *format = intl ? "%i" : "%n";
+ errno=0;
+ ssize_t n = strfmon_l(buf,sizeof(buf),*lc_,format,static_cast<double>(val));
+ if(n >= 0)
+ return write_it(out,buf,n);
+
+ for(std::vector<char> tmp(sizeof(buf)*2);tmp.size() <= 4098;tmp.resize(tmp.size()*2)) {
+ n = strfmon_l(&tmp.front(),tmp.size(),*lc_,format,static_cast<double>(val));
+ if(n >= 0)
+ return write_it(out,&tmp.front(),n);
+ }
+ return out;
+ }
+
+ std::ostreambuf_iterator<char> write_it(std::ostreambuf_iterator<char> out,char const *ptr,size_t n) const
+ {
+ for(size_t i=0;i<n;i++)
+ *out++ = *ptr++;
+ return out;
+ }
+
+ std::ostreambuf_iterator<wchar_t> write_it(std::ostreambuf_iterator<wchar_t> out,char const *ptr,size_t n) const
+ {
+ std::wstring tmp = conv::to_utf<wchar_t>(ptr,ptr+n,nl_langinfo_l(CODESET,*lc_));
+ for(size_t i=0;i<tmp.size();i++)
+ *out++ = tmp[i];
+ return out;
+ }
+private:
+
+ boost::shared_ptr<locale_t> lc_;
+
+}; /// num_format
+
+
+template<typename CharType>
+struct ftime_traits;
+
+template<>
+struct ftime_traits<char> {
+ static std::string ftime(char const *format,const struct tm *t,locale_t lc)
+ {
+ char buf[16];
+ size_t n=strftime_l(buf,sizeof(buf),format,t,lc);
+ if(n == 0) {
+ // should be big enough
+ //
+ // Note standard specifies that in case of the error
+ // the function returns 0, however 0 may be actually
+ // valid output value of for example empty format or an
+ // output of %p in some locales
+ //
+ // Thus we try to guess that 1024 would be enough.
+ std::vector<char> v(1024);
+ n = strftime_l(&v.front(),1024,format,t,lc);
+ return std::string(&v.front(),n);
+ }
+ return std::string(buf,n);
+ }
+};
+
+template<>
+struct ftime_traits<wchar_t> {
+ static std::wstring ftime(wchar_t const *format,const struct tm *t,locale_t lc)
+ {
+ #ifdef HAVE_WCSFTIME_L
+ wchar_t buf[16];
+ size_t n=wcsftime_l(buf,sizeof(buf)/sizeof(buf[0]),format,t,lc);
+ if(n == 0) {
+ // should be big enough
+ //
+ // Note standard specifies that in case of the error
+ // the function returns 0, however 0 may be actually
+ // valid output value of for example empty format or an
+ // output of %p in some locales
+ //
+ // Thus we try to guess that 1024 would be enough.
+ std::vector<wchar_t> v(1024);
+ n = wcsftime_l(&v.front(),1024,format,t,lc);
+ }
+ return std::wstring(&v.front(),n);
+ #else
+ std::string enc = nl_langinfo_l(CODESET,lc);
+ std::string nformat = conv::from_utf<wchar_t>(format,enc);
+ std::string nres = ftime_traits<char>::ftime(nformat.c_str(),t,lc);
+ return conv::to_utf<wchar_t>(nres,enc);
+ #endif
+ }
+};
+
+
+template<typename CharType>
+class time_put_posix : public std::time_put<CharType> {
+public:
+ time_put_posix(boost::shared_ptr<locale_t> lc, size_t refs = 0) :
+ std::time_put<CharType>(refs),
+ lc_(lc)
+ {
+ }
+ virtual ~time_put_posix()
+ {
+ }
+ typedef typename std::time_put<CharType>::iter_type iter_type;
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+
+ virtual iter_type do_put(iter_type out,std::ios_base &/*ios*/,CharType /*fill*/,std::tm const *tm,char format,char modifier) const
+ {
+ char_type fmt[4] = { '%' , modifier != 0 ? modifier : format , modifier == 0 ? '\0' : format };
+ string_type res = ftime_traits<char_type>::ftime(fmt,tm,*lc_);
+ for(unsigned i=0;i<res.size();i++)
+ *out++ = res[i];
+ return out;
+ }
+
+private:
+ boost::shared_ptr<locale_t> lc_;
+};
+
+
+template<typename CharType>
+class ctype_posix;
+
+template<>
+class ctype_posix<char> : public std::ctype<char> {
+public:
+
+ ctype_posix(boost::shared_ptr<locale_t> lc)
+ {
+ lc_ = lc;
+ }
+
+ bool do_is(mask m,char c) const
+ {
+ if((m & space) && isspace_l(c,*lc_))
+ return true;
+ if((m & print) && isprint_l(c,*lc_))
+ return true;
+ if((m & cntrl) && iscntrl_l(c,*lc_))
+ return true;
+ if((m & upper) && isupper_l(c,*lc_))
+ return true;
+ if((m & lower) && islower_l(c,*lc_))
+ return true;
+ if((m & alpha) && isalpha_l(c,*lc_))
+ return true;
+ if((m & digit) && isdigit_l(c,*lc_))
+ return true;
+ if((m & xdigit) && isxdigit_l(c,*lc_))
+ return true;
+ if((m & punct) && ispunct_l(c,*lc_))
+ return true;
+ return false;
+ }
+ char const *do_is(char const *begin,char const *end,mask *m) const
+ {
+ while(begin!=end) {
+ char c= *begin++;
+ int r=0;
+ if(isspace_l(c,*lc_))
+ r|=space;
+ if(isprint_l(c,*lc_))
+ r|=cntrl;
+ if(iscntrl_l(c,*lc_))
+ r|=space;
+ if(isupper_l(c,*lc_))
+ r|=upper;
+ if(islower_l(c,*lc_))
+ r|=lower;
+ if(isalpha_l(c,*lc_))
+ r|=alpha;
+ if(isdigit_l(c,*lc_))
+ r|=digit;
+ if(isxdigit_l(c,*lc_))
+ r|=xdigit;
+ if(ispunct_l(c,*lc_))
+ r|=punct;
+ // r actually should be mask, but some standard
+ // libraries (like STLPort)
+ // do not define operator | properly so using int+cast
+ *m++ = static_cast<mask>(r);
+ }
+ return begin;
+ }
+ char const *do_scan_is(mask m,char const *begin,char const *end) const
+ {
+ while(begin!=end)
+ if(do_is(m,*begin))
+ return begin;
+ return begin;
+ }
+ char const *do_scan_not(mask m,char const *begin,char const *end) const
+ {
+ while(begin!=end)
+ if(!do_is(m,*begin))
+ return begin;
+ return begin;
+ }
+ char toupper(char c) const
+ {
+ return toupper_l(c,*lc_);
+ }
+ char const *toupper(char *begin,char const *end) const
+ {
+ for(;begin!=end;begin++)
+ *begin = toupper_l(*begin,*lc_);
+ return begin;
+ }
+ char tolower(char c) const
+ {
+ return tolower_l(c,*lc_);
+ }
+ char const *tolower(char *begin,char const *end) const
+ {
+ for(;begin!=end;begin++)
+ *begin = tolower_l(*begin,*lc_);
+ return begin;
+ }
+private:
+ boost::shared_ptr<locale_t> lc_;
+};
+
+template<>
+class ctype_posix<wchar_t> : public std::ctype<wchar_t> {
+public:
+ ctype_posix(boost::shared_ptr<locale_t> lc)
+ {
+ lc_ = lc;
+ }
+
+ bool do_is(mask m,wchar_t c) const
+ {
+ if((m & space) && iswspace_l(c,*lc_))
+ return true;
+ if((m & print) && iswprint_l(c,*lc_))
+ return true;
+ if((m & cntrl) && iswcntrl_l(c,*lc_))
+ return true;
+ if((m & upper) && iswupper_l(c,*lc_))
+ return true;
+ if((m & lower) && iswlower_l(c,*lc_))
+ return true;
+ if((m & alpha) && iswalpha_l(c,*lc_))
+ return true;
+ if((m & digit) && iswdigit_l(c,*lc_))
+ return true;
+ if((m & xdigit) && iswxdigit_l(c,*lc_))
+ return true;
+ if((m & punct) && iswpunct_l(c,*lc_))
+ return true;
+ return false;
+ }
+ wchar_t const *do_is(wchar_t const *begin,wchar_t const *end,mask *m) const
+ {
+ while(begin!=end) {
+ wchar_t c= *begin++;
+ int r=0;
+ if(iswspace_l(c,*lc_))
+ r|=space;
+ if(iswprint_l(c,*lc_))
+ r|=cntrl;
+ if(iswcntrl_l(c,*lc_))
+ r|=space;
+ if(iswupper_l(c,*lc_))
+ r|=upper;
+ if(iswlower_l(c,*lc_))
+ r|=lower;
+ if(iswalpha_l(c,*lc_))
+ r|=alpha;
+ if(iswdigit_l(c,*lc_))
+ r|=digit;
+ if(iswxdigit_l(c,*lc_))
+ r|=xdigit;
+ if(iswpunct_l(c,*lc_))
+ r|=punct;
+ // r actually should be mask, but some standard
+ // libraries (like STLPort)
+ // do not define operator | properly so using int+cast
+ *m++ = static_cast<mask>(r);
+ }
+ return begin;
+ }
+ wchar_t const *do_scan_is(mask m,wchar_t const *begin,wchar_t const *end) const
+ {
+ while(begin!=end)
+ if(do_is(m,*begin))
+ return begin;
+ return begin;
+ }
+ wchar_t const *do_scan_not(mask m,wchar_t const *begin,wchar_t const *end) const
+ {
+ while(begin!=end)
+ if(!do_is(m,*begin))
+ return begin;
+ return begin;
+ }
+ wchar_t toupper(wchar_t c) const
+ {
+ return towupper_l(c,*lc_);
+ }
+ wchar_t const *toupper(wchar_t *begin,wchar_t const *end) const
+ {
+ for(;begin!=end;begin++)
+ *begin = towupper_l(*begin,*lc_);
+ return begin;
+ }
+ wchar_t tolower(wchar_t c) const
+ {
+ return tolower_l(c,*lc_);
+ }
+ wchar_t const *tolower(wchar_t *begin,wchar_t const *end) const
+ {
+ for(;begin!=end;begin++)
+ *begin = tolower_l(*begin,*lc_);
+ return begin;
+ }
+private:
+ boost::shared_ptr<locale_t> lc_;
+};
+
+
+
+
+struct basic_numpunct {
+ std::string grouping;
+ std::string thousands_sep;
+ std::string decimal_point;
+ basic_numpunct() :
+ decimal_point(".")
+ {
+ }
+ basic_numpunct(locale_t lc)
+ {
+ #if defined(__APPLE__) || defined(__FreeBSD__)
+ lconv *cv = localeconv_l(lc);
+ grouping = cv->grouping;
+ thousands_sep = cv->thousands_sep;
+ decimal_point = cv->decimal_point;
+ #else
+ thousands_sep = nl_langinfo_l(THOUSEP,lc);
+ decimal_point = nl_langinfo_l(RADIXCHAR,lc);
+ #ifdef GROUPING
+ grouping = nl_langinfo_l(GROUPING,lc);
+ #endif
+ #endif
+ }
+};
+
+template<typename CharType>
+class num_punct_posix : public std::numpunct<CharType> {
+public:
+ typedef std::basic_string<CharType> string_type;
+ num_punct_posix(locale_t lc,size_t refs = 0) :
+ std::numpunct<CharType>(refs)
+ {
+ basic_numpunct np(lc);
+ to_str(np.thousands_sep,thousands_sep_,lc);
+ to_str(np.decimal_point,decimal_point_,lc);
+ grouping_ = np.grouping;
+ if(thousands_sep_.size() > 1)
+ grouping_ = std::string();
+ if(decimal_point_.size() > 1)
+ decimal_point_ = CharType('.');
+ }
+ void to_str(std::string &s1,std::string &s2,locale_t /*lc*/)
+ {
+ s2.swap(s1);
+ }
+ void to_str(std::string &s1,std::wstring &s2,locale_t lc)
+ {
+ s2=conv::to_utf<wchar_t>(s1,nl_langinfo_l(CODESET,lc));
+ }
+ virtual CharType do_decimal_point() const
+ {
+ return *decimal_point_.c_str();
+ }
+ virtual CharType do_thousands_sep() const
+ {
+ return *thousands_sep_.c_str();
+ }
+ virtual std::string do_grouping() const
+ {
+ return grouping_;
+ }
+ virtual string_type do_truename() const
+ {
+ static const char t[]="true";
+ return string_type(t,t+sizeof(t)-1);
+ }
+ virtual string_type do_falsename() const
+ {
+ static const char t[]="false";
+ return string_type(t,t+sizeof(t)-1);
+ }
+private:
+ string_type decimal_point_;
+ string_type thousands_sep_;
+ std::string grouping_;
+};
+
+template<typename CharType>
+std::locale create_formatting_impl(std::locale const &in,boost::shared_ptr<locale_t> lc)
+{
+ std::locale tmp = std::locale(in,new num_punct_posix<CharType>(*lc));
+ tmp = std::locale(tmp,new ctype_posix<CharType>(lc));
+ tmp = std::locale(tmp,new time_put_posix<CharType>(lc));
+ tmp = std::locale(tmp,new num_format<CharType>(lc));
+ return tmp;
+}
+
+template<typename CharType>
+std::locale create_parsing_impl(std::locale const &in,boost::shared_ptr<locale_t> lc)
+{
+ std::locale tmp = std::locale(in,new num_punct_posix<CharType>(*lc));
+ tmp = std::locale(tmp,new ctype_posix<CharType>(lc));
+ tmp = std::locale(tmp,new util::base_num_parse<CharType>());
+ return tmp;
+}
+
+
+std::locale create_formatting( std::locale const &in,
+ boost::shared_ptr<locale_t> lc,
+ character_facet_type type)
+{
+ switch(type) {
+ case char_facet:
+ return create_formatting_impl<char>(in,lc);
+ case wchar_t_facet:
+ return create_formatting_impl<wchar_t>(in,lc);
+ default:
+ return in;
+ }
+}
+
+std::locale create_parsing( std::locale const &in,
+ boost::shared_ptr<locale_t> lc,
+ character_facet_type type)
+{
+ switch(type) {
+ case char_facet:
+ return create_parsing_impl<char>(in,lc);
+ case wchar_t_facet:
+ return create_parsing_impl<wchar_t>(in,lc);
+ default:
+ return in;
+ }
+}
+
+
+
+} // impl_std
+} // locale
+} //boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/posix/posix_backend.cpp b/src/boost/libs/locale/src/posix/posix_backend.cpp
new file mode 100644
index 000000000..2ab121df9
--- /dev/null
+++ b/src/boost/libs/locale/src/posix/posix_backend.cpp
@@ -0,0 +1,184 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#if defined(__FreeBSD__)
+#include <xlocale.h>
+#endif
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/gnu_gettext.hpp>
+#include <boost/locale/info.hpp>
+#include "all_generator.hpp"
+#include "posix_backend.hpp"
+
+#include "../util/locale_data.hpp"
+#include "../util/gregorian.hpp"
+#include <boost/locale/util.hpp>
+#include <algorithm>
+#include <iterator>
+
+#include <langinfo.h>
+
+namespace boost {
+namespace locale {
+namespace impl_posix {
+
+ class posix_localization_backend : public localization_backend {
+ public:
+ posix_localization_backend() :
+ invalid_(true)
+ {
+ }
+ posix_localization_backend(posix_localization_backend const &other) :
+ localization_backend(),
+ paths_(other.paths_),
+ domains_(other.domains_),
+ locale_id_(other.locale_id_),
+ invalid_(true)
+ {
+ }
+ virtual posix_localization_backend *clone() const
+ {
+ return new posix_localization_backend(*this);
+ }
+
+ void set_option(std::string const &name,std::string const &value)
+ {
+ invalid_ = true;
+ if(name=="locale")
+ locale_id_ = value;
+ else if(name=="message_path")
+ paths_.push_back(value);
+ else if(name=="message_application")
+ domains_.push_back(value);
+
+ }
+ void clear_options()
+ {
+ invalid_ = true;
+ locale_id_.clear();
+ paths_.clear();
+ domains_.clear();
+ }
+
+ static void free_locale_by_ptr(locale_t *lc)
+ {
+ freelocale(*lc);
+ delete lc;
+ }
+
+ void prepare_data()
+ {
+ if(!invalid_)
+ return;
+ invalid_ = false;
+ lc_.reset();
+ real_id_ = locale_id_;
+ if(real_id_.empty())
+ real_id_ = util::get_system_locale();
+
+ locale_t tmp = newlocale(LC_ALL_MASK,real_id_.c_str(),0);
+
+ if(!tmp) {
+ tmp=newlocale(LC_ALL_MASK,"C",0);
+ }
+ if(!tmp) {
+ throw std::runtime_error("newlocale failed");
+ }
+
+ locale_t *tmp_p = 0;
+
+ try {
+ tmp_p = new locale_t();
+ }
+ catch(...) {
+ freelocale(tmp);
+ throw;
+ }
+
+ *tmp_p = tmp;
+ lc_ = boost::shared_ptr<locale_t>(tmp_p,free_locale_by_ptr);
+ }
+
+ virtual std::locale install(std::locale const &base,
+ locale_category_type category,
+ character_facet_type type = nochar_facet)
+ {
+ prepare_data();
+
+ switch(category) {
+ case convert_facet:
+ return create_convert(base,lc_,type);
+ case collation_facet:
+ return create_collate(base,lc_,type);
+ case formatting_facet:
+ return create_formatting(base,lc_,type);
+ case parsing_facet:
+ return create_parsing(base,lc_,type);
+ case codepage_facet:
+ return create_codecvt(base,nl_langinfo_l(CODESET,*lc_),type);
+ case calendar_facet:
+ {
+ util::locale_data inf;
+ inf.parse(real_id_);
+ return util::install_gregorian_calendar(base,inf.country);
+ }
+ case message_facet:
+ {
+ gnu_gettext::messages_info minf;
+ util::locale_data inf;
+ inf.parse(real_id_);
+ minf.language = inf.language;
+ minf.country = inf.country;
+ minf.variant = inf.variant;
+ minf.encoding = inf.encoding;
+ std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
+ minf.paths = paths_;
+ switch(type) {
+ case char_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
+ case wchar_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf));
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf));
+ #endif
+ default:
+ return base;
+ }
+ }
+ case information_facet:
+ return util::create_info(base,real_id_);
+ default:
+ return base;
+ }
+ }
+
+ private:
+
+ std::vector<std::string> paths_;
+ std::vector<std::string> domains_;
+ std::string locale_id_;
+ std::string real_id_;
+
+ bool invalid_;
+ boost::shared_ptr<locale_t> lc_;
+ };
+
+ localization_backend *create_localization_backend()
+ {
+ return new posix_localization_backend();
+ }
+
+} // impl posix
+} // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/posix/posix_backend.hpp b/src/boost/libs/locale/src/posix/posix_backend.hpp
new file mode 100644
index 000000000..586a33abd
--- /dev/null
+++ b/src/boost/libs/locale/src/posix/posix_backend.hpp
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_POSIX_LOCALIZATION_BACKEND_HPP
+#define BOOST_LOCALE_IMPL_POSIX_LOCALIZATION_BACKEND_HPP
+namespace boost {
+ namespace locale {
+ class localization_backend;
+ namespace impl_posix {
+ localization_backend *create_localization_backend();
+ } // impl_std
+ } // locale
+} // boost
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/shared/date_time.cpp b/src/boost/libs/locale/src/shared/date_time.cpp
new file mode 100644
index 000000000..4f68b7d8f
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/date_time.cpp
@@ -0,0 +1,469 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/date_time.hpp>
+#include <boost/locale/formatting.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <math.h>
+
+namespace boost {
+namespace locale {
+
+using namespace period;
+
+/////////////////////////
+// Calendar
+////////////////////////
+
+calendar::calendar(std::locale const &l,std::string const &zone) :
+ locale_(l),
+ tz_(zone),
+ impl_(std::use_facet<calendar_facet>(l).create_calendar())
+{
+ impl_->set_timezone(tz_);
+}
+
+calendar::calendar(std::string const &zone) :
+ tz_(zone),
+ impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
+{
+ impl_->set_timezone(tz_);
+}
+
+
+calendar::calendar(std::locale const &l) :
+ locale_(l),
+ tz_(time_zone::global()),
+ impl_(std::use_facet<calendar_facet>(l).create_calendar())
+{
+ impl_->set_timezone(tz_);
+}
+
+calendar::calendar(std::ios_base &ios) :
+ locale_(ios.getloc()),
+ tz_(ios_info::get(ios).time_zone()),
+ impl_(std::use_facet<calendar_facet>(locale_).create_calendar())
+{
+ impl_->set_timezone(tz_);
+
+}
+
+calendar::calendar() :
+ tz_(time_zone::global()),
+ impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
+{
+ impl_->set_timezone(tz_);
+}
+
+calendar::~calendar()
+{
+}
+
+calendar::calendar(calendar const &other) :
+ locale_(other.locale_),
+ tz_(other.tz_),
+ impl_(other.impl_->clone())
+{
+}
+
+calendar const &calendar::operator = (calendar const &other)
+{
+ if(this !=&other) {
+ impl_.reset(other.impl_->clone());
+ locale_ = other.locale_;
+ tz_ = other.tz_;
+ }
+ return *this;
+}
+
+
+bool calendar::is_gregorian() const
+{
+ return impl_->get_option(abstract_calendar::is_gregorian)!=0;
+}
+
+std::string calendar::get_time_zone() const
+{
+ return tz_;
+}
+
+std::locale calendar::get_locale() const
+{
+ return locale_;
+}
+
+int calendar::minimum(period_type f) const
+{
+ return impl_->get_value(f.mark(),abstract_calendar::absolute_minimum);
+}
+
+int calendar::greatest_minimum(period_type f) const
+{
+ return impl_->get_value(f.mark(),abstract_calendar::greatest_minimum);
+}
+
+int calendar::maximum(period_type f) const
+{
+ return impl_->get_value(f.mark(),abstract_calendar::absolute_maximum);
+}
+
+int calendar::least_maximum(period_type f) const
+{
+ return impl_->get_value(f.mark(),abstract_calendar::least_maximum);
+}
+
+int calendar::first_day_of_week() const
+{
+ return impl_->get_value(period::marks::first_day_of_week,abstract_calendar::current);
+}
+
+bool calendar::operator==(calendar const &other) const
+{
+ return impl_->same(other.impl_.get());
+}
+
+bool calendar::operator!=(calendar const &other) const
+{
+ return !(*this==other);
+}
+
+//////////////////////////////////
+// date_time
+/////////////////
+
+date_time::date_time() :
+ impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
+{
+ impl_->set_timezone(time_zone::global());
+}
+
+date_time::date_time(date_time const &other)
+{
+ impl_.reset(other.impl_->clone());
+}
+
+date_time::date_time(date_time const &other,date_time_period_set const &s)
+{
+ impl_.reset(other.impl_->clone());
+ for(unsigned i=0;i<s.size();i++) {
+ impl_->set_value(s[i].type.mark(),s[i].value);
+ }
+ impl_->normalize();
+}
+
+date_time const &date_time::operator = (date_time const &other)
+{
+ if(this != &other) {
+ date_time tmp(other);
+ swap(tmp);
+ }
+ return *this;
+}
+
+date_time::~date_time()
+{
+}
+
+date_time::date_time(double t) :
+ impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
+{
+ impl_->set_timezone(time_zone::global());
+ time(t);
+}
+
+date_time::date_time(double t,calendar const &cal) :
+ impl_(cal.impl_->clone())
+{
+ time(t);
+}
+
+date_time::date_time(calendar const &cal) :
+ impl_(cal.impl_->clone())
+{
+}
+
+
+
+date_time::date_time(date_time_period_set const &s) :
+ impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
+{
+ impl_->set_timezone(time_zone::global());
+ for(unsigned i=0;i<s.size();i++) {
+ impl_->set_value(s[i].type.mark(),s[i].value);
+ }
+ impl_->normalize();
+}
+date_time::date_time(date_time_period_set const &s,calendar const &cal) :
+ impl_(cal.impl_->clone())
+{
+ for(unsigned i=0;i<s.size();i++) {
+ impl_->set_value(s[i].type.mark(),s[i].value);
+ }
+ impl_->normalize();
+}
+
+date_time const &date_time::operator=(date_time_period_set const &s)
+{
+ for(unsigned i=0;i<s.size();i++)
+ impl_->set_value(s[i].type.mark(),s[i].value);
+ impl_->normalize();
+ return *this;
+}
+
+void date_time::set(period_type f,int v)
+{
+ impl_->set_value(f.mark(),v);
+ impl_->normalize();
+}
+
+int date_time::get(period_type f) const
+{
+ return impl_->get_value(f.mark(),abstract_calendar::current);
+}
+
+date_time date_time::operator+(date_time_period const &v) const
+{
+ date_time tmp(*this);
+ tmp+=v;
+ return tmp;
+}
+
+date_time date_time::operator-(date_time_period const &v) const
+{
+ date_time tmp(*this);
+ tmp-=v;
+ return tmp;
+}
+
+date_time date_time::operator<<(date_time_period const &v) const
+{
+ date_time tmp(*this);
+ tmp<<=v;
+ return tmp;
+}
+
+date_time date_time::operator>>(date_time_period const &v) const
+{
+ date_time tmp(*this);
+ tmp>>=v;
+ return tmp;
+}
+
+date_time const &date_time::operator+=(date_time_period const &v)
+{
+ impl_->adjust_value(v.type.mark(),abstract_calendar::move,v.value);
+ return *this;
+}
+
+date_time const &date_time::operator-=(date_time_period const &v)
+{
+ impl_->adjust_value(v.type.mark(),abstract_calendar::move,-v.value);
+ return *this;
+}
+
+date_time const &date_time::operator<<=(date_time_period const &v)
+{
+ impl_->adjust_value(v.type.mark(),abstract_calendar::roll,v.value);
+ return *this;
+}
+
+date_time const &date_time::operator>>=(date_time_period const &v)
+{
+ impl_->adjust_value(v.type.mark(),abstract_calendar::roll,-v.value);
+ return *this;
+}
+
+
+date_time date_time::operator+(date_time_period_set const &v) const
+{
+ date_time tmp(*this);
+ tmp+=v;
+ return tmp;
+}
+
+date_time date_time::operator-(date_time_period_set const &v) const
+{
+ date_time tmp(*this);
+ tmp-=v;
+ return tmp;
+}
+
+date_time date_time::operator<<(date_time_period_set const &v) const
+{
+ date_time tmp(*this);
+ tmp<<=v;
+ return tmp;
+}
+
+date_time date_time::operator>>(date_time_period_set const &v) const
+{
+ date_time tmp(*this);
+ tmp>>=v;
+ return tmp;
+}
+
+date_time const &date_time::operator+=(date_time_period_set const &v)
+{
+ for(unsigned i=0;i<v.size();i++) {
+ *this+=v[i];
+ }
+ return *this;
+}
+
+date_time const &date_time::operator-=(date_time_period_set const &v)
+{
+ for(unsigned i=0;i<v.size();i++) {
+ *this-=v[i];
+ }
+ return *this;
+}
+
+date_time const &date_time::operator<<=(date_time_period_set const &v)
+{
+ for(unsigned i=0;i<v.size();i++) {
+ *this<<=v[i];
+ }
+ return *this;
+}
+
+date_time const &date_time::operator>>=(date_time_period_set const &v)
+{
+ for(unsigned i=0;i<v.size();i++) {
+ *this>>=v[i];
+ }
+ return *this;
+}
+
+double date_time::time() const
+{
+ posix_time ptime = impl_->get_time();
+ return double(ptime.seconds)+1e-9*ptime.nanoseconds;
+}
+
+void date_time::time(double v)
+{
+ double dseconds = floor(v);
+ int64_t seconds = static_cast<int64_t>(dseconds);
+ double fract = v - dseconds;
+ int nano = static_cast<int>(fract * 1e9);
+ if(nano < 0)
+ nano = 0;
+ else if(nano >999999999)
+ nano = 999999999;
+ posix_time ptime;
+ ptime.seconds = seconds;
+ ptime.nanoseconds = nano;
+ impl_->set_time(ptime);
+}
+
+namespace {
+ int compare(posix_time const &left,posix_time const &right)
+ {
+ if(left.seconds < right.seconds)
+ return -1;
+ if(left.seconds > right.seconds)
+ return 1;
+ if(left.nanoseconds < right.nanoseconds)
+ return -1;
+ if(left.nanoseconds > right.nanoseconds)
+ return 1;
+ return 0;
+ }
+}
+
+bool date_time::operator==(date_time const &other) const
+{
+ return compare(impl_->get_time(),other.impl_->get_time()) == 0;
+}
+
+bool date_time::operator!=(date_time const &other) const
+{
+ return !(*this==other);
+}
+
+bool date_time::operator<(date_time const &other) const
+{
+ return compare(impl_->get_time(),other.impl_->get_time()) < 0;
+}
+
+bool date_time::operator>=(date_time const &other) const
+{
+ return !(*this<other);
+}
+
+bool date_time::operator>(date_time const &other) const
+{
+ return compare(impl_->get_time(),other.impl_->get_time()) > 0;
+}
+
+bool date_time::operator<=(date_time const &other) const
+{
+ return !(*this>other);
+}
+
+void date_time::swap(date_time &other)
+{
+ impl_.swap(other.impl_);
+}
+
+int date_time::difference(date_time const &other,period_type f) const
+{
+ return impl_->difference(other.impl_.get(),f.mark());
+}
+
+int date_time::maximum(period_type f) const
+{
+ return impl_->get_value(f.mark(),abstract_calendar::actual_maximum);
+}
+
+int date_time::minimum(period_type f) const
+{
+ return impl_->get_value(f.mark(),abstract_calendar::actual_minimum);
+}
+
+bool date_time::is_in_daylight_saving_time() const
+{
+ return impl_->get_option(abstract_calendar::is_dst)!=0;
+}
+
+namespace time_zone {
+ boost::mutex &tz_mutex()
+ {
+ static boost::mutex m;
+ return m;
+ }
+ std::string &tz_id()
+ {
+ static std::string id;
+ return id;
+ }
+ std::string global()
+ {
+ boost::unique_lock<boost::mutex> lock(tz_mutex());
+ std::string id = tz_id();
+ return id;
+ }
+ std::string global(std::string const &new_id)
+ {
+ boost::unique_lock<boost::mutex> lock(tz_mutex());
+ std::string id = tz_id();
+ tz_id() = new_id;
+ return id;
+ }
+}
+
+
+
+} // locale
+} // boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/shared/format.cpp b/src/boost/libs/locale/src/shared/format.cpp
new file mode 100644
index 000000000..839ee5222
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/format.cpp
@@ -0,0 +1,188 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/format.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/info.hpp>
+#include <limits>
+#include <stdlib.h>
+
+#include <iostream>
+
+namespace boost {
+ namespace locale {
+ namespace details {
+ struct format_parser::data {
+ unsigned position;
+ std::streamsize precision;
+ std::ios_base::fmtflags flags;
+ ios_info info;
+ std::locale saved_locale;
+ bool restore_locale;
+ void *cookie;
+ void (*imbuer)(void *,std::locale const &);
+ };
+
+ format_parser::format_parser(std::ios_base &ios,void *cookie,void (*imbuer)(void *,std::locale const &)) :
+ ios_(ios),
+ d(new data)
+ {
+ d->position=std::numeric_limits<unsigned>::max();
+ d->precision=ios.precision();
+ d->flags = ios.flags();
+ d->info=ios_info::get(ios);
+ d->saved_locale = ios.getloc();
+ d->restore_locale=false;
+ d->cookie = cookie;
+ d->imbuer = imbuer;
+ }
+
+ void format_parser::imbue(std::locale const &l)
+ {
+ d->imbuer(d->cookie,l);
+ }
+
+ format_parser::~format_parser()
+ {
+ }
+
+ void format_parser::restore()
+ {
+ ios_info::get(ios_) = d->info;
+ ios_.width(0);
+ ios_.flags(d->flags);
+ if(d->restore_locale)
+ imbue(d->saved_locale);
+ }
+
+ unsigned format_parser::get_position()
+ {
+ return d->position;
+ }
+
+ void format_parser::set_one_flag(std::string const &key,std::string const &value)
+ {
+ if(key.empty())
+ return;
+ unsigned i;
+ for(i=0;i<key.size();i++) {
+ if(key[i] < '0' || '9'< key[i])
+ break;
+ }
+ if(i==key.size()) {
+ d->position=atoi(key.c_str()) - 1;
+ return;
+ }
+
+ if(key=="num" || key=="number") {
+ as::number(ios_);
+
+ if(value=="hex")
+ ios_.setf(std::ios_base::hex,std::ios_base::basefield);
+ else if(value=="oct")
+ ios_.setf(std::ios_base::oct,std::ios_base::basefield);
+ else if(value=="sci" || value=="scientific")
+ ios_.setf(std::ios_base::scientific,std::ios_base::floatfield);
+ else if(value=="fix" || value=="fixed")
+ ios_.setf(std::ios_base::fixed,std::ios_base::floatfield);
+ }
+ else if(key=="cur" || key=="currency") {
+ as::currency(ios_);
+ if(value=="iso")
+ as::currency_iso(ios_);
+ else if(value=="nat" || value=="national")
+ as::currency_national(ios_);
+ }
+ else if(key=="per" || key=="percent") {
+ as::percent(ios_);
+ }
+ else if(key=="date") {
+ as::date(ios_);
+ if(value=="s" || value=="short")
+ as::date_short(ios_);
+ else if(value=="m" || value=="medium")
+ as::date_medium(ios_);
+ else if(value=="l" || value=="long")
+ as::date_long(ios_);
+ else if(value=="f" || value=="full")
+ as::date_full(ios_);
+ }
+ else if(key=="time") {
+ as::time(ios_);
+ if(value=="s" || value=="short")
+ as::time_short(ios_);
+ else if(value=="m" || value=="medium")
+ as::time_medium(ios_);
+ else if(value=="l" || value=="long")
+ as::time_long(ios_);
+ else if(value=="f" || value=="full")
+ as::time_full(ios_);
+ }
+ else if(key=="dt" || key=="datetime") {
+ as::datetime(ios_);
+ if(value=="s" || value=="short") {
+ as::date_short(ios_);
+ as::time_short(ios_);
+ }
+ else if(value=="m" || value=="medium") {
+ as::date_medium(ios_);
+ as::time_medium(ios_);
+ }
+ else if(value=="l" || value=="long") {
+ as::date_long(ios_);
+ as::time_long(ios_);
+ }
+ else if(value=="f" || value=="full") {
+ as::date_full(ios_);
+ as::time_full(ios_);
+ }
+ }
+ else if(key=="spell" || key=="spellout") {
+ as::spellout(ios_);
+ }
+ else if(key=="ord" || key=="ordinal") {
+ as::ordinal(ios_);
+ }
+ else if(key=="left" || key=="<")
+ ios_.setf(std::ios_base::left,std::ios_base::adjustfield);
+ else if(key=="right" || key==">")
+ ios_.setf(std::ios_base::right,std::ios_base::adjustfield);
+ else if(key=="gmt")
+ as::gmt(ios_);
+ else if(key=="local")
+ as::local_time(ios_);
+ else if(key=="timezone" || key=="tz")
+ ios_info::get(ios_).time_zone(value);
+ else if(key=="w" || key=="width")
+ ios_.width(atoi(value.c_str()));
+ else if(key=="p" || key=="precision")
+ ios_.precision(atoi(value.c_str()));
+ else if(key=="locale") {
+ if(!d->restore_locale) {
+ d->saved_locale=ios_.getloc();
+ d->restore_locale=true;
+ }
+
+ std::string encoding=std::use_facet<info>(d->saved_locale).encoding();
+ generator gen;
+ gen.categories(formatting_facet);
+
+ std::locale new_loc;
+ if(value.find('.')==std::string::npos)
+ new_loc = gen(value + "." + encoding);
+ else
+ new_loc = gen(value);
+
+ imbue(new_loc);
+ }
+
+ }
+ }
+ }
+}
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/shared/formatting.cpp b/src/boost/libs/locale/src/shared/formatting.cpp
new file mode 100644
index 000000000..70c16c908
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/formatting.cpp
@@ -0,0 +1,180 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/date_time.hpp>
+#include <typeinfo>
+#include <algorithm>
+#include "ios_prop.hpp"
+
+namespace boost {
+ namespace locale {
+
+ ios_info::string_set::string_set() :
+ type(0),
+ size(0),
+ ptr(0)
+ {
+ }
+ ios_info::string_set::~string_set()
+ {
+ delete [] ptr;
+ }
+ ios_info::string_set::string_set(string_set const &other)
+ {
+ if(other.ptr!=0) {
+ ptr=new char[other.size];
+ size=other.size;
+ type=other.type;
+ memcpy(ptr,other.ptr,size);
+ }
+ else {
+ ptr=0;
+ size=0;
+ type=0;
+ }
+ }
+
+ void ios_info::string_set::swap(string_set &other)
+ {
+ std::swap(type,other.type);
+ std::swap(size,other.size);
+ std::swap(ptr,other.ptr);
+ }
+
+ ios_info::string_set const &ios_info::string_set::operator=(string_set const &other)
+ {
+ if(this!=&other) {
+ string_set tmp(other);
+ swap(tmp);
+ }
+ return *this;
+ }
+
+ struct ios_info::data {};
+
+ ios_info::ios_info() :
+ flags_(0),
+ domain_id_(0),
+ d(0)
+ {
+ time_zone_ = time_zone::global();
+ }
+ ios_info::~ios_info()
+ {
+ }
+
+ ios_info::ios_info(ios_info const &other)
+ {
+ flags_ = other.flags_;
+ domain_id_ = other.domain_id_;
+ time_zone_ = other.time_zone_;
+ datetime_ = other.datetime_;
+ }
+
+
+ ios_info const &ios_info::operator=(ios_info const &other)
+ {
+ if(this!=&other) {
+ flags_ = other.flags_;
+ domain_id_ = other.domain_id_;
+ time_zone_ = other.time_zone_;
+ datetime_ = other.datetime_;
+ }
+ return *this;
+ }
+
+ void ios_info::display_flags(uint64_t f)
+ {
+ flags_ = (flags_ & ~uint64_t(flags::display_flags_mask)) | f;
+ }
+ void ios_info::currency_flags(uint64_t f)
+ {
+ flags_ = (flags_ & ~uint64_t(flags::currency_flags_mask)) | f;
+ }
+ void ios_info::date_flags(uint64_t f)
+ {
+ flags_ = (flags_ & ~uint64_t(flags::date_flags_mask)) | f;
+ }
+ void ios_info::time_flags(uint64_t f)
+ {
+ flags_ = (flags_ & ~uint64_t(flags::time_flags_mask)) | f;
+ }
+
+ void ios_info::domain_id(int id)
+ {
+ domain_id_ = id;
+ }
+
+ void ios_info::time_zone(std::string const &tz)
+ {
+ time_zone_ = tz;
+ }
+
+ uint64_t ios_info::display_flags() const
+ {
+ return flags_ & flags::display_flags_mask;
+ }
+
+ uint64_t ios_info::currency_flags() const
+ {
+ return flags_ & flags::currency_flags_mask;
+ }
+
+ uint64_t ios_info::date_flags() const
+ {
+ return flags_ & flags::date_flags_mask;
+ }
+
+ uint64_t ios_info::time_flags() const
+ {
+ return flags_ & flags::time_flags_mask;
+ }
+
+ int ios_info::domain_id() const
+ {
+ return domain_id_;
+ }
+
+ std::string ios_info::time_zone() const
+ {
+ return time_zone_;
+ }
+
+ ios_info::string_set const &ios_info::date_time_pattern_set() const
+ {
+ return datetime_;
+ }
+
+
+ ios_info::string_set &ios_info::date_time_pattern_set()
+ {
+ return datetime_;
+ }
+
+ ios_info &ios_info::get(std::ios_base &ios)
+ {
+ return impl::ios_prop<ios_info>::get(ios);
+ }
+
+ void ios_info::on_imbue()
+ {
+ }
+
+ namespace {
+ struct initializer {
+ initializer() {
+ impl::ios_prop<ios_info>::global_init();
+ }
+ } initializer_instance;
+ } // namespace
+
+ } // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/shared/generator.cpp b/src/boost/libs/locale/src/shared/generator.cpp
new file mode 100644
index 000000000..a93ecb273
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/generator.cpp
@@ -0,0 +1,192 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/generator.hpp>
+#include <boost/locale/encoding.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+
+namespace boost {
+ namespace locale {
+ struct generator::data {
+ data(localization_backend_manager const &mgr) :
+ cats(all_categories),
+ chars(all_characters),
+ caching_enabled(false),
+ use_ansi_encoding(false),
+ backend_manager(mgr)
+ {
+ }
+
+ typedef std::map<std::string,std::locale> cached_type;
+ mutable cached_type cached;
+ mutable boost::mutex cached_lock;
+
+ locale_category_type cats;
+ character_facet_type chars;
+
+ bool caching_enabled;
+ bool use_ansi_encoding;
+
+ std::vector<std::string> paths;
+ std::vector<std::string> domains;
+
+ std::map<std::string,std::vector<std::string> > options;
+
+ localization_backend_manager backend_manager;
+
+ };
+
+ generator::generator(localization_backend_manager const &mgr) :
+ d(new generator::data(mgr))
+ {
+ }
+ generator::generator() :
+ d(new generator::data(localization_backend_manager::global()))
+ {
+ }
+ generator::~generator()
+ {
+ }
+
+ locale_category_type generator::categories() const
+ {
+ return d->cats;
+ }
+ void generator::categories(locale_category_type t)
+ {
+ d->cats=t;
+ }
+
+ void generator::characters(character_facet_type t)
+ {
+ d->chars=t;
+ }
+
+ character_facet_type generator::characters() const
+ {
+ return d->chars;
+ }
+
+ void generator::add_messages_domain(std::string const &domain)
+ {
+ if(std::find(d->domains.begin(),d->domains.end(),domain) == d->domains.end())
+ d->domains.push_back(domain);
+ }
+
+ void generator::set_default_messages_domain(std::string const &domain)
+ {
+ std::vector<std::string>::iterator p;
+ if((p=std::find(d->domains.begin(),d->domains.end(),domain)) != d->domains.end()) {
+ d->domains.erase(p);
+ }
+ d->domains.insert(d->domains.begin(),domain);
+ }
+
+ void generator::clear_domains()
+ {
+ d->domains.clear();
+ }
+ void generator::add_messages_path(std::string const &path)
+ {
+ d->paths.push_back(path);
+ }
+ void generator::clear_paths()
+ {
+ d->paths.clear();
+ }
+ void generator::clear_cache()
+ {
+ d->cached.clear();
+ }
+
+ std::locale generator::generate(std::string const &id) const
+ {
+ std::locale base=std::locale::classic();
+
+ return generate(base,id);
+ }
+
+ std::locale generator::generate(std::locale const &base,std::string const &id) const
+ {
+ if(d->caching_enabled) {
+ boost::unique_lock<boost::mutex> guard(d->cached_lock);
+ data::cached_type::const_iterator p = d->cached.find(id);
+ if(p!=d->cached.end()) {
+ return p->second;
+ }
+ }
+ shared_ptr<localization_backend> backend(d->backend_manager.create());
+ set_all_options(backend,id);
+
+ std::locale result = base;
+ locale_category_type facets = d->cats;
+ character_facet_type chars = d->chars;
+
+ for(locale_category_type facet = per_character_facet_first; facet <= per_character_facet_last && facet!=0; facet <<=1) {
+ if(!(facets & facet))
+ continue;
+ for(character_facet_type ch = character_first_facet ; ch<=character_last_facet;ch <<=1) {
+ if(!(ch & chars))
+ continue;
+ result = backend->install(result,facet,ch);
+ }
+ }
+ for(locale_category_type facet = non_character_facet_first; facet <= non_character_facet_last && facet!=0; facet <<=1) {
+ if(!(facets & facet))
+ continue;
+ result = backend->install(result,facet);
+ }
+ if(d->caching_enabled) {
+ boost::unique_lock<boost::mutex> guard(d->cached_lock);
+ data::cached_type::const_iterator p = d->cached.find(id);
+ if(p==d->cached.end()) {
+ d->cached[id] = result;
+ }
+ }
+ return result;
+ }
+
+ bool generator::use_ansi_encoding() const
+ {
+ return d->use_ansi_encoding;
+ }
+
+ void generator::use_ansi_encoding(bool v)
+ {
+ d->use_ansi_encoding = v;
+ }
+
+ bool generator::locale_cache_enabled() const
+ {
+ return d->caching_enabled;
+ }
+ void generator::locale_cache_enabled(bool enabled)
+ {
+ d->caching_enabled = enabled;
+ }
+
+ void generator::set_all_options(shared_ptr<localization_backend> backend,std::string const &id) const
+ {
+ backend->set_option("locale",id);
+ if(d->use_ansi_encoding)
+ backend->set_option("use_ansi_encoding","true");
+ for(size_t i=0;i<d->domains.size();i++)
+ backend->set_option("message_application",d->domains[i]);
+ for(size_t i=0;i<d->paths.size();i++)
+ backend->set_option("message_path",d->paths[i]);
+ }
+
+ } // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/shared/ids.cpp b/src/boost/libs/locale/src/shared/ids.cpp
new file mode 100644
index 000000000..952fa85a5
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/ids.cpp
@@ -0,0 +1,88 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/boundary.hpp>
+#include <boost/locale/collator.hpp>
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/date_time_facet.hpp>
+#include <boost/locale/message.hpp>
+#include <boost/locale/info.hpp>
+
+namespace boost {
+ namespace locale {
+
+ std::locale::id info::id;
+ std::locale::id calendar_facet::id;
+
+ std::locale::id converter<char>::id;
+ std::locale::id base_message_format<char>::id;
+
+ std::locale::id converter<wchar_t>::id;
+ std::locale::id base_message_format<wchar_t>::id;
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+
+ std::locale::id converter<char16_t>::id;
+ std::locale::id base_message_format<char16_t>::id;
+
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+
+ std::locale::id converter<char32_t>::id;
+ std::locale::id base_message_format<char32_t>::id;
+
+ #endif
+
+ namespace boundary {
+
+ std::locale::id boundary_indexing<char>::id;
+
+ std::locale::id boundary_indexing<wchar_t>::id;
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::locale::id boundary_indexing<char16_t>::id;
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::locale::id boundary_indexing<char32_t>::id;
+ #endif
+ }
+
+ namespace {
+ struct install_all {
+ install_all()
+ {
+ std::locale l = std::locale::classic();
+ install_by<char>();
+ install_by<wchar_t>();
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ install_by<char16_t>();
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ install_by<char32_t>();
+ #endif
+
+ std::has_facet<info>(l);
+ std::has_facet<calendar_facet>(l);
+ }
+ template<typename Char>
+ void install_by()
+ {
+ std::locale l = std::locale::classic();
+ std::has_facet<boundary::boundary_indexing<Char> >(l);
+ std::has_facet<converter<Char> >(l);
+ std::has_facet<base_message_format<Char> >(l);
+ }
+ } installer;
+ }
+
+ }
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/shared/ios_prop.hpp b/src/boost/libs/locale/src/shared/ios_prop.hpp
new file mode 100644
index 000000000..0a820e126
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/ios_prop.hpp
@@ -0,0 +1,109 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_SRC_LOCALE_IOS_PROP_HPP
+#define BOOST_SRC_LOCALE_IOS_PROP_HPP
+#include <ios>
+
+namespace boost {
+ namespace locale {
+ namespace impl {
+
+ template<typename Property>
+ class ios_prop {
+ public:
+ static void set(Property const &prop,std::ios_base &ios)
+ {
+ int id=get_id();
+ if(ios.pword(id)==0) {
+ ios.pword(id) = new Property(prop);
+ ios.register_callback(callback,id);
+ }
+ else if(ios.pword(id)==invalid) {
+ ios.pword(id) = new Property(prop);
+ }
+ else {
+ *static_cast<Property *>(ios.pword(id))=prop;
+ }
+ }
+
+ static Property &get(std::ios_base &ios)
+ {
+ int id=get_id();
+ if(!has(ios))
+ set(Property(),ios);
+ return *static_cast<Property *>(ios.pword(id));
+ }
+
+ static bool has(std::ios_base &ios)
+ {
+ int id=get_id();
+ if(ios.pword(id)==0 || ios.pword(id)==invalid)
+ return false;
+ return true;
+ }
+
+ static void unset(std::ios_base &ios)
+ {
+ if(has(ios)) {
+ int id=get_id();
+ Property *p=static_cast<Property *>(ios.pword(id));
+ delete p;
+ ios.pword(id)=invalid;
+ }
+ }
+ static void global_init()
+ {
+ get_id();
+ }
+ private:
+ static void * const invalid;
+
+ static void callback(std::ios_base::event ev,std::ios_base &ios,int id)
+ {
+ switch(ev) {
+ case std::ios_base::erase_event:
+ if(!has(ios))
+ break;
+ delete reinterpret_cast<Property *>(ios.pword(id));
+ break;
+ case std::ios_base::copyfmt_event:
+ if(ios.pword(id)==invalid || ios.pword(id)==0)
+ break;
+ ios.pword(id)=new Property(*reinterpret_cast<Property *>(ios.pword(id)));
+ break;
+ case std::ios_base::imbue_event:
+ if(ios.pword(id)==invalid || ios.pword(id)==0)
+ break;
+ reinterpret_cast<Property *>(ios.pword(id))->on_imbue();
+ break;
+
+ default: ;
+ }
+ }
+ static int get_id()
+ {
+ static int id = std::ios_base::xalloc();
+ return id;
+ }
+ };
+
+ template<typename Property>
+ void * const ios_prop<Property>::invalid = (void *)(-1);
+
+
+
+ }
+ }
+}
+
+
+
+#endif
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/shared/localization_backend.cpp b/src/boost/libs/locale/src/shared/localization_backend.cpp
new file mode 100644
index 000000000..0a9b7a281
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/localization_backend.cpp
@@ -0,0 +1,285 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/localization_backend.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/locale/hold_ptr.hpp>
+#include <vector>
+
+#ifdef BOOST_LOCALE_WITH_ICU
+#include "../icu/icu_backend.hpp"
+#endif
+
+#ifndef BOOST_LOCALE_NO_POSIX_BACKEND
+#include "../posix/posix_backend.hpp"
+#endif
+
+#ifndef BOOST_LOCALE_NO_STD_BACKEND
+#include "../std/std_backend.hpp"
+#endif
+
+#ifndef BOOST_LOCALE_NO_WINAPI_BACKEND
+#include "../win32/win_backend.hpp"
+#endif
+
+namespace boost {
+ namespace locale {
+ class localization_backend_manager::impl {
+ void operator = (impl const &);
+ public:
+ impl(impl const &other) :
+ default_backends_(other.default_backends_)
+ {
+ for(all_backends_type::const_iterator p=other.all_backends_.begin();p!=other.all_backends_.end();++p) {
+ all_backends_type::value_type v;
+ v.first=p->first;
+ v.second.reset(p->second->clone());
+ all_backends_.push_back(v);
+ }
+ }
+ impl() :
+ default_backends_(32,-1)
+ {
+ }
+
+ localization_backend *create() const
+ {
+ std::vector<boost::shared_ptr<localization_backend> > backends;
+ for(unsigned i=0;i<all_backends_.size();i++)
+ backends.push_back(all_backends_[i].second);
+ return new actual_backend(backends,default_backends_);
+ }
+ void adopt_backend(std::string const &name,localization_backend *backend_ptr)
+ {
+ boost::shared_ptr<localization_backend> sptr(backend_ptr);
+ if(all_backends_.empty()) {
+ all_backends_.push_back(std::make_pair(name,sptr));
+ for(unsigned i=0;i<default_backends_.size();i++)
+ default_backends_[i]=0;
+ }
+ else {
+ for(unsigned i=0;i<all_backends_.size();i++)
+ if(all_backends_[i].first == name)
+ return;
+ all_backends_.push_back(std::make_pair(name,sptr));
+ }
+ }
+
+ void select(std::string const &backend_name,locale_category_type category = all_categories)
+ {
+ unsigned id;
+ for(id=0;id<all_backends_.size();id++) {
+ if(all_backends_[id].first == backend_name)
+ break;
+ }
+ if(id==all_backends_.size())
+ return;
+ for(unsigned flag = 1,i=0;i<default_backends_.size();flag <<=1,i++) {
+ if(category & flag) {
+ default_backends_[i]=id;
+ }
+ }
+ }
+
+ void remove_all_backends()
+ {
+ all_backends_.clear();
+ for(unsigned i=0;i<default_backends_.size();i++) {
+ default_backends_[i]=-1;
+ }
+ }
+ std::vector<std::string> get_all_backends() const
+ {
+ std::vector<std::string> res;
+ all_backends_type::const_iterator p;
+ for(p=all_backends_.begin();p!=all_backends_.end();++p) {
+ res.push_back(p->first);
+ }
+ return res;
+ }
+
+ private:
+ class actual_backend : public localization_backend {
+ public:
+ actual_backend(std::vector<boost::shared_ptr<localization_backend> > const &backends,std::vector<int> const &index):
+ index_(index)
+ {
+ backends_.resize(backends.size());
+ for(unsigned i=0;i<backends.size();i++) {
+ backends_[i].reset(backends[i]->clone());
+ }
+ }
+ virtual actual_backend *clone() const
+ {
+ return new actual_backend(backends_,index_);
+ }
+ virtual void set_option(std::string const &name,std::string const &value)
+ {
+ for(unsigned i=0;i<backends_.size();i++)
+ backends_[i]->set_option(name,value);
+ }
+ virtual void clear_options()
+ {
+ for(unsigned i=0;i<backends_.size();i++)
+ backends_[i]->clear_options();
+ }
+ virtual std::locale install(std::locale const &l,locale_category_type category,character_facet_type type = nochar_facet)
+ {
+ int id;
+ unsigned v;
+ for(v=1,id=0;v!=0;v<<=1,id++) {
+ if(category == v)
+ break;
+ }
+ if(v==0)
+ return l;
+ if(unsigned(id) >= index_.size())
+ return l;
+ if(index_[id]==-1)
+ return l;
+ return backends_[index_[id]]->install(l,category,type);
+ }
+ private:
+ std::vector<boost::shared_ptr<localization_backend> > backends_;
+ std::vector<int> index_;
+ };
+
+ typedef std::vector<std::pair<std::string,boost::shared_ptr<localization_backend> > > all_backends_type;
+ all_backends_type all_backends_;
+ std::vector<int> default_backends_;
+ };
+
+
+
+ localization_backend_manager::localization_backend_manager() :
+ pimpl_(new impl())
+ {
+ }
+
+ localization_backend_manager::~localization_backend_manager()
+ {
+ }
+
+ localization_backend_manager::localization_backend_manager(localization_backend_manager const &other) :
+ pimpl_(new impl(*other.pimpl_))
+ {
+ }
+
+ localization_backend_manager const &localization_backend_manager::operator = (localization_backend_manager const &other)
+ {
+ if(this!=&other) {
+ pimpl_.reset(new impl(*other.pimpl_));
+ }
+ return *this;
+ }
+
+
+ #if !defined(BOOST_LOCALE_HIDE_AUTO_PTR) && !defined(BOOST_NO_AUTO_PTR)
+ std::auto_ptr<localization_backend> localization_backend_manager::get() const
+ {
+ std::auto_ptr<localization_backend> r(pimpl_->create());
+ return r;
+ }
+ void localization_backend_manager::add_backend(std::string const &name,std::auto_ptr<localization_backend> backend)
+ {
+ pimpl_->adopt_backend(name,backend.release());
+ }
+ #endif
+ #ifndef BOOST_NO_CXX11_SMART_PTR
+ std::unique_ptr<localization_backend> localization_backend_manager::get_unique_ptr() const
+ {
+ std::unique_ptr<localization_backend> r(pimpl_->create());
+ return r;
+ }
+ void localization_backend_manager::add_backend(std::string const &name,std::unique_ptr<localization_backend> backend)
+ {
+ pimpl_->adopt_backend(name,backend.release());
+ }
+ #endif
+ localization_backend *localization_backend_manager::create() const
+ {
+ return pimpl_->create();
+ }
+ void localization_backend_manager::adopt_backend(std::string const &name,localization_backend *backend)
+ {
+ pimpl_->adopt_backend(name,backend);
+ }
+
+
+ void localization_backend_manager::remove_all_backends()
+ {
+ pimpl_->remove_all_backends();
+ }
+ std::vector<std::string> localization_backend_manager::get_all_backends() const
+ {
+ return pimpl_->get_all_backends();
+ }
+ void localization_backend_manager::select(std::string const &backend_name,locale_category_type category)
+ {
+ pimpl_->select(backend_name,category);
+ }
+
+ namespace {
+ // prevent initialization order fiasco
+ boost::mutex &localization_backend_manager_mutex()
+ {
+ static boost::mutex the_mutex;
+ return the_mutex;
+ }
+ // prevent initialization order fiasco
+ localization_backend_manager &localization_backend_manager_global()
+ {
+ static localization_backend_manager the_manager;
+ return the_manager;
+ }
+
+ struct init {
+ init() {
+ localization_backend_manager mgr;
+ #ifdef BOOST_LOCALE_WITH_ICU
+ mgr.adopt_backend("icu",impl_icu::create_localization_backend());
+ #endif
+
+ #ifndef BOOST_LOCALE_NO_POSIX_BACKEND
+ mgr.adopt_backend("posix",impl_posix::create_localization_backend());
+ #endif
+
+ #ifndef BOOST_LOCALE_NO_WINAPI_BACKEND
+ mgr.adopt_backend("winapi",impl_win::create_localization_backend());
+ #endif
+
+ #ifndef BOOST_LOCALE_NO_STD_BACKEND
+ mgr.adopt_backend("std",impl_std::create_localization_backend());
+ #endif
+
+ localization_backend_manager::global(mgr);
+ }
+ } do_init;
+ }
+
+ localization_backend_manager localization_backend_manager::global()
+ {
+ boost::unique_lock<boost::mutex> lock(localization_backend_manager_mutex());
+ localization_backend_manager mgr = localization_backend_manager_global();
+ return mgr;
+ }
+ localization_backend_manager localization_backend_manager::global(localization_backend_manager const &in)
+ {
+ boost::unique_lock<boost::mutex> lock(localization_backend_manager_mutex());
+ localization_backend_manager mgr = localization_backend_manager_global();
+ localization_backend_manager_global() = in;
+ return mgr;
+ }
+
+
+
+ } // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/shared/message.cpp b/src/boost/libs/locale/src/shared/message.cpp
new file mode 100644
index 000000000..e25d26fd8
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/message.cpp
@@ -0,0 +1,784 @@
+//
+// Copyright (c) 2009-2015 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#define BOOST_DETAIL_NO_CONTAINER_FWD
+#include <boost/config.hpp>
+#include <boost/version.hpp>
+#include <boost/locale/message.hpp>
+#include <boost/locale/gnu_gettext.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/locale/hold_ptr.hpp>
+#include <boost/locale/encoding.hpp>
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4996)
+#endif
+
+
+#if BOOST_VERSION >= 103600
+#define BOOST_LOCALE_UNORDERED_CATALOG
+#endif
+
+#ifdef BOOST_LOCALE_UNORDERED_CATALOG
+#include <boost/unordered_map.hpp>
+#else
+#include <map>
+#endif
+
+#include <iostream>
+
+
+#include "mo_hash.hpp"
+#include "mo_lambda.hpp"
+
+#include <stdio.h>
+
+#include <string.h>
+
+namespace boost {
+ namespace locale {
+ namespace gnu_gettext {
+
+ class c_file {
+ c_file(c_file const &);
+ void operator=(c_file const &);
+ public:
+
+ FILE *file;
+
+ c_file() :
+ file(0)
+ {
+ }
+ ~c_file()
+ {
+ close();
+ }
+
+ void close()
+ {
+ if(file) {
+ fclose(file);
+ file=0;
+ }
+ }
+
+ #if defined(BOOST_WINDOWS)
+
+ bool open(std::string const &file_name,std::string const &encoding)
+ {
+ close();
+
+ //
+ // Under windows we have to use "_wfopen" to get
+ // access to path's with Unicode in them
+ //
+ // As not all standard C++ libraries support nonstandard std::istream::open(wchar_t const *)
+ // we would use old and good stdio and _wfopen CRTL functions
+ //
+
+ std::wstring wfile_name = conv::to_utf<wchar_t>(file_name,encoding);
+ file = _wfopen(wfile_name.c_str(),L"rb");
+
+ return file!=0;
+ }
+
+ #else // POSIX systems do not have all this Wide API crap, as native codepages are UTF-8
+
+ // We do not use encoding as we use native file name encoding
+
+ bool open(std::string const &file_name,std::string const &/* encoding */)
+ {
+ close();
+
+ file = fopen(file_name.c_str(),"rb");
+
+ return file!=0;
+ }
+
+ #endif
+
+ };
+
+ class mo_file {
+ public:
+ typedef std::pair<char const *,char const *> pair_type;
+
+ mo_file(std::vector<char> &file) :
+ native_byteorder_(true),
+ size_(0)
+ {
+ load_file(file);
+ init();
+ }
+
+ mo_file(FILE *file) :
+ native_byteorder_(true),
+ size_(0)
+ {
+ load_file(file);
+ init();
+ }
+
+ pair_type find(char const *context_in,char const *key_in) const
+ {
+ pair_type null_pair((char const *)0,(char const *)0);
+ if(hash_size_==0)
+ return null_pair;
+ uint32_t hkey = 0;
+ if(context_in == 0)
+ hkey = pj_winberger_hash_function(key_in);
+ else {
+ pj_winberger_hash::state_type st = pj_winberger_hash::initial_state;
+ st = pj_winberger_hash::update_state(st,context_in);
+ st = pj_winberger_hash::update_state(st,'\4'); // EOT
+ st = pj_winberger_hash::update_state(st,key_in);
+ hkey = st;
+ }
+ uint32_t incr = 1 + hkey % (hash_size_-2);
+ hkey %= hash_size_;
+ uint32_t orig=hkey;
+
+
+ do {
+ uint32_t idx = get(hash_offset_ + 4*hkey);
+ /// Not found
+ if(idx == 0)
+ return null_pair;
+ /// If equal values return translation
+ if(key_equals(key(idx-1),context_in,key_in))
+ return value(idx-1);
+ /// Rehash
+ hkey=(hkey + incr) % hash_size_;
+ } while(hkey!=orig);
+ return null_pair;
+ }
+
+ static bool key_equals(char const *real_key,char const *cntx,char const *key)
+ {
+ if(cntx == 0)
+ return strcmp(real_key,key) == 0;
+ else {
+ size_t real_len = strlen(real_key);
+ size_t cntx_len = strlen(cntx);
+ size_t key_len = strlen(key);
+ if(cntx_len + 1 + key_len != real_len)
+ return false;
+ return
+ memcmp(real_key,cntx,cntx_len) == 0
+ && real_key[cntx_len] == '\4'
+ && memcmp(real_key + cntx_len + 1 ,key,key_len) == 0;
+ }
+ }
+
+ char const *key(int id) const
+ {
+ uint32_t off = get(keys_offset_ + id*8 + 4);
+ return data_ + off;
+ }
+
+ pair_type value(int id) const
+ {
+ uint32_t len = get(translations_offset_ + id*8);
+ uint32_t off = get(translations_offset_ + id*8 + 4);
+ if(off >= file_size_ || off + len >= file_size_)
+ throw std::runtime_error("Bad mo-file format");
+ return pair_type(&data_[off],&data_[off]+len);
+ }
+
+ bool has_hash() const
+ {
+ return hash_size_ != 0;
+ }
+
+ size_t size() const
+ {
+ return size_;
+ }
+
+ bool empty()
+ {
+ return size_ == 0;
+ }
+
+ private:
+ void init()
+ {
+ // Read all format sizes
+ size_=get(8);
+ keys_offset_=get(12);
+ translations_offset_=get(16);
+ hash_size_=get(20);
+ hash_offset_=get(24);
+ }
+
+ void load_file(std::vector<char> &data)
+ {
+ vdata_.swap(data);
+ file_size_ = vdata_.size();
+ data_ = &vdata_[0];
+ if(file_size_ < 4 )
+ throw std::runtime_error("invalid 'mo' file format - the file is too short");
+ uint32_t magic=0;
+ memcpy(&magic,data_,4);
+ if(magic == 0x950412de)
+ native_byteorder_ = true;
+ else if(magic == 0xde120495)
+ native_byteorder_ = false;
+ else
+ throw std::runtime_error("Invalid file format - invalid magic number");
+ }
+
+ void load_file(FILE *file)
+ {
+ uint32_t magic=0;
+ // if the size is wrong magic would be wrong
+ // ok to ingnore fread result
+ size_t four_bytes = fread(&magic,4,1,file);
+ (void)four_bytes; // shut GCC
+
+ if(magic == 0x950412de)
+ native_byteorder_ = true;
+ else if(magic == 0xde120495)
+ native_byteorder_ = false;
+ else
+ throw std::runtime_error("Invalid file format");
+
+ fseek(file,0,SEEK_END);
+ long len=ftell(file);
+ if(len < 0) {
+ throw std::runtime_error("Wrong file object");
+ }
+ fseek(file,0,SEEK_SET);
+ vdata_.resize(len+1,0); // +1 to make sure the vector is not empty
+ if(fread(&vdata_.front(),1,len,file)!=unsigned(len))
+ throw std::runtime_error("Failed to read file");
+ data_ = &vdata_[0];
+ file_size_ = len;
+ }
+
+ uint32_t get(unsigned offset) const
+ {
+ uint32_t tmp;
+ if(offset > file_size_ - 4) {
+ throw std::runtime_error("Bad mo-file format");
+ }
+ memcpy(&tmp,data_ + offset,4);
+ convert(tmp);
+ return tmp;
+ }
+
+ void convert(uint32_t &v) const
+ {
+ if(native_byteorder_)
+ return;
+ v = ((v & 0xFF) << 24)
+ | ((v & 0xFF00) << 8)
+ | ((v & 0xFF0000) >> 8)
+ | ((v & 0xFF000000) >> 24);
+ }
+
+ uint32_t keys_offset_;
+ uint32_t translations_offset_;
+ uint32_t hash_size_;
+ uint32_t hash_offset_;
+
+ char const *data_;
+ size_t file_size_;
+ std::vector<char> vdata_;
+ bool native_byteorder_;
+ size_t size_;
+ };
+
+ template<typename CharType>
+ struct mo_file_use_traits {
+ static const bool in_use = false;
+ typedef CharType char_type;
+ typedef std::pair<char_type const *,char_type const *> pair_type;
+ static pair_type use(mo_file const &/*mo*/,char_type const * /*context*/,char_type const * /*key*/)
+ {
+ return pair_type((char_type const *)(0),(char_type const *)(0));
+ }
+ };
+
+ template<>
+ struct mo_file_use_traits<char> {
+ static const bool in_use = true;
+ typedef char char_type;
+ typedef std::pair<char_type const *,char_type const *> pair_type;
+ static pair_type use(mo_file const &mo,char const *context,char const *key)
+ {
+ return mo.find(context,key);
+ }
+ };
+
+ template<typename CharType>
+ class converter {
+ public:
+ converter(std::string /*out_enc*/,std::string in_enc) :
+ in_(in_enc)
+ {
+ }
+
+ std::basic_string<CharType> operator()(char const *begin,char const *end)
+ {
+ return conv::to_utf<CharType>(begin,end,in_,conv::stop);
+ }
+
+ private:
+ std::string in_;
+ };
+
+ template<>
+ class converter<char> {
+ public:
+ converter(std::string out_enc,std::string in_enc) :
+ out_(out_enc),
+ in_(in_enc)
+ {
+ }
+
+ std::string operator()(char const *begin,char const *end)
+ {
+ return conv::between(begin,end,out_,in_,conv::stop);
+ }
+
+ private:
+ std::string out_,in_;
+ };
+
+ template<typename CharType>
+ struct message_key {
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+
+
+ message_key(string_type const &c = string_type()) :
+ c_context_(0),
+ c_key_(0)
+ {
+ size_t pos = c.find(char_type(4));
+ if(pos == string_type::npos) {
+ key_ = c;
+ }
+ else {
+ context_ = c.substr(0,pos);
+ key_ = c.substr(pos+1);
+ }
+ }
+ message_key(char_type const *c,char_type const *k) :
+ c_key_(k)
+ {
+ static const char_type empty = 0;
+ if(c!=0)
+ c_context_ = c;
+ else
+ c_context_ = &empty;
+ }
+ bool operator < (message_key const &other) const
+ {
+ int cc = compare(context(),other.context());
+ if(cc != 0)
+ return cc < 0;
+ return compare(key(),other.key()) < 0;
+ }
+ bool operator==(message_key const &other) const
+ {
+ return compare(context(),other.context()) == 0
+ && compare(key(),other.key())==0;
+ }
+ bool operator!=(message_key const &other) const
+ {
+ return !(*this==other);
+ }
+ char_type const *context() const
+ {
+ if(c_context_)
+ return c_context_;
+ return context_.c_str();
+ }
+ char_type const *key() const
+ {
+ if(c_key_)
+ return c_key_;
+ return key_.c_str();
+ }
+ private:
+ static int compare(char_type const *l,char_type const *r)
+ {
+ typedef std::char_traits<char_type> traits_type;
+ for(;;) {
+ char_type cl = *l++;
+ char_type cr = *r++;
+ if(cl == 0 && cr == 0)
+ return 0;
+ if(traits_type::lt(cl,cr))
+ return -1;
+ if(traits_type::lt(cr,cl))
+ return 1;
+ }
+ }
+ string_type context_;
+ string_type key_;
+ char_type const *c_context_;
+ char_type const *c_key_;
+ };
+
+ template<typename CharType>
+ struct hash_function {
+ size_t operator()(message_key<CharType> const &msg) const
+ {
+ pj_winberger_hash::state_type state = pj_winberger_hash::initial_state;
+ CharType const *p = msg.context();
+ if(*p != 0) {
+ CharType const *e = p;
+ while(*e)
+ e++;
+ state = pj_winberger_hash::update_state(state,
+ reinterpret_cast<char const *>(p),
+ reinterpret_cast<char const *>(e));
+ state = pj_winberger_hash::update_state(state,'\4');
+ }
+ p = msg.key();
+ CharType const *e = p;
+ while(*e)
+ e++;
+ state = pj_winberger_hash::update_state(state,
+ reinterpret_cast<char const *>(p),
+ reinterpret_cast<char const *>(e));
+ return state;
+ }
+ };
+
+
+ // By default for wide types the conversion is not requiredyy
+ template<typename CharType>
+ CharType const *runtime_conversion(CharType const *msg,
+ std::basic_string<CharType> &/*buffer*/,
+ bool /*do_conversion*/,
+ std::string const &/*locale_encoding*/,
+ std::string const &/*key_encoding*/)
+ {
+ return msg;
+ }
+
+ // But still need to specialize for char
+ template<>
+ char const *runtime_conversion( char const *msg,
+ std::string &buffer,
+ bool do_conversion,
+ std::string const &locale_encoding,
+ std::string const &key_encoding)
+ {
+ if(!do_conversion)
+ return msg;
+ if(details::is_us_ascii_string(msg))
+ return msg;
+ std::string tmp = conv::between(msg,locale_encoding,key_encoding,conv::skip);
+ buffer.swap(tmp);
+ return buffer.c_str();
+ }
+
+ template<typename CharType>
+ class mo_message : public message_format<CharType> {
+
+ typedef CharType char_type;
+ typedef std::basic_string<CharType> string_type;
+ typedef message_key<CharType> key_type;
+ #ifdef BOOST_LOCALE_UNORDERED_CATALOG
+ typedef boost::unordered_map<key_type,string_type,hash_function<CharType> > catalog_type;
+ #else
+ typedef std::map<key_type,string_type> catalog_type;
+ #endif
+ typedef std::vector<catalog_type> catalogs_set_type;
+ typedef std::map<std::string,int> domains_map_type;
+ public:
+
+ typedef std::pair<CharType const *,CharType const *> pair_type;
+
+ virtual char_type const *get(int domain_id,char_type const *context,char_type const *id) const
+ {
+ return get_string(domain_id,context,id).first;
+ }
+
+ virtual char_type const *get(int domain_id,char_type const *context,char_type const *single_id,int n) const
+ {
+ pair_type ptr = get_string(domain_id,context,single_id);
+ if(!ptr.first)
+ return 0;
+ int form=0;
+ if(plural_forms_.at(domain_id))
+ form = (*plural_forms_[domain_id])(n);
+ else
+ form = n == 1 ? 0 : 1; // Fallback to english plural form
+
+ CharType const *p=ptr.first;
+ for(int i=0;p < ptr.second && i<form;i++) {
+ p=std::find(p,ptr.second,0);
+ if(p==ptr.second)
+ return 0;
+ ++p;
+ }
+ if(p>=ptr.second)
+ return 0;
+ return p;
+ }
+
+ virtual int domain(std::string const &domain) const
+ {
+ domains_map_type::const_iterator p=domains_.find(domain);
+ if(p==domains_.end())
+ return -1;
+ return p->second;
+ }
+
+ mo_message(messages_info const &inf)
+ {
+ std::string language = inf.language;
+ std::string variant = inf.variant;
+ std::string country = inf.country;
+ std::string encoding = inf.encoding;
+ std::string lc_cat = inf.locale_category;
+ std::vector<messages_info::domain> const &domains = inf.domains;
+ std::vector<std::string> const &search_paths = inf.paths;
+
+ //
+ // List of fallbacks: en_US@euro, en@euro, en_US, en.
+ //
+ std::vector<std::string> paths;
+
+
+ if(!variant.empty() && !country.empty())
+ paths.push_back(language + "_" + country + "@" + variant);
+
+ if(!variant.empty())
+ paths.push_back(language + "@" + variant);
+
+ if(!country.empty())
+ paths.push_back(language + "_" + country);
+
+ paths.push_back(language);
+
+ catalogs_.resize(domains.size());
+ mo_catalogs_.resize(domains.size());
+ plural_forms_.resize(domains.size());
+
+
+ for(unsigned id=0;id<domains.size();id++) {
+ std::string domain=domains[id].name;
+ std::string key_encoding = domains[id].encoding;
+ domains_[domain]=id;
+
+
+ bool found=false;
+ for(unsigned j=0;!found && j<paths.size();j++) {
+ for(unsigned i=0;!found && i<search_paths.size();i++) {
+ std::string full_path = search_paths[i]+"/"+paths[j]+"/" + lc_cat + "/"+domain+".mo";
+ found = load_file(full_path,encoding,key_encoding,id,inf.callback);
+ }
+ }
+ }
+ }
+
+ char_type const *convert(char_type const *msg,string_type &buffer) const
+ {
+ return runtime_conversion<char_type>(msg,buffer,key_conversion_required_,locale_encoding_,key_encoding_);
+ }
+
+ virtual ~mo_message()
+ {
+ }
+
+ private:
+ int compare_encodings(std::string const &left,std::string const &right)
+ {
+ return convert_encoding_name(left).compare(convert_encoding_name(right));
+ }
+
+ std::string convert_encoding_name(std::string const &in)
+ {
+ std::string result;
+ for(unsigned i=0;i<in.size();i++) {
+ char c=in[i];
+ if('A' <= c && c<='Z')
+ c=c-'A' + 'a';
+ else if(('a' <= c && c<='z') || ('0' <= c && c<='9'))
+ ;
+ else
+ continue;
+ result+=c;
+ }
+ return result;
+ }
+
+
+ bool load_file( std::string const &file_name,
+ std::string const &locale_encoding,
+ std::string const &key_encoding,
+ int id,
+ messages_info::callback_type const &callback)
+ {
+ locale_encoding_ = locale_encoding;
+ key_encoding_ = key_encoding;
+
+ key_conversion_required_ = sizeof(CharType) == 1
+ && compare_encodings(locale_encoding,key_encoding)!=0;
+
+ boost::shared_ptr<mo_file> mo;
+
+ if(callback) {
+ std::vector<char> vfile = callback(file_name,locale_encoding);
+ if(vfile.empty())
+ return false;
+ mo.reset(new mo_file(vfile));
+ }
+ else {
+ c_file the_file;
+ the_file.open(file_name,locale_encoding);
+ if(!the_file.file)
+ return false;
+ mo.reset(new mo_file(the_file.file));
+ }
+
+ std::string plural = extract(mo->value(0).first,"plural=","\r\n;");
+
+ std::string mo_encoding = extract(mo->value(0).first,"charset="," \r\n;");
+
+ if(mo_encoding.empty())
+ throw std::runtime_error("Invalid mo-format, encoding is not specified");
+
+ if(!plural.empty()) {
+ plural_forms_[id] = lambda::compile(plural.c_str());;
+ }
+
+ if( mo_useable_directly(mo_encoding,*mo) )
+ {
+ mo_catalogs_[id]=mo;
+ }
+ else {
+ converter<CharType> cvt_value(locale_encoding,mo_encoding);
+ converter<CharType> cvt_key(key_encoding,mo_encoding);
+ for(unsigned i=0;i<mo->size();i++) {
+ char const *ckey = mo->key(i);
+ string_type skey = cvt_key(ckey,ckey+strlen(ckey));
+ key_type key(skey);
+
+ mo_file::pair_type tmp = mo->value(i);
+ string_type value = cvt_value(tmp.first,tmp.second);
+ catalogs_[id][key].swap(value);
+ }
+ }
+ return true;
+
+ }
+
+ // Check if the mo file as-is is useful
+ // 1. It is char and not wide character
+ // 2. The locale encoding and mo encoding is same
+ // 3. The source strings encoding and mo encoding is same or all
+ // mo key strings are US-ASCII
+ bool mo_useable_directly( std::string const &mo_encoding,
+ mo_file const &mo)
+ {
+ if(sizeof(CharType) != 1)
+ return false;
+ if(!mo.has_hash())
+ return false;
+ if(compare_encodings(mo_encoding,locale_encoding_)!=0)
+ return false;
+ if(compare_encodings(mo_encoding,key_encoding_)==0) {
+ return true;
+ }
+ for(unsigned i=0;i<mo.size();i++) {
+ if(!details::is_us_ascii_string(mo.key(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+
+ static std::string extract(std::string const &meta,std::string const &key,char const *separator)
+ {
+ size_t pos=meta.find(key);
+ if(pos == std::string::npos)
+ return "";
+ pos+=key.size(); /// size of charset=
+ size_t end_pos = meta.find_first_of(separator,pos);
+ return meta.substr(pos,end_pos - pos);
+ }
+
+
+
+
+ pair_type get_string(int domain_id,char_type const *context,char_type const *in_id) const
+ {
+ pair_type null_pair((CharType const *)0,(CharType const *)0);
+ if(domain_id < 0 || size_t(domain_id) >= catalogs_.size())
+ return null_pair;
+ if(mo_file_use_traits<char_type>::in_use && mo_catalogs_[domain_id]) {
+ return mo_file_use_traits<char_type>::use(*mo_catalogs_[domain_id],context,in_id);
+ }
+ else {
+ key_type key(context,in_id);
+ catalog_type const &cat = catalogs_[domain_id];
+ typename catalog_type::const_iterator p = cat.find(key);
+ if(p==cat.end()) {
+ return null_pair;
+ }
+ return pair_type(p->second.data(),p->second.data()+p->second.size());
+ }
+ }
+
+ catalogs_set_type catalogs_;
+ std::vector<boost::shared_ptr<mo_file> > mo_catalogs_;
+ std::vector<boost::shared_ptr<lambda::plural> > plural_forms_;
+ domains_map_type domains_;
+
+ std::string locale_encoding_;
+ std::string key_encoding_;
+ bool key_conversion_required_;
+ };
+
+ template<>
+ message_format<char> *create_messages_facet(messages_info const &info)
+ {
+ return new mo_message<char>(info);
+ }
+
+ template<>
+ message_format<wchar_t> *create_messages_facet(messages_info const &info)
+ {
+ return new mo_message<wchar_t>(info);
+ }
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+
+ template<>
+ message_format<char16_t> *create_messages_facet(messages_info const &info)
+ {
+ return new mo_message<char16_t>(info);
+ }
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+
+ template<>
+ message_format<char32_t> *create_messages_facet(messages_info const &info)
+ {
+ return new mo_message<char32_t>(info);
+ }
+ #endif
+
+
+ } /// gnu_gettext
+
+ } // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/shared/mo_hash.hpp b/src/boost/libs/locale/src/shared/mo_hash.hpp
new file mode 100644
index 000000000..d8c8f69c3
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/mo_hash.hpp
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/cstdint.hpp>
+
+namespace boost {
+ namespace locale {
+ namespace gnu_gettext {
+
+ struct pj_winberger_hash {
+
+ typedef uint32_t state_type;
+
+ static const state_type initial_state = 0;
+
+ static state_type update_state(state_type value,char c)
+ {
+ value = (value << 4) + static_cast<unsigned char>(c);
+ uint32_t high = (value & 0xF0000000U);
+ if(high!=0)
+ value = (value ^ (high >> 24)) ^ high;
+ return value;
+ }
+ static state_type update_state(state_type value,char const *ptr)
+ {
+ while(*ptr)
+ value = update_state(value,*ptr++);
+ return value;
+ }
+ static state_type update_state(state_type value,char const *begin,char const *end)
+ {
+ while(begin!=end)
+ value = update_state(value,*begin++);
+ return value;
+ }
+ };
+
+ inline pj_winberger_hash::state_type pj_winberger_hash_function(char const *ptr)
+ {
+ pj_winberger_hash::state_type state = pj_winberger_hash::initial_state;
+ state = pj_winberger_hash::update_state(state,ptr);
+ return state;
+ }
+
+ inline pj_winberger_hash::state_type pj_winberger_hash_function(char const *begin,char const *end)
+ {
+ pj_winberger_hash::state_type state = pj_winberger_hash::initial_state;
+ state = pj_winberger_hash::update_state(state,begin,end);
+ return state;
+ }
+ }
+ }
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/shared/mo_lambda.cpp b/src/boost/libs/locale/src/shared/mo_lambda.cpp
new file mode 100644
index 000000000..ab4bb0d8e
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/mo_lambda.cpp
@@ -0,0 +1,411 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include "mo_lambda.hpp"
+#include <string.h>
+#include <stdlib.h>
+
+namespace boost {
+namespace locale {
+namespace gnu_gettext {
+namespace lambda {
+
+namespace { // anon
+ struct identity : public plural {
+ virtual int operator()(int n) const
+ {
+ return n;
+ };
+ virtual identity *clone() const
+ {
+ return new identity();
+ }
+ };
+
+ struct unary : public plural
+ {
+ unary(plural_ptr ptr) :
+ op1(ptr)
+ {
+ }
+ protected:
+ plural_ptr op1;
+ };
+
+
+ struct binary : public plural
+ {
+ binary(plural_ptr p1,plural_ptr p2) :
+ op1(p1),
+ op2(p2)
+ {
+ }
+ protected:
+ plural_ptr op1,op2;
+ };
+
+ struct number : public plural
+ {
+ number(int v) :
+ val(v)
+ {
+ }
+ virtual int operator()(int /*n*/) const
+ {
+ return val;
+ }
+ virtual number *clone() const
+ {
+ return new number(val);
+ }
+
+ private:
+ int val;
+ };
+
+ #define UNOP(name,oper) \
+ struct name: public unary { \
+ name(plural_ptr op) : unary(op) \
+ { \
+ }; \
+ virtual int operator()(int n) const \
+ { \
+ return oper (*op1)(n); \
+ } \
+ virtual name *clone() const \
+ { \
+ plural_ptr op1_copy(op1->clone()); \
+ return new name(op1_copy); \
+ } \
+ };
+
+ #define BINOP(name,oper) \
+ struct name : public binary \
+ { \
+ name(plural_ptr p1,plural_ptr p2) : \
+ binary(p1,p2) \
+ { \
+ } \
+ \
+ virtual int operator()(int n) const \
+ { \
+ return (*op1)(n) oper (*op2)(n); \
+ } \
+ virtual name *clone() const \
+ { \
+ plural_ptr op1_copy(op1->clone()); \
+ plural_ptr op2_copy(op2->clone()); \
+ return new name(op1_copy,op2_copy); \
+ } \
+ };
+
+ #define BINOPD(name,oper) \
+ struct name : public binary { \
+ name(plural_ptr p1,plural_ptr p2) : \
+ binary(p1,p2) \
+ { \
+ } \
+ virtual int operator()(int n) const \
+ { \
+ int v1=(*op1)(n); \
+ int v2=(*op2)(n); \
+ return v2==0 ? 0 : v1 oper v2; \
+ } \
+ virtual name *clone() const \
+ { \
+ plural_ptr op1_copy(op1->clone()); \
+ plural_ptr op2_copy(op2->clone()); \
+ return new name(op1_copy,op2_copy); \
+ } \
+ };
+
+ enum { END = 0 , SHL = 256, SHR, GTE,LTE, EQ, NEQ, AND, OR, NUM, VARIABLE };
+
+ UNOP(l_not,!)
+ UNOP(minus,-)
+ UNOP(bin_not,~)
+
+ BINOP(mul,*)
+ BINOPD(div,/)
+ BINOPD(mod,%)
+ static int level10[]={3,'*','/','%'};
+
+ BINOP(add,+)
+ BINOP(sub,-)
+ static int level9[]={2,'+','-'};
+
+ BINOP(shl,<<)
+ BINOP(shr,>>)
+ static int level8[]={2,SHL,SHR};
+
+ BINOP(gt,>)
+ BINOP(lt,<)
+ BINOP(gte,>=)
+ BINOP(lte,<=)
+ static int level7[]={4,'<','>',GTE,LTE};
+
+ BINOP(eq,==)
+ BINOP(neq,!=)
+ static int level6[]={2,EQ,NEQ};
+
+ BINOP(bin_and,&)
+ static int level5[]={1,'&'};
+
+ BINOP(bin_xor,^)
+ static int level4[]={1,'^'};
+
+ BINOP(bin_or,|)
+ static int level3[]={1,'|'};
+
+ BINOP(l_and,&&)
+ static int level2[]={1,AND};
+
+ BINOP(l_or,||)
+ static int level1[]={1,OR};
+
+ struct conditional : public plural {
+ conditional(plural_ptr p1,plural_ptr p2,plural_ptr p3) :
+ op1(p1),
+ op2(p2),
+ op3(p3)
+ {
+ }
+ virtual int operator()(int n) const
+ {
+ return (*op1)(n) ? (*op2)(n) : (*op3)(n);
+ }
+ virtual conditional *clone() const
+ {
+ plural_ptr op1_copy(op1->clone());
+ plural_ptr op2_copy(op2->clone());
+ plural_ptr op3_copy(op3->clone());
+ return new conditional(op1_copy,op2_copy,op3_copy);
+ }
+ private:
+ plural_ptr op1,op2,op3;
+ };
+
+
+ plural_ptr bin_factory(int value,plural_ptr left,plural_ptr right)
+ {
+
+ switch(value) {
+ case '/': return plural_ptr(new div(left,right));
+ case '*': return plural_ptr(new mul(left,right));
+ case '%': return plural_ptr(new mod(left,right));
+ case '+': return plural_ptr(new add(left,right));
+ case '-': return plural_ptr(new sub(left,right));
+ case SHL: return plural_ptr(new shl(left,right));
+ case SHR: return plural_ptr(new shr(left,right));
+ case '>': return plural_ptr(new gt(left,right));
+ case '<': return plural_ptr(new lt(left,right));
+ case GTE: return plural_ptr(new gte(left,right));
+ case LTE: return plural_ptr(new lte(left,right));
+ case EQ: return plural_ptr(new eq(left,right));
+ case NEQ: return plural_ptr(new neq(left,right));
+ case '&': return plural_ptr(new bin_and(left,right));
+ case '^': return plural_ptr(new bin_xor(left,right));
+ case '|': return plural_ptr(new bin_or (left,right));
+ case AND: return plural_ptr(new l_and(left,right));
+ case OR: return plural_ptr(new l_or(left,right));
+ default:
+ return plural_ptr();
+ }
+ }
+
+ static inline bool is_in(int v,int *p)
+ {
+ int len=*p;
+ p++;
+ while(len && *p!=v) { p++;len--; }
+ return len!=0;
+ }
+
+
+ class tokenizer {
+ public:
+ tokenizer(char const *s) { text=s; pos=0; step(); };
+ int get(int *val=NULL){
+ int iv=int_value;
+ int res=next_tocken;
+ step();
+ if(val && res==NUM){
+ *val=iv;
+ }
+ return res;
+ };
+ int next(int *val=NULL) {
+ if(val && next_tocken==NUM) {
+ *val=int_value;
+ return NUM;
+ }
+ return next_tocken;
+ }
+ private:
+ char const *text;
+ int pos;
+ int next_tocken;
+ int int_value;
+ bool is_blank(char c)
+ {
+ return c==' ' || c=='\r' || c=='\n' || c=='\t';
+ }
+ bool isdigit(char c)
+ {
+ return '0'<=c && c<='9';
+ }
+ void step()
+ {
+ while(text[pos] && is_blank(text[pos])) pos++;
+ char const *ptr=text+pos;
+ char *tmp_ptr;
+ if(strncmp(ptr,"<<",2)==0) { pos+=2; next_tocken=SHL; }
+ else if(strncmp(ptr,">>",2)==0) { pos+=2; next_tocken=SHR; }
+ else if(strncmp(ptr,"&&",2)==0) { pos+=2; next_tocken=AND; }
+ else if(strncmp(ptr,"||",2)==0) { pos+=2; next_tocken=OR; }
+ else if(strncmp(ptr,"<=",2)==0) { pos+=2; next_tocken=LTE; }
+ else if(strncmp(ptr,">=",2)==0) { pos+=2; next_tocken=GTE; }
+ else if(strncmp(ptr,"==",2)==0) { pos+=2; next_tocken=EQ; }
+ else if(strncmp(ptr,"!=",2)==0) { pos+=2; next_tocken=NEQ; }
+ else if(*ptr=='n') { pos++; next_tocken=VARIABLE; }
+ else if(isdigit(*ptr)) { int_value=strtol(text+pos,&tmp_ptr,0); pos=tmp_ptr-text; next_tocken=NUM; }
+ else if(*ptr=='\0') { next_tocken=0; }
+ else { next_tocken=*ptr; pos++; }
+ }
+ };
+
+
+ #define BINARY_EXPR(expr,hexpr,list) \
+ plural_ptr expr() \
+ { \
+ plural_ptr op1,op2; \
+ if((op1=hexpr()).get()==0) \
+ return plural_ptr(); \
+ while(is_in(t.next(),list)) { \
+ int o=t.get(); \
+ if((op2=hexpr()).get()==0) \
+ return plural_ptr(); \
+ op1=bin_factory(o,op1,op2); \
+ } \
+ return op1; \
+ }
+
+ class parser {
+ public:
+
+ parser(tokenizer &tin) : t(tin) {};
+
+ plural_ptr compile()
+ {
+ plural_ptr res=cond_expr();
+ if(res.get() && t.next()!=END) {
+ return plural_ptr();
+ };
+ return res;
+ }
+
+ private:
+
+ plural_ptr value_expr()
+ {
+ plural_ptr op;
+ if(t.next()=='(') {
+ t.get();
+ if((op=cond_expr()).get()==0)
+ return plural_ptr();
+ if(t.get()!=')')
+ return plural_ptr();
+ return op;
+ }
+ else if(t.next()==NUM) {
+ int value;
+ t.get(&value);
+ return plural_ptr(new number(value));
+ }
+ else if(t.next()==VARIABLE) {
+ t.get();
+ return plural_ptr(new identity());
+ }
+ return plural_ptr();
+ };
+
+ plural_ptr un_expr()
+ {
+ plural_ptr op1;
+ static int level_unary[]={3,'-','!','~'};
+ if(is_in(t.next(),level_unary)) {
+ int op=t.get();
+ if((op1=un_expr()).get()==0)
+ return plural_ptr();
+ switch(op) {
+ case '-':
+ return plural_ptr(new minus(op1));
+ case '!':
+ return plural_ptr(new l_not(op1));
+ case '~':
+ return plural_ptr(new bin_not(op1));
+ default:
+ return plural_ptr();
+ }
+ }
+ else {
+ return value_expr();
+ }
+ };
+
+ BINARY_EXPR(l10,un_expr,level10);
+ BINARY_EXPR(l9,l10,level9);
+ BINARY_EXPR(l8,l9,level8);
+ BINARY_EXPR(l7,l8,level7);
+ BINARY_EXPR(l6,l7,level6);
+ BINARY_EXPR(l5,l6,level5);
+ BINARY_EXPR(l4,l5,level4);
+ BINARY_EXPR(l3,l4,level3);
+ BINARY_EXPR(l2,l3,level2);
+ BINARY_EXPR(l1,l2,level1);
+
+ plural_ptr cond_expr()
+ {
+ plural_ptr cond,case1,case2;
+ if((cond=l1()).get()==0)
+ return plural_ptr();
+ if(t.next()=='?') {
+ t.get();
+ if((case1=cond_expr()).get()==0)
+ return plural_ptr();
+ if(t.get()!=':')
+ return plural_ptr();
+ if((case2=cond_expr()).get()==0)
+ return plural_ptr();
+ }
+ else {
+ return cond;
+ }
+ return plural_ptr(new conditional(cond,case1,case2));
+ }
+
+ tokenizer &t;
+
+ };
+
+} // namespace anon
+
+plural_ptr compile(char const *str)
+{
+ tokenizer t(str);
+ parser p(t);
+ return p.compile();
+}
+
+
+} // lambda
+} // gnu_gettext
+} // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/shared/mo_lambda.hpp b/src/boost/libs/locale/src/shared/mo_lambda.hpp
new file mode 100644
index 000000000..c14afd077
--- /dev/null
+++ b/src/boost/libs/locale/src/shared/mo_lambda.hpp
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_SRC_LOCALE_MO_LAMBDA_HPP_INCLUDED
+#define BOOST_SRC_LOCALE_MO_LAMBDA_HPP_INCLUDED
+
+#include <boost/shared_ptr.hpp>
+
+namespace boost {
+ namespace locale {
+ namespace gnu_gettext {
+ namespace lambda {
+
+ struct plural {
+
+ virtual int operator()(int n) const = 0;
+ virtual plural *clone() const = 0;
+ virtual ~plural()
+ {
+ }
+ };
+
+ typedef boost::shared_ptr<plural> plural_ptr;
+
+ plural_ptr compile(char const *c_expression);
+
+ } // lambda
+ } // gnu_gettext
+ } // locale
+} // boost
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/std/all_generator.hpp b/src/boost/libs/locale/src/std/all_generator.hpp
new file mode 100644
index 000000000..d79525b71
--- /dev/null
+++ b/src/boost/libs/locale/src/std/all_generator.hpp
@@ -0,0 +1,54 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_STD_ALL_GENERATOR_HPP
+#define BOOST_LOCALE_IMPL_STD_ALL_GENERATOR_HPP
+
+#include <boost/locale/generator.hpp>
+#include <vector>
+
+namespace boost {
+ namespace locale {
+ namespace impl_std {
+ typedef enum {
+ utf8_none,
+ utf8_native,
+ utf8_native_with_wide,
+ utf8_from_wide
+ } utf8_support;
+
+ std::locale create_convert( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf = utf8_none);
+
+ std::locale create_collate( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf = utf8_none);
+
+ std::locale create_formatting( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf = utf8_none);
+
+ std::locale create_parsing( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf = utf8_none);
+
+ std::locale create_codecvt( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf = utf8_none);
+
+ }
+ }
+}
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/std/codecvt.cpp b/src/boost/libs/locale/src/std/codecvt.cpp
new file mode 100644
index 000000000..9b62d2f4f
--- /dev/null
+++ b/src/boost/libs/locale/src/std/codecvt.cpp
@@ -0,0 +1,55 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <locale>
+#include <boost/cstdint.hpp>
+#include <boost/locale/util.hpp>
+#include "all_generator.hpp"
+#include <vector>
+namespace boost {
+namespace locale {
+namespace impl_std {
+ template<typename CharType>
+ std::locale codecvt_bychar( std::locale const &in,
+ std::string const &locale_name)
+ {
+ return std::locale(in,new std::codecvt_byname<CharType,char,std::mbstate_t>(locale_name.c_str()));
+ }
+
+
+ std::locale create_codecvt( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf)
+ {
+ if(utf == utf8_from_wide) {
+ return util::create_utf8_codecvt(in,type);
+ }
+ switch(type) {
+ case char_facet:
+ return codecvt_bychar<char>(in,locale_name);
+ case wchar_t_facet:
+ return codecvt_bychar<wchar_t>(in,locale_name);
+ #if defined(BOOST_LOCALE_ENABLE_CHAR16_T) && !defined(BOOST_NO_CHAR16_T_CODECVT)
+ case char16_t_facet:
+ return codecvt_bychar<char16_t>(in,locale_name);
+ #endif
+ #if defined(BOOST_LOCALE_ENABLE_CHAR32_T) && !defined(BOOST_NO_CHAR32_T_CODECVT)
+ case char32_t_facet:
+ return codecvt_bychar<char32_t>(in,locale_name);
+ #endif
+ default:
+ return in;
+ }
+ }
+
+} // impl_std
+} // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/std/collate.cpp b/src/boost/libs/locale/src/std/collate.cpp
new file mode 100644
index 000000000..8b7127ad7
--- /dev/null
+++ b/src/boost/libs/locale/src/std/collate.cpp
@@ -0,0 +1,113 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <locale>
+#include <string>
+#include <ios>
+#include <boost/locale/encoding.hpp>
+#include "all_generator.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_std {
+
+class utf8_collator_from_wide : public std::collate<char> {
+public:
+ typedef std::collate<wchar_t> wfacet;
+ utf8_collator_from_wide(std::locale const &base,size_t refs = 0) :
+ std::collate<char>(refs),
+ base_(base)
+ {
+ }
+ virtual int do_compare(char const *lb,char const *le,char const *rb,char const *re) const
+ {
+ std::wstring l=conv::to_utf<wchar_t>(lb,le,"UTF-8");
+ std::wstring r=conv::to_utf<wchar_t>(rb,re,"UTF-8");
+ return std::use_facet<wfacet>(base_).compare( l.c_str(),l.c_str()+l.size(),
+ r.c_str(),r.c_str()+r.size());
+ }
+ virtual long do_hash(char const *b,char const *e) const
+ {
+ std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8");
+ return std::use_facet<wfacet>(base_).hash(tmp.c_str(),tmp.c_str()+tmp.size());
+ }
+ virtual std::string do_transform(char const *b,char const *e) const
+ {
+ std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8");
+ std::wstring wkey =
+ std::use_facet<wfacet>(base_).transform(tmp.c_str(),tmp.c_str()+tmp.size());
+ std::string key;
+ if(sizeof(wchar_t)==2)
+ key.reserve(wkey.size()*2);
+ else
+ key.reserve(wkey.size()*3);
+ for(unsigned i=0;i<wkey.size();i++) {
+ if(sizeof(wchar_t)==2) {
+ uint16_t tv = static_cast<uint16_t>(wkey[i]);
+ key += char(tv >> 8);
+ key += char(tv & 0xFF);
+ }
+ else { // 4
+ uint32_t tv = static_cast<uint32_t>(wkey[i]);
+ // 21 bit
+ key += char((tv >> 16) & 0xFF);
+ key += char((tv >> 8) & 0xFF);
+ key += char(tv & 0xFF);
+ }
+ }
+ return key;
+ }
+private:
+ std::locale base_;
+};
+
+std::locale create_collate( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf)
+{
+ switch(type) {
+ case char_facet:
+ {
+ if(utf == utf8_from_wide) {
+ std::locale base=
+ std::locale(std::locale::classic(),
+ new std::collate_byname<wchar_t>(locale_name.c_str()));
+ return std::locale(in,new utf8_collator_from_wide(base));
+ }
+ else
+ {
+ return std::locale(in,new std::collate_byname<char>(locale_name.c_str()));
+ }
+ }
+
+ case wchar_t_facet:
+ return std::locale(in,new std::collate_byname<wchar_t>(locale_name.c_str()));
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ return std::locale(in,new std::collate_byname<char16_t>(locale_name.c_str()));
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ return std::locale(in,new std::collate_byname<char32_t>(locale_name.c_str()));
+ #endif
+ default:
+ return in;
+ }
+}
+
+
+} // impl_std
+} // locale
+} //boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/std/converter.cpp b/src/boost/libs/locale/src/std/converter.cpp
new file mode 100644
index 000000000..e4f925ade
--- /dev/null
+++ b/src/boost/libs/locale/src/std/converter.cpp
@@ -0,0 +1,148 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+
+#include <boost/config.hpp>
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4996)
+#endif
+
+#include <locale>
+#include <stdexcept>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/encoding.hpp>
+#include <vector>
+
+
+
+#include "all_generator.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_std {
+
+
+template<typename CharType>
+class std_converter : public converter<CharType>
+{
+public:
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+ typedef std::ctype<char_type> ctype_type;
+ std_converter(std::locale const &base,size_t refs = 0) :
+ converter<CharType>(refs),
+ base_(base)
+ {
+ }
+ virtual string_type convert(converter_base::conversion_type how,char_type const *begin,char_type const *end,int /*flags*/ = 0) const
+ {
+ switch(how) {
+ case converter_base::upper_case:
+ case converter_base::lower_case:
+ case converter_base::case_folding:
+ {
+ ctype_type const &ct=std::use_facet<ctype_type>(base_);
+ size_t len = end - begin;
+ std::vector<char_type> res(len+1,0);
+ char_type *lbegin = &res[0];
+ std::copy(begin,end,lbegin);
+ if(how == converter_base::upper_case)
+ ct.toupper(lbegin,lbegin+len);
+ else
+ ct.tolower(lbegin,lbegin+len);
+ return string_type(lbegin,len);
+ }
+ default:
+ return string_type(begin,end-begin);
+ }
+ }
+private:
+ std::locale base_;
+};
+
+class utf8_converter : public converter<char> {
+public:
+ typedef std::ctype<char> ctype_type;
+ typedef std::ctype<wchar_t> wctype_type;
+ utf8_converter(std::locale const &base,size_t refs = 0) :
+ converter<char>(refs),
+ base_(base)
+ {
+ }
+ virtual std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int /*flags*/ = 0) const
+ {
+ switch(how) {
+ case upper_case:
+ case lower_case:
+ case case_folding:
+ {
+ std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8");
+ wctype_type const &ct=std::use_facet<wctype_type>(base_);
+ size_t len = tmp.size();
+ std::vector<wchar_t> res(len+1,0);
+ wchar_t *lbegin = &res[0];
+ std::copy(tmp.c_str(),tmp.c_str()+len,lbegin);
+ if(how == upper_case)
+ ct.toupper(lbegin,lbegin+len);
+ else
+ ct.tolower(lbegin,lbegin+len);
+ return conv::from_utf<wchar_t>(lbegin,lbegin+len,"UTF-8");
+ }
+ default:
+ return std::string(begin,end-begin);
+ }
+ }
+private:
+ std::locale base_;
+};
+
+std::locale create_convert( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf)
+{
+ switch(type) {
+ case char_facet:
+ {
+ if(utf == utf8_native_with_wide || utf == utf8_from_wide) {
+ std::locale base(std::locale::classic(),new std::ctype_byname<wchar_t>(locale_name.c_str()));
+ return std::locale(in,new utf8_converter(base));
+ }
+ std::locale base(std::locale::classic(),new std::ctype_byname<char>(locale_name.c_str()));
+ return std::locale(in,new std_converter<char>(base));
+ }
+ case wchar_t_facet:
+ {
+ std::locale base(std::locale::classic(),new std::ctype_byname<wchar_t>(locale_name.c_str()));
+ return std::locale(in,new std_converter<wchar_t>(base));
+ }
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ {
+ std::locale base(std::locale::classic(),new std::ctype_byname<char16_t>(locale_name.c_str()));
+ return std::locale(in,new std_converter<char16_t>(base));
+ }
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ {
+ std::locale base(std::locale::classic(),new std::ctype_byname<char32_t>(locale_name.c_str()));
+ return std::locale(in,new std_converter<char32_t>(base));
+ }
+ #endif
+ default:
+ return in;
+ }
+}
+
+
+} // namespace impl_std
+} // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/std/numeric.cpp b/src/boost/libs/locale/src/std/numeric.cpp
new file mode 100644
index 000000000..cbb0d9de3
--- /dev/null
+++ b/src/boost/libs/locale/src/std/numeric.cpp
@@ -0,0 +1,456 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <locale>
+#include <string>
+#include <ios>
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/encoding.hpp>
+#include <sstream>
+#include <stdlib.h>
+
+#include "../util/numeric.hpp"
+#include "all_generator.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_std {
+
+template<typename CharType>
+class time_put_from_base : public std::time_put<CharType> {
+public:
+ time_put_from_base(std::locale const &base, size_t refs = 0) :
+ std::time_put<CharType>(refs),
+ base_(base)
+ {
+ }
+ typedef typename std::time_put<CharType>::iter_type iter_type;
+
+ virtual iter_type do_put(iter_type out,std::ios_base &/*ios*/,CharType fill,std::tm const *tm,char format,char modifier) const
+ {
+ std::basic_stringstream<CharType> ss;
+ ss.imbue(base_);
+ return std::use_facet<std::time_put<CharType> >(base_).put(out,ss,fill,tm,format,modifier);
+ }
+private:
+ std::locale base_;
+};
+
+class utf8_time_put_from_wide : public std::time_put<char> {
+public:
+ utf8_time_put_from_wide(std::locale const &base, size_t refs = 0) :
+ std::time_put<char>(refs),
+ base_(base)
+ {
+ }
+ virtual iter_type do_put(iter_type out,std::ios_base &/*ios*/,char fill,std::tm const *tm,char format,char modifier = 0) const
+ {
+ std::basic_ostringstream<wchar_t> wtmps;
+ wtmps.imbue(base_);
+ std::use_facet<std::time_put<wchar_t> >(base_).put(wtmps,wtmps,wchar_t(fill),tm,wchar_t(format),wchar_t(modifier));
+ std::wstring wtmp=wtmps.str();
+ std::string const tmp = conv::from_utf<wchar_t>(wtmp,"UTF-8");
+ for(unsigned i=0;i<tmp.size();i++) {
+ *out++ = tmp[i];
+ }
+ return out;
+ }
+private:
+ std::locale base_;
+};
+
+class utf8_numpunct_from_wide : public std::numpunct<char> {
+public:
+ utf8_numpunct_from_wide(std::locale const &base,size_t refs = 0) : std::numpunct<char>(refs)
+ {
+ typedef std::numpunct<wchar_t> wfacet_type;
+ wfacet_type const &wfacet = std::use_facet<wfacet_type>(base);
+
+ truename_ = conv::from_utf<wchar_t>(wfacet.truename(),"UTF-8");
+ falsename_ = conv::from_utf<wchar_t>(wfacet.falsename(),"UTF-8");
+
+ wchar_t tmp_decimal_point = wfacet.decimal_point();
+ wchar_t tmp_thousands_sep = wfacet.thousands_sep();
+ std::string tmp_grouping = wfacet.grouping();
+
+ if( 32 <= tmp_thousands_sep && tmp_thousands_sep <=126 &&
+ 32 <= tmp_decimal_point && tmp_decimal_point <=126)
+ {
+ thousands_sep_ = static_cast<char>(tmp_thousands_sep);
+ decimal_point_ = static_cast<char>(tmp_decimal_point);
+ grouping_ = tmp_grouping;
+ }
+ else if(32 <= tmp_decimal_point && tmp_decimal_point <=126 && tmp_thousands_sep == 0xA0) {
+ // workaround common bug - substitute NBSP with ordinary space
+ thousands_sep_ = ' ';
+ decimal_point_ = static_cast<char>(tmp_decimal_point);
+ grouping_ = tmp_grouping;
+ }
+ else if(32 <= tmp_decimal_point && tmp_decimal_point <=126)
+ {
+ thousands_sep_=',';
+ decimal_point_ = static_cast<char>(tmp_decimal_point);
+ grouping_=std::string();
+ }
+ else {
+ thousands_sep_ = ',';
+ decimal_point_ = '.';
+ grouping_=std::string();
+ }
+ }
+
+ virtual char do_decimal_point() const
+ {
+ return decimal_point_;
+ }
+ virtual char do_thousands_sep() const
+ {
+ return thousands_sep_;
+ }
+ virtual std::string do_grouping() const
+ {
+ return grouping_;
+ }
+ virtual std::string do_truename() const
+ {
+ return truename_;
+ }
+ virtual std::string do_falsename() const
+ {
+ return falsename_;
+ }
+private:
+ std::string truename_;
+ std::string falsename_;
+ char thousands_sep_;
+ char decimal_point_;
+ std::string grouping_;
+
+};
+
+template<bool Intl>
+class utf8_moneypunct_from_wide : public std::moneypunct<char,Intl> {
+public:
+ utf8_moneypunct_from_wide(std::locale const &base,size_t refs = 0) : std::moneypunct<char,Intl>(refs)
+ {
+ typedef std::moneypunct<wchar_t,Intl> wfacet_type;
+ wfacet_type const &wfacet = std::use_facet<wfacet_type>(base);
+
+ curr_symbol_ = conv::from_utf<wchar_t>(wfacet.curr_symbol(),"UTF-8");
+ positive_sign_ = conv::from_utf<wchar_t>(wfacet.positive_sign(),"UTF-8");
+ negative_sign_ = conv::from_utf<wchar_t>(wfacet.negative_sign(),"UTF-8");
+ frac_digits_ = wfacet.frac_digits();
+ pos_format_ = wfacet.pos_format();
+ neg_format_ = wfacet.neg_format();
+
+ wchar_t tmp_decimal_point = wfacet.decimal_point();
+ wchar_t tmp_thousands_sep = wfacet.thousands_sep();
+ std::string tmp_grouping = wfacet.grouping();
+ if( 32 <= tmp_thousands_sep && tmp_thousands_sep <=126 &&
+ 32 <= tmp_decimal_point && tmp_decimal_point <=126)
+ {
+ thousands_sep_ = static_cast<char>(tmp_thousands_sep);
+ decimal_point_ = static_cast<char>(tmp_decimal_point);
+ grouping_ = tmp_grouping;
+ }
+ else if(32 <= tmp_decimal_point && tmp_decimal_point <=126 && tmp_thousands_sep == 0xA0) {
+ // workaround common bug - substitute NBSP with ordinary space
+ thousands_sep_ = ' ';
+ decimal_point_ = static_cast<char>(tmp_decimal_point);
+ grouping_ = tmp_grouping;
+ }
+ else if(32 <= tmp_decimal_point && tmp_decimal_point <=126)
+ {
+ thousands_sep_=',';
+ decimal_point_ = static_cast<char>(tmp_decimal_point);
+ grouping_=std::string();
+ }
+ else {
+ thousands_sep_ = ',';
+ decimal_point_ = '.';
+ grouping_=std::string();
+ }
+ }
+
+ virtual char do_decimal_point() const
+ {
+ return decimal_point_;
+ }
+
+ virtual char do_thousands_sep() const
+ {
+ return thousands_sep_;
+ }
+
+ virtual std::string do_grouping() const
+ {
+ return grouping_;
+ }
+
+ virtual std::string do_curr_symbol() const
+ {
+ return curr_symbol_;
+ }
+ virtual std::string do_positive_sign () const
+ {
+ return positive_sign_;
+ }
+ virtual std::string do_negative_sign() const
+ {
+ return negative_sign_;
+ }
+
+ virtual int do_frac_digits() const
+ {
+ return frac_digits_;
+ }
+
+ virtual std::money_base::pattern do_pos_format() const
+ {
+ return pos_format_;
+ }
+
+ virtual std::money_base::pattern do_neg_format() const
+ {
+ return neg_format_;
+ }
+
+private:
+ char thousands_sep_;
+ char decimal_point_;
+ std::string grouping_;
+ std::string curr_symbol_;
+ std::string positive_sign_;
+ std::string negative_sign_;
+ int frac_digits_;
+ std::money_base::pattern pos_format_,neg_format_;
+
+};
+
+class utf8_numpunct : public std::numpunct_byname<char> {
+public:
+ typedef std::numpunct_byname<char> base_type;
+ utf8_numpunct(char const *name,size_t refs = 0) :
+ std::numpunct_byname<char>(name,refs)
+ {
+ }
+ virtual char do_thousands_sep() const
+ {
+ unsigned char bs = base_type::do_thousands_sep();
+ if(bs > 127)
+ if(bs == 0xA0)
+ return ' ';
+ else
+ return 0;
+ else
+ return bs;
+ }
+ virtual std::string do_grouping() const
+ {
+ unsigned char bs = base_type::do_thousands_sep();
+ if(bs > 127 && bs != 0xA0)
+ return std::string();
+ return base_type::do_grouping();
+ }
+};
+
+template<bool Intl>
+class utf8_moneypunct : public std::moneypunct_byname<char,Intl> {
+public:
+ typedef std::moneypunct_byname<char,Intl> base_type;
+ utf8_moneypunct(char const *name,size_t refs = 0) :
+ std::moneypunct_byname<char,Intl>(name,refs)
+ {
+ }
+ virtual char do_thousands_sep() const
+ {
+ unsigned char bs = base_type::do_thousands_sep();
+ if(bs > 127)
+ if(bs == 0xA0)
+ return ' ';
+ else
+ return 0;
+ else
+ return bs;
+ }
+ virtual std::string do_grouping() const
+ {
+ unsigned char bs = base_type::do_thousands_sep();
+ if(bs > 127 && bs != 0xA0)
+ return std::string();
+ return base_type::do_grouping();
+ }
+};
+
+
+template<typename CharType>
+std::locale create_basic_parsing(std::locale const &in,std::string const &locale_name)
+{
+ std::locale tmp = std::locale(in,new std::numpunct_byname<CharType>(locale_name.c_str()));
+ tmp = std::locale(tmp,new std::moneypunct_byname<CharType,true>(locale_name.c_str()));
+ tmp = std::locale(tmp,new std::moneypunct_byname<CharType,false>(locale_name.c_str()));
+ tmp = std::locale(tmp,new std::ctype_byname<CharType>(locale_name.c_str()));
+ return tmp;
+}
+
+template<typename CharType>
+std::locale create_basic_formatting(std::locale const &in,std::string const &locale_name)
+{
+ std::locale tmp = create_basic_parsing<CharType>(in,locale_name);
+ std::locale base(locale_name.c_str());
+ tmp = std::locale(tmp,new time_put_from_base<CharType>(base));
+ return tmp;
+}
+
+
+std::locale create_formatting( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf)
+{
+ switch(type) {
+ case char_facet:
+ {
+ if(utf == utf8_from_wide ) {
+ std::locale base = std::locale(locale_name.c_str());
+
+ std::locale tmp = std::locale(in,new utf8_time_put_from_wide(base));
+ tmp = std::locale(tmp,new utf8_numpunct_from_wide(base));
+ tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
+ tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
+ return std::locale(tmp,new util::base_num_format<char>());
+ }
+ else if(utf == utf8_native) {
+ std::locale base = std::locale(locale_name.c_str());
+
+ std::locale tmp = std::locale(in,new time_put_from_base<char>(base));
+ tmp = std::locale(tmp,new utf8_numpunct(locale_name.c_str()));
+ tmp = std::locale(tmp,new utf8_moneypunct<true>(locale_name.c_str()));
+ tmp = std::locale(tmp,new utf8_moneypunct<false>(locale_name.c_str()));
+ return std::locale(tmp,new util::base_num_format<char>());
+ }
+ else if(utf == utf8_native_with_wide) {
+ std::locale base = std::locale(locale_name.c_str());
+
+ std::locale tmp = std::locale(in,new time_put_from_base<char>(base));
+ tmp = std::locale(tmp,new utf8_numpunct_from_wide(base));
+ tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
+ tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
+ return std::locale(tmp,new util::base_num_format<char>());
+ }
+ else
+ {
+ std::locale tmp = create_basic_formatting<char>(in,locale_name);
+ tmp = std::locale(tmp,new util::base_num_format<char>());
+ return tmp;
+ }
+ }
+ case wchar_t_facet:
+ {
+ std::locale tmp = create_basic_formatting<wchar_t>(in,locale_name);
+ tmp = std::locale(tmp,new util::base_num_format<wchar_t>());
+ return tmp;
+ }
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ {
+ std::locale tmp = create_basic_formatting<char16_t>(in,locale_name);
+ tmp = std::locale(tmp,new util::base_num_format<char16_t>());
+ return tmp;
+ }
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ {
+ std::locale tmp = create_basic_formatting<char32_t>(in,locale_name);
+ tmp = std::locale(tmp,new util::base_num_format<char32_t>());
+ return tmp;
+ }
+ #endif
+ default:
+ return in;
+ }
+}
+
+std::locale create_parsing( std::locale const &in,
+ std::string const &locale_name,
+ character_facet_type type,
+ utf8_support utf)
+{
+ switch(type) {
+ case char_facet:
+ {
+ if(utf == utf8_from_wide ) {
+ std::locale base = std::locale::classic();
+
+ base = std::locale(base,new std::numpunct_byname<wchar_t>(locale_name.c_str()));
+ base = std::locale(base,new std::moneypunct_byname<wchar_t,true>(locale_name.c_str()));
+ base = std::locale(base,new std::moneypunct_byname<wchar_t,false>(locale_name.c_str()));
+
+ std::locale tmp = std::locale(in,new utf8_numpunct_from_wide(base));
+ tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
+ tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
+ return std::locale(tmp,new util::base_num_parse<char>());
+ }
+ else if(utf == utf8_native) {
+ std::locale tmp = std::locale(in,new utf8_numpunct(locale_name.c_str()));
+ tmp = std::locale(tmp,new utf8_moneypunct<true>(locale_name.c_str()));
+ tmp = std::locale(tmp,new utf8_moneypunct<false>(locale_name.c_str()));
+ return std::locale(tmp,new util::base_num_parse<char>());
+ }
+ else if(utf == utf8_native_with_wide) {
+ std::locale base = std::locale(locale_name.c_str());
+
+ std::locale tmp = std::locale(in,new utf8_numpunct_from_wide(base));
+ tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
+ tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
+ return std::locale(tmp,new util::base_num_parse<char>());
+ }
+ else
+ {
+ std::locale tmp = create_basic_parsing<char>(in,locale_name);
+ tmp = std::locale(in,new util::base_num_parse<char>());
+ return tmp;
+ }
+ }
+ case wchar_t_facet:
+ {
+ std::locale tmp = create_basic_parsing<wchar_t>(in,locale_name);
+ tmp = std::locale(in,new util::base_num_parse<wchar_t>());
+ return tmp;
+ }
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ {
+ std::locale tmp = create_basic_parsing<char16_t>(in,locale_name);
+ tmp = std::locale(in,new util::base_num_parse<char16_t>());
+ return tmp;
+ }
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ {
+ std::locale tmp = create_basic_parsing<char32_t>(in,locale_name);
+ tmp = std::locale(in,new util::base_num_parse<char32_t>());
+ return tmp;
+ }
+ #endif
+ default:
+ return in;
+ }
+}
+
+
+} // impl_std
+} // locale
+} //boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/std/std_backend.cpp b/src/boost/libs/locale/src/std/std_backend.cpp
new file mode 100644
index 000000000..f9afcb417
--- /dev/null
+++ b/src/boost/libs/locale/src/std/std_backend.cpp
@@ -0,0 +1,234 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/gnu_gettext.hpp>
+#include "all_generator.hpp"
+#include "../util/locale_data.hpp"
+#include "../util/gregorian.hpp"
+#include <boost/locale/util.hpp>
+#include <algorithm>
+#include <iterator>
+
+#if defined(BOOST_WINDOWS)
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
+# include <windows.h>
+# include "../encoding/conv.hpp"
+# include "../win32/lcid.hpp"
+#endif
+
+#include "std_backend.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_std {
+
+ class std_localization_backend : public localization_backend {
+ public:
+ std_localization_backend() :
+ invalid_(true),
+ use_ansi_encoding_(false)
+ {
+ }
+ std_localization_backend(std_localization_backend const &other) :
+ localization_backend(),
+ paths_(other.paths_),
+ domains_(other.domains_),
+ locale_id_(other.locale_id_),
+ invalid_(true),
+ use_ansi_encoding_(other.use_ansi_encoding_)
+ {
+ }
+ virtual std_localization_backend *clone() const
+ {
+ return new std_localization_backend(*this);
+ }
+
+ void set_option(std::string const &name,std::string const &value)
+ {
+ invalid_ = true;
+ if(name=="locale")
+ locale_id_ = value;
+ else if(name=="message_path")
+ paths_.push_back(value);
+ else if(name=="message_application")
+ domains_.push_back(value);
+ else if(name=="use_ansi_encoding")
+ use_ansi_encoding_ = value == "true";
+
+ }
+ void clear_options()
+ {
+ invalid_ = true;
+ use_ansi_encoding_ = false;
+ locale_id_.clear();
+ paths_.clear();
+ domains_.clear();
+ }
+
+ void prepare_data()
+ {
+ if(!invalid_)
+ return;
+ invalid_ = false;
+ std::string lid=locale_id_;
+ if(lid.empty()) {
+ bool use_utf8 = ! use_ansi_encoding_;
+ lid = util::get_system_locale(use_utf8);
+ }
+ in_use_id_ = lid;
+ data_.parse(lid);
+ name_ = "C";
+ utf_mode_ = utf8_none;
+
+ #if defined(BOOST_WINDOWS)
+ std::pair<std::string,int> wl_inf = to_windows_name(lid);
+ std::string win_name = wl_inf.first;
+ int win_codepage = wl_inf.second;
+ #endif
+
+ if(!data_.utf8) {
+ if(loadable(lid)) {
+ name_ = lid;
+ utf_mode_ = utf8_none;
+ }
+ #if defined(BOOST_WINDOWS)
+ else if(loadable(win_name)
+ && win_codepage == conv::impl::encoding_to_windows_codepage(data_.encoding.c_str()))
+ {
+ name_ = win_name;
+ utf_mode_ = utf8_none;
+ }
+ #endif
+ }
+ else {
+ if(loadable(lid)) {
+ name_ = lid;
+ utf_mode_ = utf8_native_with_wide;
+ }
+ #if defined(BOOST_WINDOWS)
+ else if(loadable(win_name)) {
+ name_ = win_name;
+ utf_mode_ = utf8_from_wide;
+ }
+ #endif
+ }
+ }
+
+ #if defined(BOOST_WINDOWS)
+ std::pair<std::string,int> to_windows_name(std::string const &l)
+ {
+ std::pair<std::string,int> res("C",0);
+ unsigned lcid = impl_win::locale_to_lcid(l);
+ char win_lang[256] = {0};
+ char win_country[256] = {0};
+ char win_codepage[10] = {0};
+ if(GetLocaleInfoA(lcid,LOCALE_SENGLANGUAGE,win_lang,sizeof(win_lang))==0)
+ return res;
+ std::string lc_name = win_lang;
+ if(GetLocaleInfoA(lcid,LOCALE_SENGCOUNTRY,win_country,sizeof(win_country))!=0) {
+ lc_name += "_";
+ lc_name += win_country;
+ }
+
+ res.first = lc_name;
+
+ if(GetLocaleInfoA(lcid,LOCALE_IDEFAULTANSICODEPAGE,win_codepage,sizeof(win_codepage))!=0)
+ res.second = atoi(win_codepage);
+ return res;
+ }
+ #endif
+
+ bool loadable(std::string name)
+ {
+ try {
+ std::locale l(name.c_str());
+ return true;
+ }
+ catch(std::exception const &/*e*/) {
+ return false;
+ }
+ }
+
+ virtual std::locale install(std::locale const &base,
+ locale_category_type category,
+ character_facet_type type = nochar_facet)
+ {
+ prepare_data();
+
+ switch(category) {
+ case convert_facet:
+ return create_convert(base,name_,type,utf_mode_);
+ case collation_facet:
+ return create_collate(base,name_,type,utf_mode_);
+ case formatting_facet:
+ return create_formatting(base,name_,type,utf_mode_);
+ case parsing_facet:
+ return create_parsing(base,name_,type,utf_mode_);
+ case codepage_facet:
+ return create_codecvt(base,name_,type,utf_mode_);
+ case calendar_facet:
+ return util::install_gregorian_calendar(base,data_.country);
+ case message_facet:
+ {
+ gnu_gettext::messages_info minf;
+ minf.language = data_.language;
+ minf.country = data_.country;
+ minf.variant = data_.variant;
+ minf.encoding = data_.encoding;
+ std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
+ minf.paths = paths_;
+ switch(type) {
+ case char_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
+ case wchar_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ case char16_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf));
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ case char32_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf));
+ #endif
+ default:
+ return base;
+ }
+ }
+ case information_facet:
+ return util::create_info(base,in_use_id_);
+ default:
+ return base;
+ }
+ }
+
+ private:
+
+ std::vector<std::string> paths_;
+ std::vector<std::string> domains_;
+ std::string locale_id_;
+
+ util::locale_data data_;
+ std::string name_;
+ std::string in_use_id_;
+ utf8_support utf_mode_;
+ bool invalid_;
+ bool use_ansi_encoding_;
+ };
+
+ localization_backend *create_localization_backend()
+ {
+ return new std_localization_backend();
+ }
+
+} // impl icu
+} // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/std/std_backend.hpp b/src/boost/libs/locale/src/std/std_backend.hpp
new file mode 100644
index 000000000..0caf779c6
--- /dev/null
+++ b/src/boost/libs/locale/src/std/std_backend.hpp
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_STD_LOCALIZATION_BACKEND_HPP
+#define BOOST_LOCALE_IMPL_STD_LOCALIZATION_BACKEND_HPP
+namespace boost {
+ namespace locale {
+ class localization_backend;
+ namespace impl_std {
+ localization_backend *create_localization_backend();
+ } // impl_std
+ } // locale
+} // boost
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/util/codecvt_converter.cpp b/src/boost/libs/locale/src/util/codecvt_converter.cpp
new file mode 100644
index 000000000..1adb6b41d
--- /dev/null
+++ b/src/boost/libs/locale/src/util/codecvt_converter.cpp
@@ -0,0 +1,458 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/generator.hpp>
+#include <boost/locale/encoding.hpp>
+#include <boost/locale/utf8_codecvt.hpp>
+
+#include "../encoding/conv.hpp"
+
+#include <boost/locale/util.hpp>
+
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4244 4996) // loose data
+#endif
+
+#include <cstddef>
+#include <string.h>
+#include <vector>
+#include <algorithm>
+
+//#define DEBUG_CODECVT
+
+#ifdef DEBUG_CODECVT
+#include <iostream>
+#endif
+
+namespace boost {
+namespace locale {
+namespace util {
+
+ class utf8_converter : public base_converter {
+ public:
+ virtual int max_len() const
+ {
+ return 4;
+ }
+
+ virtual utf8_converter *clone() const
+ {
+ return new utf8_converter();
+ }
+
+ bool is_thread_safe() const
+ {
+ return true;
+ }
+
+ virtual uint32_t to_unicode(char const *&begin,char const *end)
+ {
+ char const *p=begin;
+
+ utf::code_point c = utf::utf_traits<char>::decode(p,end);
+
+ if(c==utf::illegal)
+ return illegal;
+
+ if(c==utf::incomplete)
+ return incomplete;
+
+ begin = p;
+ return c;
+ }
+
+ virtual uint32_t from_unicode(uint32_t u,char *begin,char const *end)
+ {
+ if(!utf::is_valid_codepoint(u))
+ return illegal;
+ int width = utf::utf_traits<char>::width(u);
+ std::ptrdiff_t d=end-begin;
+ if(d < width)
+ return incomplete;
+ utf::utf_traits<char>::encode(u,begin);
+ return width;
+ }
+ }; // utf8_converter
+
+ class simple_converter_impl {
+ public:
+
+ static const int hash_table_size = 1024;
+
+ simple_converter_impl(std::string const &encoding)
+ {
+ for(unsigned i=0;i<128;i++)
+ to_unicode_tbl_[i]=i;
+ for(unsigned i=128;i<256;i++) {
+ char buf[2] = { char(i) , 0 };
+ uint32_t uchar=utf::illegal;
+ try {
+ std::wstring const tmp = conv::to_utf<wchar_t>(buf,buf+1,encoding,conv::stop);
+ if(tmp.size() == 1) {
+ uchar = tmp[0];
+ }
+ else {
+ uchar = utf::illegal;
+ }
+ }
+ catch(conv::conversion_error const &/*e*/) {
+ uchar = utf::illegal;
+ }
+ to_unicode_tbl_[i]=uchar;
+ }
+ for(int i=0;i<hash_table_size;i++)
+ from_unicode_tbl_[i]=0;
+ for(unsigned i=1;i<256;i++) {
+ if(to_unicode_tbl_[i]!=utf::illegal) {
+ unsigned pos = to_unicode_tbl_[i] % hash_table_size;
+ while(from_unicode_tbl_[pos]!=0)
+ pos = (pos + 1) % hash_table_size;
+ from_unicode_tbl_[pos] = i;
+ }
+ }
+ }
+
+ uint32_t to_unicode(char const *&begin,char const *end) const
+ {
+ if(begin==end)
+ return utf::incomplete;
+ unsigned char c = *begin++;
+ return to_unicode_tbl_[c];
+ }
+ uint32_t from_unicode(uint32_t u,char *begin,char const *end) const
+ {
+ if(begin==end)
+ return utf::incomplete;
+ if(u==0) {
+ *begin = 0;
+ return 1;
+ }
+ unsigned pos = u % hash_table_size;
+ unsigned char c;
+ while((c=from_unicode_tbl_[pos])!=0 && to_unicode_tbl_[c]!=u)
+ pos = (pos + 1) % hash_table_size;
+ if(c==0)
+ return utf::illegal;
+ *begin = c;
+ return 1;
+ }
+ private:
+ uint32_t to_unicode_tbl_[256];
+ unsigned char from_unicode_tbl_[hash_table_size];
+ };
+
+ class simple_converter : public base_converter {
+ public:
+
+ virtual ~simple_converter()
+ {
+ }
+
+ simple_converter(std::string const &encoding) :
+ cvt_(encoding)
+ {
+ }
+
+ virtual int max_len() const
+ {
+ return 1;
+ }
+
+ virtual bool is_thread_safe() const
+ {
+ return true;
+ }
+ virtual base_converter *clone() const
+ {
+ return new simple_converter(*this);
+ }
+
+ virtual uint32_t to_unicode(char const *&begin,char const *end)
+ {
+ return cvt_.to_unicode(begin,end);
+ }
+ virtual uint32_t from_unicode(uint32_t u,char *begin,char const *end)
+ {
+ return cvt_.from_unicode(u,begin,end);
+ }
+ private:
+ simple_converter_impl cvt_;
+ };
+
+ template<typename CharType>
+ class simple_codecvt : public generic_codecvt<CharType,simple_codecvt<CharType> >
+ {
+ public:
+
+ simple_codecvt(std::string const &encoding,size_t refs = 0) :
+ generic_codecvt<CharType,simple_codecvt<CharType> >(refs),
+ cvt_(encoding)
+ {
+ }
+
+ struct state_type {};
+ static state_type initial_state(generic_codecvt_base::initial_convertion_state /* unused */)
+ {
+ return state_type();
+ }
+ static int max_encoding_length()
+ {
+ return 1;
+ }
+
+ utf::code_point to_unicode(state_type &,char const *&begin,char const *end) const
+ {
+ return cvt_.to_unicode(begin,end);
+ }
+
+ utf::code_point from_unicode(state_type &,utf::code_point u,char *begin,char const *end) const
+ {
+ return cvt_.from_unicode(u,begin,end);
+ }
+ private:
+ simple_converter_impl cvt_;
+
+ };
+
+ namespace {
+ char const *simple_encoding_table[] = {
+ "cp1250",
+ "cp1251",
+ "cp1252",
+ "cp1253",
+ "cp1254",
+ "cp1255",
+ "cp1256",
+ "cp1257",
+ "iso88591",
+ "iso885913",
+ "iso885915",
+ "iso88592",
+ "iso88593",
+ "iso88594",
+ "iso88595",
+ "iso88596",
+ "iso88597",
+ "iso88598",
+ "iso88599",
+ "koi8r",
+ "koi8u",
+ "usascii",
+ "windows1250",
+ "windows1251",
+ "windows1252",
+ "windows1253",
+ "windows1254",
+ "windows1255",
+ "windows1256",
+ "windows1257"
+ };
+
+ bool compare_strings(char const *l,char const *r)
+ {
+ return strcmp(l,r) < 0;
+ }
+ }
+
+ bool check_is_simple_encoding(std::string const &encoding)
+ {
+ std::string norm = conv::impl::normalize_encoding(encoding.c_str());
+ return std::binary_search<char const **>( simple_encoding_table,
+ simple_encoding_table + sizeof(simple_encoding_table)/sizeof(char const *),
+ norm.c_str(),
+ compare_strings);
+ return 0;
+ }
+
+ #if !defined(BOOST_LOCALE_HIDE_AUTO_PTR) && !defined(BOOST_NO_AUTO_PTR)
+ std::auto_ptr<base_converter> create_utf8_converter()
+ {
+ std::auto_ptr<base_converter> res(create_utf8_converter_new_ptr());
+ return res;
+ }
+ std::auto_ptr<base_converter> create_simple_converter(std::string const &encoding)
+ {
+ std::auto_ptr<base_converter> res(create_simple_converter_new_ptr(encoding));
+ return res;
+ }
+ std::locale create_codecvt(std::locale const &in,std::auto_ptr<base_converter> cvt,character_facet_type type)
+ {
+ return create_codecvt_from_pointer(in,cvt.release(),type);
+ }
+ #endif
+ #ifndef BOOST_NO_CXX11_SMART_PTR
+ std::unique_ptr<base_converter> create_utf8_converter_unique_ptr()
+ {
+ std::unique_ptr<base_converter> res(create_utf8_converter_new_ptr());
+ return res;
+ }
+ std::unique_ptr<base_converter> create_simple_converter_unique_ptr(std::string const &encoding)
+ {
+ std::unique_ptr<base_converter> res(create_simple_converter_new_ptr(encoding));
+ return res;
+ }
+ std::locale create_codecvt(std::locale const &in,std::unique_ptr<base_converter> cvt,character_facet_type type)
+ {
+ return create_codecvt_from_pointer(in,cvt.release(),type);
+ }
+ #endif
+
+ base_converter *create_simple_converter_new_ptr(std::string const &encoding)
+ {
+ if(check_is_simple_encoding(encoding))
+ return new simple_converter(encoding);
+ return 0;
+ }
+
+ base_converter *create_utf8_converter_new_ptr()
+ {
+ return new utf8_converter();
+ }
+
+ template<typename CharType>
+ class code_converter : public generic_codecvt<CharType,code_converter<CharType> >
+ {
+ public:
+ #ifndef BOOST_NO_CXX11_SMART_PTR
+ typedef std::unique_ptr<base_converter> base_converter_ptr;
+ #define PTR_TRANS(x) std::move((x))
+ #else
+ typedef std::auto_ptr<base_converter> base_converter_ptr;
+ #define PTR_TRANS(x) (x)
+ #endif
+ typedef base_converter_ptr state_type;
+
+ code_converter(base_converter_ptr cvt,size_t refs = 0) :
+ generic_codecvt<CharType,code_converter<CharType> >(refs),
+ cvt_(PTR_TRANS(cvt))
+ {
+ max_len_ = cvt_->max_len();
+ thread_safe_ = cvt_->is_thread_safe();
+ }
+
+
+ int max_encoding_length() const
+ {
+ return max_len_;
+ }
+
+ base_converter_ptr initial_state(generic_codecvt_base::initial_convertion_state /* unused */) const
+ {
+ base_converter_ptr r;
+ if(!thread_safe_)
+ r.reset(cvt_->clone());
+ return r;
+ }
+
+ utf::code_point to_unicode(base_converter_ptr &ptr,char const *&begin,char const *end) const
+ {
+ if(thread_safe_)
+ return cvt_->to_unicode(begin,end);
+ else
+ return ptr->to_unicode(begin,end);
+ }
+
+ utf::code_point from_unicode(base_converter_ptr &ptr,utf::code_point u,char *begin,char const *end) const
+ {
+ if(thread_safe_)
+ return cvt_->from_unicode(u,begin,end);
+ else
+ return ptr->from_unicode(u,begin,end);
+ }
+
+ private:
+ base_converter_ptr cvt_;
+ int max_len_;
+ bool thread_safe_;
+ };
+
+
+ std::locale create_codecvt_from_pointer(std::locale const &in,base_converter *pcvt,character_facet_type type)
+ {
+ code_converter<char>::base_converter_ptr cvt(pcvt);
+ if(!cvt.get())
+ cvt.reset(new base_converter());
+ switch(type) {
+ case char_facet:
+ return std::locale(in,new code_converter<char>(PTR_TRANS(cvt)));
+ case wchar_t_facet:
+ return std::locale(in,new code_converter<wchar_t>(PTR_TRANS(cvt)));
+ #if defined(BOOST_LOCALE_ENABLE_CHAR16_T) && !defined(BOOST_NO_CHAR16_T_CODECVT)
+ case char16_t_facet:
+ return std::locale(in,new code_converter<char16_t>(PTR_TRANS(cvt)));
+ #endif
+ #if defined(BOOST_LOCALE_ENABLE_CHAR32_T) && !defined(BOOST_NO_CHAR32_T_CODECVT)
+ case char32_t_facet:
+ return std::locale(in,new code_converter<char32_t>(PTR_TRANS(cvt)));
+ #endif
+ default:
+ return in;
+ }
+ }
+
+
+ ///
+ /// Install utf8 codecvt to UTF-16 or UTF-32 into locale \a in and return
+ /// new locale that is based on \a in and uses new facet.
+ ///
+ std::locale create_utf8_codecvt(std::locale const &in,character_facet_type type)
+ {
+ switch(type) {
+ case char_facet:
+ return std::locale(in,new utf8_codecvt<char>());
+ case wchar_t_facet:
+ return std::locale(in,new utf8_codecvt<wchar_t>());
+ #if defined(BOOST_LOCALE_ENABLE_CHAR16_T) && !defined(BOOST_NO_CHAR16_T_CODECVT)
+ case char16_t_facet:
+ return std::locale(in,new utf8_codecvt<char16_t>());
+ #endif
+ #if defined(BOOST_LOCALE_ENABLE_CHAR32_T) && !defined(BOOST_NO_CHAR32_T_CODECVT)
+ case char32_t_facet:
+ return std::locale(in,new utf8_codecvt<char32_t>());
+ #endif
+ default:
+ return in;
+ }
+ }
+
+ ///
+ /// This function installs codecvt that can be used for conversion between single byte
+ /// character encodings like ISO-8859-1, koi8-r, windows-1255 and Unicode code points,
+ ///
+ /// Throws invalid_charset_error if the chacater set is not supported or isn't single byte character
+ /// set
+ std::locale create_simple_codecvt(std::locale const &in,std::string const &encoding,character_facet_type type)
+ {
+ if(!check_is_simple_encoding(encoding))
+ throw boost::locale::conv::invalid_charset_error("Invalid simple encoding " + encoding);
+
+ switch(type) {
+ case char_facet:
+ return std::locale(in,new simple_codecvt<char>(encoding));
+ case wchar_t_facet:
+ return std::locale(in,new simple_codecvt<wchar_t>(encoding));
+ #if defined(BOOST_LOCALE_ENABLE_CHAR16_T) && !defined(BOOST_NO_CHAR16_T_CODECVT)
+ case char16_t_facet:
+ return std::locale(in,new simple_codecvt<char16_t>(encoding));
+ #endif
+ #if defined(BOOST_LOCALE_ENABLE_CHAR32_T) && !defined(BOOST_NO_CHAR32_T_CODECVT)
+ case char32_t_facet:
+ return std::locale(in,new simple_codecvt<char32_t>(encoding));
+ #endif
+ default:
+ return in;
+ }
+ }
+
+
+
+} // util
+} // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/util/default_locale.cpp b/src/boost/libs/locale/src/util/default_locale.cpp
new file mode 100644
index 000000000..b0aab03c7
--- /dev/null
+++ b/src/boost/libs/locale/src/util/default_locale.cpp
@@ -0,0 +1,80 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/util.hpp>
+#include <boost/config.hpp>
+#include <stdlib.h>
+
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4996)
+#endif
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <windows.h>
+#define BOOST_LOCALE_USE_WIN32_API
+#endif
+
+namespace boost {
+ namespace locale {
+ namespace util {
+ std::string get_system_locale(bool use_utf8)
+ {
+ char const *lang = 0;
+ if(!lang || !*lang)
+ lang = getenv("LC_CTYPE");
+ if(!lang || !*lang)
+ lang = getenv("LC_ALL");
+ if(!lang || !*lang)
+ lang = getenv("LANG");
+ #ifndef BOOST_LOCALE_USE_WIN32_API
+ (void)use_utf8; // not relevant for non-windows
+ if(!lang || !*lang)
+ lang = "C";
+ return lang;
+ #else
+ if(lang && *lang) {
+ return lang;
+ }
+ char buf[10];
+ if(GetLocaleInfoA(LOCALE_USER_DEFAULT,LOCALE_SISO639LANGNAME,buf,sizeof(buf))==0)
+ return "C";
+ std::string lc_name = buf;
+ if(GetLocaleInfoA(LOCALE_USER_DEFAULT,LOCALE_SISO3166CTRYNAME,buf,sizeof(buf))!=0) {
+ lc_name += "_";
+ lc_name += buf;
+ }
+ if(!use_utf8) {
+ if(GetLocaleInfoA(LOCALE_USER_DEFAULT,LOCALE_IDEFAULTANSICODEPAGE,buf,sizeof(buf))!=0) {
+ if(atoi(buf)==0)
+ lc_name+=".UTF-8";
+ else {
+ lc_name +=".windows-";
+ lc_name +=buf;
+ }
+ }
+ else {
+ lc_name += "UTF-8";
+ }
+ }
+ else {
+ lc_name += ".UTF-8";
+ }
+ return lc_name;
+
+ #endif
+ }
+ } // impl
+ } // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/util/gregorian.cpp b/src/boost/libs/locale/src/util/gregorian.cpp
new file mode 100644
index 000000000..49e45c3a5
--- /dev/null
+++ b/src/boost/libs/locale/src/util/gregorian.cpp
@@ -0,0 +1,852 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/config.hpp>
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4996)
+#endif
+#include <locale>
+#include <string>
+#include <ios>
+#include <boost/locale/date_time_facet.hpp>
+#include <boost/locale/date_time.hpp>
+#include <boost/locale/hold_ptr.hpp>
+#include <stdlib.h>
+#include <ctime>
+#include <memory>
+#include <algorithm>
+#include <limits>
+
+#include "timezone.hpp"
+#include "gregorian.hpp"
+
+namespace boost {
+namespace locale {
+namespace util {
+ namespace {
+
+ int is_leap(int year)
+ {
+ if(year % 400 == 0)
+ return 1;
+ if(year % 100 == 0)
+ return 0;
+ if(year % 4 == 0)
+ return 1;
+ return 0;
+ }
+
+ int days_in_month(int year,int month)
+ {
+ static const int tbl[2][12] = {
+ { 31,28,31,30,31,30,31,31,30,31,30,31 },
+ { 31,29,31,30,31,30,31,31,30,31,30,31 }
+ };
+ return tbl[is_leap(year)][month - 1];
+ }
+
+ inline int days_from_0(int year)
+ {
+ year--;
+ return 365 * year + (year / 400) - (year/100) + (year / 4);
+ }
+
+ int days_from_1970(int year)
+ {
+ static const int days_from_0_to_1970 = days_from_0(1970);
+ return days_from_0(year) - days_from_0_to_1970;
+ }
+
+ int days_from_1jan(int year,int month,int day)
+ {
+ static const int days[2][12] = {
+ { 0,31,59,90,120,151,181,212,243,273,304,334 },
+ { 0,31,60,91,121,152,182,213,244,274,305,335 }
+ };
+ return days[is_leap(year)][month-1] + day - 1;
+ }
+
+ std::time_t internal_timegm(std::tm const *t)
+ {
+ int year = t->tm_year + 1900;
+ int month = t->tm_mon;
+ if(month > 11) {
+ year += month/12;
+ month %= 12;
+ }
+ else if(month < 0) {
+ int years_diff = (-month + 11)/12;
+ year -= years_diff;
+ month+=12 * years_diff;
+ }
+ month++;
+ int day = t->tm_mday;
+ int day_of_year = days_from_1jan(year,month,day);
+ int days_since_epoch = days_from_1970(year) + day_of_year;
+
+ std::time_t seconds_in_day = 3600 * 24;
+ std::time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
+
+ return result;
+ }
+
+ } // anon
+
+
+
+
+ namespace {
+
+ // Locale dependent data
+
+ bool comparator(char const *left,char const *right)
+ {
+ return strcmp(left,right) < 0;
+ }
+
+ //
+ // Ref: CLDR 1.9 common/supplemental/supplementalData.xml
+ //
+ // monday - default
+ // fri - MV
+ // sat - AE AF BH DJ DZ EG ER ET IQ IR JO KE KW LY MA OM QA SA SD SO SY TN YE
+ // sun - AR AS AZ BW CA CN FO GE GL GU HK IL IN JM JP KG KR LA MH MN MO MP MT NZ PH PK SG TH TT TW UM US UZ VI ZW
+ //
+
+ int first_day_of_week(char const *terr) {
+ static char const * const sat[] = {
+ "AE","AF","BH","DJ","DZ","EG","ER","ET","IQ","IR",
+ "JO","KE","KW","LY","MA","OM","QA","SA","SD","SO",
+ "SY","TN","YE"
+ };
+ static char const * const sunday[] = {
+ "AR","AS","AZ","BW","CA","CN","FO","GE","GL","GU",
+ "HK","IL","IN","JM","JP","KG","KR","LA","MH","MN",
+ "MO","MP","MT","NZ","PH","PK","SG","TH","TT","TW",
+ "UM","US","UZ","VI","ZW"
+ };
+ if(strcmp(terr,"MV") == 0)
+ return 5; // fri
+ if(std::binary_search<char const * const *>(sat,sat+sizeof(sat)/(sizeof(sat[0])),terr,comparator))
+ return 6; // sat
+ if(std::binary_search<char const * const *>(sunday,sunday+sizeof(sunday)/(sizeof(sunday[0])),terr,comparator))
+ return 0; // sun
+ // default
+ return 1; // mon
+ }
+ }
+
+ class gregorian_calendar : public abstract_calendar {
+ public:
+
+ gregorian_calendar(std::string const &terr)
+ {
+ first_day_of_week_ = first_day_of_week(terr.c_str());
+ time_ = std::time(0);
+ is_local_ = true;
+ tzoff_ = 0;
+ from_time(time_);
+ }
+
+ ///
+ /// Make a polymorphic copy of the calendar
+ ///
+ virtual gregorian_calendar *clone() const
+ {
+ return new gregorian_calendar(*this);
+ }
+
+ ///
+ /// Set specific \a value for period \a p, note not all values are settable.
+ ///
+ virtual void set_value(period::marks::period_mark p,int value)
+ {
+ using namespace period::marks;
+ switch(p) {
+ case era: ///< Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1]
+ return;
+ case year: ///< Year, it is calendar specific
+ case extended_year: ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1.
+ tm_updated_.tm_year = value - 1900;
+ break;
+ case month:
+ tm_updated_.tm_mon = value;
+ break;
+ case day:
+ tm_updated_.tm_mday = value;
+ break;
+ case hour: ///< 24 clock hour [0..23]
+ tm_updated_.tm_hour = value;
+ break;
+ case hour_12: ///< 12 clock hour [0..11]
+ tm_updated_.tm_hour = tm_updated_.tm_hour / 12 * 12 + value;
+ break;
+ case am_pm: ///< am or pm marker, [0..1]
+ tm_updated_.tm_hour = 12 * value + tm_updated_.tm_hour % 12;
+ break;
+ case minute: ///< minute [0..59]
+ tm_updated_.tm_min = value;
+ break;
+ case second:
+ tm_updated_.tm_sec = value;
+ break;
+ case day_of_year:
+ normalize();
+ tm_updated_.tm_mday += (value - (tm_updated_.tm_yday + 1));
+ break;
+ case day_of_week: ///< Day of week, starting from Sunday, [1..7]
+ if(value < 1) // make sure it is positive
+ value += (-value / 7) * 7 + 7;
+ // convert to local DOW
+ value = (value - 1 - first_day_of_week_ + 14) % 7 + 1;
+ // fall throght
+ case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
+ normalize();
+ tm_updated_.tm_mday += (value - 1) - (tm_updated_.tm_wday - first_day_of_week_ + 7) % 7;
+ break;
+ case day_of_week_in_month: ///< Original number of the day of the week in month. (1st sunday, 2nd sunday etc)
+ case week_of_year: ///< The week number in the year, 4 is the minimal number of days to be in month
+ case week_of_month: ///< The week number withing current month
+ {
+ normalize();
+ int current_week = get_value(p,current);
+ int diff = 7 * (value - current_week);
+ tm_updated_.tm_mday += diff;
+ }
+ break;
+ case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France
+ default:
+ return;
+ }
+ normalized_ = false;
+ }
+
+ void normalize()
+ {
+ if(!normalized_) {
+ std::tm val = tm_updated_;
+ val.tm_isdst = -1;
+ val.tm_wday = -1; // indecator of error
+ std::time_t point = -1;
+ if(is_local_) {
+ point = std::mktime(&val);
+ if(point == static_cast<std::time_t>(-1)){
+ #ifndef BOOST_WINDOWS
+ // windows does not handle negative time_t, under other plaforms
+ // it may be actually valid value in 1969-12-31 23:59:59
+ // so we check that a filed was updated - does not happen in case of error
+ if(val.tm_wday == -1)
+ #endif
+ {
+ throw date_time_error("boost::locale::gregorian_calendar: invalid time");
+ }
+ }
+ }
+ else {
+ point = internal_timegm(&val);
+ #ifdef BOOST_WINDOWS
+ // Windows uses TLS, thread safe
+ std::tm *revert_point = 0;
+ if(point < 0 || (revert_point = gmtime(&point)) == 0)
+ throw date_time_error("boost::locale::gregorian_calendar time is out of range");
+ val = *revert_point;
+ #else
+ if(!gmtime_r(&point,&val))
+ throw date_time_error("boost::locale::gregorian_calendar invalid time");
+ #endif
+
+ }
+
+ time_ = point - tzoff_;
+ tm_ = val;
+ tm_updated_ = val;
+ normalized_ = true;
+ }
+ }
+
+ int get_week_number(int day,int wday) const
+ {
+ ///
+ /// This is the number of days that are considered withing
+ /// period such that the week belongs there
+ ///
+ static const int days_in_full_week = 4;
+
+
+ // Alaways use local week start
+ int current_dow = (wday - first_day_of_week_ + 7) % 7;
+ // Calculate local week day of Jan 1st.
+ int first_week_day = (current_dow + 700 - day) % 7;
+ // adding something big devidable by 7
+
+ int start_of_period_in_weeks;
+ if(first_week_day < days_in_full_week) {
+ start_of_period_in_weeks = - first_week_day;
+ }
+ else {
+ start_of_period_in_weeks = 7 - first_week_day;
+ }
+ int week_number_in_days = day - start_of_period_in_weeks;
+ if(week_number_in_days < 0)
+ return -1;
+ return week_number_in_days / 7 + 1;
+ }
+
+ ///
+ /// Get specific value for period \a p according to a value_type \a v
+ ///
+ virtual int get_value(period::marks::period_mark p,value_type v) const
+ {
+ using namespace period::marks;
+ switch(p) {
+ case era:
+ return 1;
+ case year:
+ case extended_year:
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ #ifdef BOOST_WINDOWS
+ return 1970; // Unix epoch windows can't handle negative time_t
+ #else
+ if(sizeof(std::time_t) == 4)
+ return 1901; // minimal year with 32 bit time_t
+ else
+ return 1;
+ #endif
+ case absolute_maximum:
+ case least_maximum:
+ case actual_maximum:
+ if(sizeof(std::time_t) == 4)
+ return 2038; // Y2K38 - maximal with 32 bit time_t
+ else
+ return std::numeric_limits<int>::max();
+ case current:
+ return tm_.tm_year + 1900;
+ };
+ break;
+ case month:
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 0;
+ case absolute_maximum:
+ case least_maximum:
+ case actual_maximum:
+ return 11;
+ case current:
+ return tm_.tm_mon;
+ };
+ break;
+ case day:
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 1;
+ case absolute_maximum:
+ return 31;
+ case least_maximum:
+ return 28;
+ case actual_maximum:
+ return days_in_month(tm_.tm_year + 1900,tm_.tm_mon + 1);
+ case current:
+ return tm_.tm_mday;
+ };
+ break;
+ case day_of_year: ///< The number of day in year, starting from 1
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 1;
+ case absolute_maximum:
+ return 366;
+ case least_maximum:
+ return 365;
+ case actual_maximum:
+ return is_leap(tm_.tm_year + 1900) ? 366 : 365;
+ case current:
+ return tm_.tm_yday + 1;
+ }
+ break;
+ case day_of_week: ///< Day of week, starting from Sunday, [1..7]
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 1;
+ case absolute_maximum:
+ case least_maximum:
+ case actual_maximum:
+ return 7;
+ case current:
+ return tm_.tm_wday + 1;
+ }
+ break;
+ case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 1;
+ case absolute_maximum:
+ case least_maximum:
+ case actual_maximum:
+ return 7;
+ case current:
+ return (tm_.tm_wday - first_day_of_week_ + 7) % 7 + 1;
+ }
+ break;
+ case hour: ///< 24 clock hour [0..23]
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 0;
+ case absolute_maximum:
+ case least_maximum:
+ case actual_maximum:
+ return 23;
+ case current:
+ return tm_.tm_hour;
+ }
+ break;
+ case hour_12: ///< 12 clock hour [0..11]
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 0;
+ case absolute_maximum:
+ case least_maximum:
+ case actual_maximum:
+ return 11;
+ case current:
+ return tm_.tm_hour % 12;
+ }
+ break;
+ case am_pm: ///< am or pm marker, [0..1]
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 0;
+ case absolute_maximum:
+ case least_maximum:
+ case actual_maximum:
+ return 1;
+ case current:
+ return tm_.tm_hour >= 12 ? 1 : 0;
+ }
+ break;
+ case minute: ///< minute [0..59]
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 0;
+ case absolute_maximum:
+ case least_maximum:
+ case actual_maximum:
+ return 59;
+ case current:
+ return tm_.tm_min;
+ }
+ break;
+ case second: ///< second [0..59]
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 0;
+ case absolute_maximum:
+ case least_maximum:
+ case actual_maximum:
+ return 59;
+ case current:
+ return tm_.tm_sec;
+ }
+ break;
+ case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France
+ return first_day_of_week_ + 1;
+
+ case week_of_year: ///< The week number in the year
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 1;
+ case absolute_maximum:
+ return 53;
+ case least_maximum:
+ return 52;
+ case actual_maximum:
+ {
+ int year = tm_.tm_year + 1900;
+ int end_of_year_days = (is_leap(year) ? 366 : 365) - 1;
+ int dow_of_end_of_year = (end_of_year_days - tm_.tm_yday + tm_.tm_wday) % 7;
+ return get_week_number(end_of_year_days,dow_of_end_of_year);
+ }
+ case current:
+ {
+ int val = get_week_number(tm_.tm_yday,tm_.tm_wday);
+ if(val < 0)
+ return 53;
+ return val;
+ }
+ }
+ case week_of_month: ///< The week number withing current month
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 1;
+ case absolute_maximum:
+ return 5;
+ case least_maximum:
+ return 4;
+ case actual_maximum:
+ {
+ int end_of_month_days = days_in_month(tm_.tm_year + 1900,tm_.tm_mon + 1);
+ int dow_of_end_of_month = (end_of_month_days - tm_.tm_mday + tm_.tm_wday) % 7;
+ return get_week_number(end_of_month_days,dow_of_end_of_month);
+ }
+ case current:
+ {
+ int val = get_week_number(tm_.tm_mday,tm_.tm_wday);
+ if(val < 0)
+ return 5;
+ return val;
+ }
+ }
+
+ case day_of_week_in_month: ///< Original number of the day of the week in month.
+ switch(v) {
+ case absolute_minimum:
+ case greatest_minimum:
+ case actual_minimum:
+ return 1;
+ case absolute_maximum:
+ return 5;
+ case least_maximum:
+ return 4;
+ case actual_maximum:
+ if(tm_.tm_mon == 1 && !is_leap(tm_.tm_year + 1900)) {
+ // only in february in non leap year is 28 days, the rest
+ // conver more then 4 weeks
+ return 4;
+ }
+ return 5;
+ case current:
+ return (tm_.tm_mday - 1) / 7 + 1;
+ default:
+ ;
+ }
+ default:
+ ;
+ }
+ return 0;
+
+ }
+
+ ///
+ /// Set current time point
+ ///
+ virtual void set_time(posix_time const &p)
+ {
+ from_time(static_cast<std::time_t>(p.seconds));
+ }
+ virtual posix_time get_time() const
+ {
+ posix_time pt = { time_, 0};
+ return pt;
+ }
+
+ ///
+ /// Set option for calendar, for future use
+ ///
+ virtual void set_option(calendar_option_type opt,int /*v*/)
+ {
+ switch(opt) {
+ case is_gregorian:
+ throw date_time_error("is_gregorian is not settable options for calendar");
+ case is_dst:
+ throw date_time_error("is_dst is not settable options for calendar");
+ default:
+ ;
+ }
+ }
+ ///
+ /// Get option for calendar, currently only check if it is Gregorian calendar
+ ///
+ virtual int get_option(calendar_option_type opt) const
+ {
+ switch(opt) {
+ case is_gregorian:
+ return 1;
+ case is_dst:
+ return tm_.tm_isdst == 1;
+ default:
+ return 0;
+ };
+ }
+
+ ///
+ /// Adjust period's \a p value by \a difference items using a update_type \a u.
+ /// Note: not all values are adjustable
+ ///
+ virtual void adjust_value(period::marks::period_mark p,update_type u,int difference)
+ {
+ switch(u) {
+ case move:
+ {
+ using namespace period::marks;
+ switch(p) {
+ case year: ///< Year, it is calendar specific
+ case extended_year: ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1.
+ tm_updated_.tm_year +=difference;
+ break;
+ case month:
+ tm_updated_.tm_mon +=difference;
+ break;
+ case day:
+ case day_of_year:
+ case day_of_week: ///< Day of week, starting from Sunday, [1..7]
+ case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
+ tm_updated_.tm_mday +=difference;
+ break;
+ case hour: ///< 24 clock hour [0..23]
+ case hour_12: ///< 12 clock hour [0..11]
+ tm_updated_.tm_hour += difference;
+ break;
+ case am_pm: ///< am or pm marker, [0..1]
+ tm_updated_.tm_hour += 12 * difference;
+ break;
+ case minute: ///< minute [0..59]
+ tm_updated_.tm_min += difference;
+ break;
+ case second:
+ tm_updated_.tm_sec += difference;
+ break;
+ case week_of_year: ///< The week number in the year
+ case week_of_month: ///< The week number withing current month
+ case day_of_week_in_month: ///< Original number of the day of the week in month.
+ tm_updated_.tm_mday +=difference * 7;
+ break;
+ default:
+ ; // Not all values are adjustable
+ }
+ normalized_ = false;
+ normalize();
+ }
+ break;
+ case roll:
+ { // roll
+ int cur_min = get_value(p,actual_minimum);
+ int cur_max = get_value(p,actual_maximum);
+ int max_diff = cur_max - cur_min + 1;
+ if(max_diff > 0) {
+ int value = get_value(p,current);
+ int addon = 0;
+ if(difference < 0)
+ addon = ((-difference/max_diff) + 1) * max_diff;
+ value = (value - cur_min + difference + addon) % max_diff + cur_min;
+ set_value(p,value);
+ normalize();
+ }
+ }
+ default:
+ ;
+ }
+ }
+
+ int get_diff(period::marks::period_mark p,int diff,gregorian_calendar const *other) const
+ {
+ if(diff == 0)
+ return 0;
+ hold_ptr<gregorian_calendar> self(clone());
+ self->adjust_value(p,move,diff);
+ if(diff > 0){
+ if(self->time_ > other->time_)
+ return diff - 1;
+ else
+ return diff;
+ }
+ else {
+ if(self->time_ < other->time_)
+ return diff + 1;
+ else
+ return diff;
+ }
+ }
+
+ ///
+ /// Calculate the difference between this calendar and \a other in \a p units
+ ///
+ virtual int difference(abstract_calendar const *other_cal,period::marks::period_mark p) const
+ {
+ hold_ptr<gregorian_calendar> keeper;
+ gregorian_calendar const *other = dynamic_cast<gregorian_calendar const *>(other_cal);
+ if(!other) {
+ keeper.reset(clone());
+ keeper->set_time(other_cal->get_time());
+ other = keeper.get();
+ }
+
+ int factor = 1; // for weeks vs days handling
+
+ using namespace period::marks;
+ switch(p) {
+ case era:
+ return 0;
+ case year:
+ case extended_year:
+ {
+ int diff = other->tm_.tm_year - tm_.tm_year;
+ return get_diff(period::marks::year,diff,other);
+ }
+ case month:
+ {
+ int diff = 12 * (other->tm_.tm_year - tm_.tm_year)
+ + other->tm_.tm_mon - tm_.tm_mon;
+ return get_diff(period::marks::month,diff,other);
+ }
+ case day_of_week_in_month:
+ case week_of_month:
+ case week_of_year:
+ factor = 7;
+ // fall
+ case day:
+ case day_of_year:
+ case day_of_week:
+ case day_of_week_local:
+ {
+ int diff = other->tm_.tm_yday - tm_.tm_yday;
+ if(other->tm_.tm_year != tm_.tm_year) {
+ diff += days_from_0(other->tm_.tm_year + 1900) -
+ days_from_0(tm_.tm_year + 1900);
+ }
+ return get_diff(period::marks::day,diff,other) / factor;
+ }
+ case am_pm:
+ return static_cast<int>( (other->time_ - time_) / (3600*12) );
+ case hour:
+ case hour_12:
+ return static_cast<int>( (other->time_ - time_) / 3600 );
+ case minute:
+ return static_cast<int>( (other->time_ - time_) / 60 );
+ case second:
+ return static_cast<int>( other->time_ - time_ );
+ default:
+ return 0;
+ };
+ }
+
+ ///
+ /// Set time zone, empty - use system
+ ///
+ virtual void set_timezone(std::string const &tz)
+ {
+ if(tz.empty()) {
+ is_local_ = true;
+ tzoff_ = 0;
+ }
+ else {
+ is_local_ = false;
+ tzoff_ = parse_tz(tz);
+ }
+ from_time(time_);
+ time_zone_name_ = tz;
+ }
+ virtual std::string get_timezone() const
+ {
+ return time_zone_name_;
+ }
+
+ virtual bool same(abstract_calendar const *other) const
+ {
+ gregorian_calendar const *gcal = dynamic_cast<gregorian_calendar const *>(other);
+ if(!gcal)
+ return false;
+ return
+ gcal->tzoff_ == tzoff_
+ && gcal->is_local_ == is_local_
+ && gcal->first_day_of_week_ == first_day_of_week_;
+ }
+
+ virtual ~gregorian_calendar()
+ {
+ }
+
+ private:
+
+ void from_time(std::time_t point)
+ {
+ std::time_t real_point = point + tzoff_;
+ std::tm *t = 0;
+ #ifdef BOOST_WINDOWS
+ // Windows uses TLS, thread safe
+ t = is_local_ ? localtime(&real_point) : gmtime(&real_point);
+ #else
+ std::tm tmp_tm;
+ t = is_local_ ? localtime_r(&real_point,&tmp_tm) : gmtime_r(&real_point,&tmp_tm);
+ #endif
+ if(!t) {
+ throw date_time_error("boost::locale::gregorian_calendar: invalid time point");
+ }
+ tm_ = *t;
+ tm_updated_ = *t;
+ normalized_ = true;
+ time_ = point;
+ }
+ int first_day_of_week_;
+ std::time_t time_;
+ std::tm tm_;
+ std::tm tm_updated_;
+ bool normalized_;
+ bool is_local_;
+ int tzoff_;
+ std::string time_zone_name_;
+
+ };
+
+ abstract_calendar *create_gregorian_calendar(std::string const &terr)
+ {
+ return new gregorian_calendar(terr);
+ }
+
+ class gregorian_facet : public calendar_facet {
+ public:
+ gregorian_facet(std::string const &terr,size_t refs = 0) :
+ calendar_facet(refs),
+ terr_(terr)
+ {
+ }
+ virtual abstract_calendar *create_calendar() const
+ {
+ return create_gregorian_calendar(terr_);
+ }
+ private:
+ std::string terr_;
+ };
+
+ std::locale install_gregorian_calendar(std::locale const &in,std::string const &terr)
+ {
+ return std::locale(in,new gregorian_facet(terr));
+ }
+
+
+} // util
+} // locale
+} //boost
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/util/gregorian.hpp b/src/boost/libs/locale/src/util/gregorian.hpp
new file mode 100644
index 000000000..dc8c5d591
--- /dev/null
+++ b/src/boost/libs/locale/src/util/gregorian.hpp
@@ -0,0 +1,25 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_SRC_UTIL_GREGORIAN_HPP
+#define BOOST_LOCALE_SRC_UTIL_GREGORIAN_HPP
+
+#include <locale>
+
+namespace boost {
+namespace locale {
+namespace util {
+
+ std::locale install_gregorian_calendar(std::locale const &in,std::string const &terr);
+
+} // util
+} // locale
+} //boost
+
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/util/iconv.hpp b/src/boost/libs/locale/src/util/iconv.hpp
new file mode 100644
index 000000000..3dc69fbc6
--- /dev/null
+++ b/src/boost/libs/locale/src/util/iconv.hpp
@@ -0,0 +1,58 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_ICONV_FIXER_HPP
+#define BOOST_LOCALE_ICONV_FIXER_HPP
+
+#include <iconv.h>
+
+namespace boost {
+ namespace locale {
+#if defined(__ICONV_F_HIDE_INVALID) && defined(__FreeBSD__)
+ extern "C" {
+ typedef size_t (*const_iconv_ptr_type)(iconv_t d,char const **in,size_t *insize,char **out,size_t *outsize,uint32_t,size_t *);
+ typedef size_t (*nonconst_iconv_ptr_type)(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize,uint32_t,size_t *);
+ }
+ inline size_t do_iconv(const_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize)
+ {
+ char const **rin = const_cast<char const **>(in);
+ return ptr(d,rin,insize,out,outsize,__ICONV_F_HIDE_INVALID,0);
+ }
+ inline size_t do_iconv(nonconst_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize)
+ {
+ return ptr(d,in,insize,out,outsize,__ICONV_F_HIDE_INVALID,0);
+ }
+ inline size_t call_iconv(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize)
+ {
+ char const **rin = const_cast<char const **>(in);
+ return do_iconv(__iconv, d, in,insize,out,outsize);
+ }
+#else
+ extern "C" {
+ typedef size_t (*gnu_iconv_ptr_type)(iconv_t d,char const **in,size_t *insize,char **out,size_t *outsize);
+ typedef size_t (*posix_iconv_ptr_type)(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize);
+ }
+ inline size_t do_iconv(gnu_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize)
+ {
+ char const **rin = const_cast<char const **>(in);
+ return ptr(d,rin,insize,out,outsize);
+ }
+ inline size_t do_iconv(posix_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize)
+ {
+ return ptr(d,in,insize,out,outsize);
+ }
+ inline size_t call_iconv(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize)
+ {
+ return do_iconv( iconv, d, in,insize,out,outsize);
+ }
+#endif
+
+ } // locale
+} // boost
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/util/info.cpp b/src/boost/libs/locale/src/util/info.cpp
new file mode 100644
index 000000000..67266354e
--- /dev/null
+++ b/src/boost/libs/locale/src/util/info.cpp
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <locale>
+#include <string>
+#include <ios>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/info.hpp>
+#include <boost/locale/util.hpp>
+#include <sstream>
+#include <stdlib.h>
+
+#include "locale_data.hpp"
+
+namespace boost {
+namespace locale {
+namespace util {
+ class simple_info : public info {
+ public:
+ simple_info(std::string const &name,size_t refs = 0) :
+ info(refs),
+ name_(name)
+ {
+ d.parse(name);
+ }
+ virtual std::string get_string_property(string_propery v) const
+ {
+ switch(v) {
+ case language_property:
+ return d.language;
+ case country_property:
+ return d.country;
+ case variant_property:
+ return d.variant;
+ case encoding_property:
+ return d.encoding;
+ case name_property:
+ return name_;
+ default:
+ return "";
+ };
+ }
+
+ virtual int get_integer_property(integer_property v) const
+ {
+ switch(v) {
+ case utf8_property:
+ return d.utf8;
+ default:
+ return 0;
+ }
+ }
+ private:
+ locale_data d;
+ std::string name_;
+ };
+
+ std::locale create_info(std::locale const &in,std::string const &name)
+ {
+ return std::locale(in,new simple_info(name));
+ }
+
+
+} // util
+} // locale
+} //boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/util/locale_data.cpp b/src/boost/libs/locale/src/util/locale_data.cpp
new file mode 100644
index 000000000..a0070d535
--- /dev/null
+++ b/src/boost/libs/locale/src/util/locale_data.cpp
@@ -0,0 +1,113 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include "locale_data.hpp"
+#include "../encoding/conv.hpp"
+#include <string>
+
+namespace boost {
+namespace locale {
+namespace util {
+ void locale_data::parse(std::string const &locale_name)
+ {
+ language = "C";
+ country.clear();
+ variant.clear();
+ encoding = "us-ascii";
+ utf8=false;
+ parse_from_lang(locale_name);
+ }
+
+ void locale_data::parse_from_lang(std::string const &locale_name)
+ {
+ size_t end = locale_name.find_first_of("-_@.");
+ std::string tmp = locale_name.substr(0,end);
+ if(tmp.empty())
+ return;
+ for(unsigned i=0;i<tmp.size();i++) {
+ if('A' <= tmp[i] && tmp[i]<='Z')
+ tmp[i]=tmp[i]-'A'+'a';
+ else if(tmp[i] < 'a' || 'z' < tmp[i])
+ return;
+ }
+ language = tmp;
+ if(end >= locale_name.size())
+ return;
+
+ if(locale_name[end] == '-' || locale_name[end]=='_') {
+ parse_from_country(locale_name.substr(end+1));
+ }
+ else if(locale_name[end] == '.') {
+ parse_from_encoding(locale_name.substr(end+1));
+ }
+ else if(locale_name[end] == '@') {
+ parse_from_variant(locale_name.substr(end+1));
+ }
+ }
+
+ void locale_data::parse_from_country(std::string const &locale_name)
+ {
+ size_t end = locale_name.find_first_of("@.");
+ std::string tmp = locale_name.substr(0,end);
+ if(tmp.empty())
+ return;
+ for(unsigned i=0;i<tmp.size();i++) {
+ if('a' <= tmp[i] && tmp[i]<='z')
+ tmp[i]=tmp[i]-'a'+'A';
+ else if(tmp[i] < 'A' || 'Z' < tmp[i])
+ return;
+ }
+
+ country = tmp;
+
+ if(end >= locale_name.size())
+ return;
+ else if(locale_name[end] == '.') {
+ parse_from_encoding(locale_name.substr(end+1));
+ }
+ else if(locale_name[end] == '@') {
+ parse_from_variant(locale_name.substr(end+1));
+ }
+ }
+
+ void locale_data::parse_from_encoding(std::string const &locale_name)
+ {
+ size_t end = locale_name.find_first_of("@");
+ std::string tmp = locale_name.substr(0,end);
+ if(tmp.empty())
+ return;
+ for(unsigned i=0;i<tmp.size();i++) {
+ if('A' <= tmp[i] && tmp[i]<='Z')
+ tmp[i]=tmp[i]-'A'+'a';
+ }
+ encoding = tmp;
+
+ utf8 = conv::impl::normalize_encoding(encoding.c_str()) == "utf8";
+
+ if(end >= locale_name.size())
+ return;
+
+ if(locale_name[end] == '@') {
+ parse_from_variant(locale_name.substr(end+1));
+ }
+ }
+
+ void locale_data::parse_from_variant(std::string const &locale_name)
+ {
+ variant = locale_name;
+ for(unsigned i=0;i<variant.size();i++) {
+ if('A' <= variant[i] && variant[i]<='Z')
+ variant[i]=variant[i]-'A'+'a';
+ }
+ }
+
+} // util
+} // locale
+} // boost
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/util/locale_data.hpp b/src/boost/libs/locale/src/util/locale_data.hpp
new file mode 100644
index 000000000..5b929f148
--- /dev/null
+++ b/src/boost/libs/locale/src/util/locale_data.hpp
@@ -0,0 +1,47 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_UTIL_LOCALE_DATA_HPP
+#define BOOST_LOCALE_IMPL_UTIL_LOCALE_DATA_HPP
+
+#include <string>
+
+namespace boost {
+ namespace locale {
+ namespace util {
+
+ class locale_data {
+ public:
+ locale_data() :
+ language("C"),
+ encoding("us-ascii"),
+ utf8(false)
+ {
+ }
+
+ std::string language;
+ std::string country;
+ std::string variant;
+ std::string encoding;
+ bool utf8;
+
+ void parse(std::string const &locale_name);
+
+ private:
+
+ void parse_from_lang(std::string const &locale_name);
+ void parse_from_country(std::string const &locale_name);
+ void parse_from_encoding(std::string const &locale_name);
+ void parse_from_variant(std::string const &locale_name);
+ };
+
+ } // util
+ } // locale
+} // boost
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/util/numeric.hpp b/src/boost/libs/locale/src/util/numeric.hpp
new file mode 100644
index 000000000..892427dfc
--- /dev/null
+++ b/src/boost/libs/locale/src/util/numeric.hpp
@@ -0,0 +1,393 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_UTIL_NUMERIC_HPP
+#define BOOST_LOCALE_IMPL_UTIL_NUMERIC_HPP
+#include <locale>
+#include <string>
+#include <ios>
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/info.hpp>
+#include <sstream>
+#include <vector>
+#include <ctime>
+#include <stdlib.h>
+
+#include "timezone.hpp"
+
+// This is internal header so disable crappy "unsecure functions" for all
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4996)
+#endif
+
+
+namespace boost {
+namespace locale {
+namespace util {
+
+template<typename CharType>
+struct formatting_size_traits {
+ static size_t size(std::basic_string<CharType> const &s,std::locale const &/*l*/)
+ {
+ return s.size();
+ }
+};
+
+template<>
+struct formatting_size_traits<char> {
+ static size_t size(std::string const &s,std::locale const &l)
+ {
+ if(!std::has_facet<info>(l))
+ return s.size();
+ if(!std::use_facet<info>(l).utf8())
+ return s.size();
+ // count code points, poor man's text size
+ size_t res = 0;
+ for(size_t i=0;i<s.size();i++) {
+ unsigned char c = s[i];
+ if(c <= 127)
+ res ++;
+ else if ((c & 0xC0) == 0xC0) { // first UTF-8 byte
+ res ++;
+ }
+ }
+ return res;
+ }
+};
+
+
+
+template<typename CharType>
+class base_num_format : public std::num_put<CharType>
+{
+public:
+ typedef typename std::num_put<CharType>::iter_type iter_type;
+ typedef std::basic_string<CharType> string_type;
+ typedef CharType char_type;
+
+ base_num_format(size_t refs = 0) :
+ std::num_put<CharType>(refs)
+ {
+ }
+protected:
+
+
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, unsigned long val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, double val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long double val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+
+ #ifndef BOOST_NO_LONG_LONG
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long long val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ virtual iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, unsigned long long val) const
+ {
+ return do_real_put(out,ios,fill,val);
+ }
+ #endif
+
+
+private:
+
+
+
+ template<typename ValueType>
+ iter_type do_real_put (iter_type out, std::ios_base &ios, char_type fill, ValueType val) const
+ {
+ typedef std::num_put<char_type> super;
+
+ ios_info &info=ios_info::get(ios);
+
+ switch(info.display_flags()) {
+ case flags::posix:
+ {
+ typedef std::basic_ostringstream<char_type> sstream_type;
+ sstream_type ss;
+ ss.imbue(std::locale::classic());
+ ss.flags(ios.flags());
+ ss.precision(ios.precision());
+ ss.width(ios.width());
+ iter_type ret_ptr = super::do_put(out,ss,fill,val);
+ ios.width(0);
+ return ret_ptr;
+ }
+ case flags::date:
+ return format_time(out,ios,fill,static_cast<std::time_t>(val),'x');
+ case flags::time:
+ return format_time(out,ios,fill,static_cast<std::time_t>(val),'X');
+ case flags::datetime:
+ return format_time(out,ios,fill,static_cast<std::time_t>(val),'c');
+ case flags::strftime:
+ return format_time(out,ios,fill,static_cast<std::time_t>(val),info.date_time_pattern<char_type>());
+ case flags::currency:
+ {
+ bool nat = info.currency_flags()==flags::currency_default
+ || info.currency_flags() == flags::currency_national;
+ bool intl = !nat;
+ return do_format_currency(intl,out,ios,fill,static_cast<long double>(val));
+ }
+
+ case flags::number:
+ case flags::percent:
+ case flags::spellout:
+ case flags::ordinal:
+ default:
+ return super::do_put(out,ios,fill,val);
+ }
+ }
+
+ virtual iter_type do_format_currency(bool intl,iter_type out,std::ios_base &ios,char_type fill,long double val) const
+ {
+ if(intl)
+ return format_currency<true>(out,ios,fill,val);
+ else
+ return format_currency<false>(out,ios,fill,val);
+ }
+
+ template<bool intl>
+ iter_type format_currency(iter_type out,std::ios_base &ios,char_type fill,long double val) const
+ {
+ std::locale loc = ios.getloc();
+ int digits = std::use_facet<std::moneypunct<char_type,intl> >(loc).frac_digits();
+ while(digits > 0) {
+ val*=10;
+ digits --;
+ }
+ std::ios_base::fmtflags f=ios.flags();
+ ios.flags(f | std::ios_base::showbase);
+ out = std::use_facet<std::money_put<char_type> >(loc).put(out,intl,ios,fill,val);
+ ios.flags(f);
+ return out;
+ }
+
+ iter_type format_time(iter_type out,std::ios_base &ios,char_type fill,std::time_t time,char c) const
+ {
+ string_type fmt;
+ fmt+=char_type('%');
+ fmt+=char_type(c);
+ return format_time(out,ios,fill,time,fmt);
+ }
+
+ iter_type format_time(iter_type out,std::ios_base &ios,char_type fill,std::time_t time,string_type const &format) const
+ {
+ std::string tz = ios_info::get(ios).time_zone();
+ std::tm tm;
+ #if defined(__linux) || defined(__FreeBSD__) || defined(__APPLE__)
+ std::vector<char> tmp_buf(tz.c_str(),tz.c_str()+tz.size()+1);
+ #endif
+ if(tz.empty()) {
+ #ifdef BOOST_WINDOWS
+ /// Windows uses TLS
+ tm = *localtime(&time);
+ #else
+ localtime_r(&time,&tm);
+ #endif
+ }
+ else {
+ int gmtoff = parse_tz(tz);
+ time+=gmtoff;
+ #ifdef BOOST_WINDOWS
+ /// Windows uses TLS
+ tm = *gmtime(&time);
+ #else
+ gmtime_r(&time,&tm);
+ #endif
+
+ #if defined(__linux) || defined(__FreeBSD__) || defined(__APPLE__)
+ // These have extra fields to specify timezone
+ if(gmtoff!=0) {
+ // bsd and apple want tm_zone be non-const
+ tm.tm_zone=&tmp_buf.front();
+ tm.tm_gmtoff = gmtoff;
+ }
+ #endif
+ }
+ std::basic_ostringstream<char_type> tmp_out;
+ std::use_facet<std::time_put<char_type> >(ios.getloc()).put(tmp_out,tmp_out,fill,&tm,format.c_str(),format.c_str()+format.size());
+ string_type str = tmp_out.str();
+ std::streamsize on_left=0,on_right = 0;
+ std::streamsize points =
+ formatting_size_traits<char_type>::size(str,ios.getloc());
+ if(points < ios.width()) {
+ std::streamsize n = ios.width() - points;
+
+ std::ios_base::fmtflags flags = ios.flags() & std::ios_base::adjustfield;
+
+ //
+ // we do not really know internal point, so we assume that it does not
+ // exist. so according to the standard field should be right aligned
+ //
+ if(flags != std::ios_base::left)
+ on_left = n;
+ on_right = n - on_left;
+ }
+ while(on_left > 0) {
+ *out++ = fill;
+ on_left--;
+ }
+ std::copy(str.begin(),str.end(),out);
+ while(on_right > 0) {
+ *out++ = fill;
+ on_right--;
+ }
+ ios.width(0);
+ return out;
+ }
+
+}; /// num_format
+
+
+template<typename CharType>
+class base_num_parse : public std::num_get<CharType>
+{
+public:
+ base_num_parse(size_t refs = 0) :
+ std::num_get<CharType>(refs)
+ {
+ }
+protected:
+ typedef typename std::num_get<CharType>::iter_type iter_type;
+ typedef std::basic_string<CharType> string_type;
+ typedef CharType char_type;
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned short &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned int &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,float &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,double &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long double &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ #ifndef BOOST_NO_LONG_LONG
+ virtual iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long long &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ virtual iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long long &val) const
+ {
+ return do_real_get(in,end,ios,err,val);
+ }
+
+ #endif
+
+private:
+
+ template<typename ValueType>
+ iter_type do_real_get(iter_type in,iter_type end,std::ios_base &ios,std::ios_base::iostate &err,ValueType &val) const
+ {
+ typedef std::num_get<char_type> super;
+
+ ios_info &info=ios_info::get(ios);
+
+ switch(info.display_flags()) {
+ case flags::posix:
+ {
+ std::stringstream ss;
+ ss.imbue(std::locale::classic());
+ ss.flags(ios.flags());
+ ss.precision(ios.precision());
+ return super::do_get(in,end,ss,err,val);
+ }
+ case flags::currency:
+ {
+ long double ret_val = 0;
+ if(info.currency_flags()==flags::currency_default || info.currency_flags() == flags::currency_national)
+ in = parse_currency<false>(in,end,ios,err,ret_val);
+ else
+ in = parse_currency<true>(in,end,ios,err,ret_val);
+ if(!(err & std::ios_base::failbit))
+ val = static_cast<ValueType>(ret_val);
+ return in;
+ }
+
+ // date-time parsing is not supported
+ // due to buggy standard
+ case flags::date:
+ case flags::time:
+ case flags::datetime:
+ case flags::strftime:
+
+ case flags::number:
+ case flags::percent:
+ case flags::spellout:
+ case flags::ordinal:
+ default:
+ return super::do_get(in,end,ios,err,val);
+ }
+ }
+
+ template<bool intl>
+ iter_type parse_currency(iter_type in,iter_type end,std::ios_base &ios,std::ios_base::iostate &err,long double &val) const
+ {
+ std::locale loc = ios.getloc();
+ int digits = std::use_facet<std::moneypunct<char_type,intl> >(loc).frac_digits();
+ long double rval;
+ in = std::use_facet<std::money_get<char_type> >(loc).get(in,end,intl,ios,err,rval);
+ if(!(err & std::ios::failbit)) {
+ while(digits > 0) {
+ rval/=10;
+ digits --;
+ }
+ val = rval;
+ }
+ return in;
+ }
+
+
+};
+
+} // util
+} // locale
+} //boost
+
+
+
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/util/timezone.hpp b/src/boost/libs/locale/src/util/timezone.hpp
new file mode 100644
index 000000000..07a8c8ca2
--- /dev/null
+++ b/src/boost/libs/locale/src/util/timezone.hpp
@@ -0,0 +1,53 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_UTIL_TIMEZONE_HPP
+#define BOOST_LOCALE_IMPL_UTIL_TIMEZONE_HPP
+#include <string>
+#include <stdlib.h>
+#include <string.h>
+namespace boost {
+namespace locale {
+namespace util {
+ inline int parse_tz(std::string const &tz)
+ {
+ int gmtoff = 0;
+ std::string ltz;
+ for(unsigned i=0;i<tz.size();i++) {
+ if('a' <= tz[i] && tz[i] <= 'z')
+ ltz += tz[i]-'a' + 'A';
+ else if(tz[i]==' ')
+ ;
+ else
+ ltz+=tz[i];
+ }
+ if(ltz.compare(0,3,"GMT")!=0 && ltz.compare(0,3,"UTC")!=0)
+ return 0;
+ if(ltz.size()<=3)
+ return 0;
+ char const *begin = ltz.c_str()+3;
+ char *end=0;
+ int hours = strtol(begin,&end,10);
+ if(end != begin) {
+ gmtoff+=hours * 3600;
+ }
+ if(*end==':') {
+ begin=end+1;
+ int minutes = strtol(begin,&end,10);
+ if(end!=begin)
+ gmtoff+=minutes * 60;
+ }
+ return gmtoff;
+ }
+
+} // util
+} // locale
+} //boost
+
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/win32/all_generator.hpp b/src/boost/libs/locale/src/win32/all_generator.hpp
new file mode 100644
index 000000000..083d05627
--- /dev/null
+++ b/src/boost/libs/locale/src/win32/all_generator.hpp
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_WIN32_ALL_GENERATOR_HPP
+#define BOOST_LOCALE_IMPL_WIN32_ALL_GENERATOR_HPP
+
+#include <boost/locale/generator.hpp>
+#include <vector>
+#include <locale.h>
+
+namespace boost {
+ namespace locale {
+ namespace impl_win {
+
+ class winlocale;
+
+ std::locale create_convert( std::locale const &in,
+ winlocale const &lc,
+ character_facet_type type);
+
+ std::locale create_collate( std::locale const &in,
+ winlocale const &lc,
+ character_facet_type type);
+
+ std::locale create_formatting( std::locale const &in,
+ winlocale const &lc,
+ character_facet_type type);
+
+ std::locale create_parsing( std::locale const &in,
+ winlocale const &lc,
+ character_facet_type type);
+
+ std::locale create_codecvt( std::locale const &in,
+ character_facet_type type);
+
+ }
+ }
+}
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/win32/api.hpp b/src/boost/libs/locale/src/win32/api.hpp
new file mode 100644
index 000000000..a41fbde5e
--- /dev/null
+++ b/src/boost/libs/locale/src/win32/api.hpp
@@ -0,0 +1,357 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_WIN32_API_HPP
+#define BOOST_LOCALE_IMPL_WIN32_API_HPP
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <ctime>
+
+#include "lcid.hpp"
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#ifndef UNICODE
+#define UNICODE
+#endif
+#include <windows.h>
+
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/collator.hpp>
+
+#define BOOST_LOCALE_WINDOWS_2000_API
+
+#if defined(_WIN32_NT) && _WIN32_NT >= 0x600 && !defined(BOOST_LOCALE_WINDOWS_2000_API)
+#define BOOST_LOCALE_WINDOWS_VISTA_API
+#else
+#define BOOST_LOCALE_WINDOWS_2000_API
+#endif
+
+namespace boost {
+namespace locale {
+namespace impl_win {
+
+ struct numeric_info {
+ std::wstring thousands_sep;
+ std::wstring decimal_point;
+ std::string grouping;
+ };
+
+ inline DWORD collation_level_to_flag(collator_base::level_type level)
+ {
+ DWORD flags;
+ switch(level) {
+ case collator_base::primary:
+ flags = NORM_IGNORESYMBOLS | NORM_IGNORECASE | NORM_IGNORENONSPACE;
+ break;
+ case collator_base::secondary:
+ flags = NORM_IGNORESYMBOLS | NORM_IGNORECASE;
+ break;
+ case collator_base::tertiary:
+ flags = NORM_IGNORESYMBOLS;
+ break;
+ default:
+ flags = 0;
+ }
+ return flags;
+ }
+
+
+
+ #ifdef BOOST_LOCALE_WINDOWS_2000_API
+
+ class winlocale{
+ public:
+ winlocale() :
+ lcid(0)
+ {
+ }
+
+ winlocale(std::string const &name)
+ {
+ lcid = locale_to_lcid(name);
+ }
+
+ unsigned lcid;
+
+ bool is_c() const
+ {
+ return lcid == 0;
+ }
+ };
+
+
+ ////////////////////////////////////////////////////////////////////////
+ ///
+ /// Number Format
+ ///
+ ////////////////////////////////////////////////////////////////////////
+
+ inline numeric_info wcsnumformat_l(winlocale const &l)
+ {
+ numeric_info res;
+ res.decimal_point = L'.';
+ unsigned lcid = l.lcid;
+
+ if(lcid == 0)
+ return res;
+
+ // limits according to MSDN
+ static const int th_size = 4;
+ static const int de_size = 4;
+ static const int gr_size = 10;
+
+ wchar_t th[th_size]={0};
+ wchar_t de[de_size]={0};
+ wchar_t gr[gr_size]={0};
+
+ if( GetLocaleInfoW(lcid,LOCALE_STHOUSAND,th,th_size)==0
+ || GetLocaleInfoW(lcid,LOCALE_SDECIMAL ,de,de_size)==0
+ || GetLocaleInfoW(lcid,LOCALE_SGROUPING,gr,gr_size)==0)
+ {
+ return res;
+ }
+ res.decimal_point = de;
+ res.thousands_sep = th;
+ bool inf_group = false;
+ for(unsigned i=0;gr[i];i++) {
+ if(gr[i]==L';')
+ continue;
+ if(L'1'<= gr[i] && gr[i]<=L'9') {
+ res.grouping += char(gr[i]-L'0');
+ }
+ else if(gr[i]==L'0')
+ inf_group = true;
+ }
+ if(!inf_group) {
+ if(std::numeric_limits<char>::is_signed) {
+ res.grouping+=std::numeric_limits<char>::min();
+ }
+ else {
+ res.grouping+=std::numeric_limits<char>::max();
+ }
+ }
+ return res;
+ }
+
+ inline std::wstring win_map_string_l(unsigned flags,wchar_t const *begin,wchar_t const *end,winlocale const &l)
+ {
+ std::wstring res;
+ int len = LCMapStringW(l.lcid,flags,begin,end-begin,0,0);
+ if(len == 0)
+ return res;
+ std::vector<wchar_t> buf(len+1);
+ int l2 = LCMapStringW(l.lcid,flags,begin,end-begin,&buf.front(),buf.size());
+ res.assign(&buf.front(),l2);
+ return res;
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ ///
+ /// Collation
+ ///
+ ////////////////////////////////////////////////////////////////////////
+
+
+ inline int wcscoll_l( collator_base::level_type level,
+ wchar_t const *lb,wchar_t const *le,
+ wchar_t const *rb,wchar_t const *re,
+ winlocale const &l)
+ {
+ return CompareStringW(l.lcid,collation_level_to_flag(level),lb,le-lb,rb,re-rb) - 2;
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////
+ ///
+ /// Money Format
+ ///
+ ////////////////////////////////////////////////////////////////////////
+
+ inline std::wstring wcsfmon_l(double value,winlocale const &l)
+ {
+ std::wostringstream ss;
+ ss.imbue(std::locale::classic());
+
+ ss << std::setprecision(std::numeric_limits<double>::digits10+1) << value;
+ std::wstring sval = ss.str();
+ int len = GetCurrencyFormatW(l.lcid,0,sval.c_str(),0,0,0);
+ std::vector<wchar_t> buf(len+1);
+ GetCurrencyFormatW(l.lcid,0,sval.c_str(),0,&buf.front(),len);
+ return &buf.front();
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ ///
+ /// Time Format
+ ///
+ ////////////////////////////////////////////////////////////////////////
+
+
+ inline std::wstring wcs_format_date_l(wchar_t const *format,SYSTEMTIME const *tm,winlocale const &l)
+ {
+ int len = GetDateFormatW(l.lcid,0,tm,format,0,0);
+ std::vector<wchar_t> buf(len+1);
+ GetDateFormatW(l.lcid,0,tm,format,&buf.front(),len);
+ return &buf.front();
+ }
+
+ inline std::wstring wcs_format_time_l(wchar_t const *format,SYSTEMTIME const *tm,winlocale const &l)
+ {
+ int len = GetTimeFormatW(l.lcid,0,tm,format,0,0);
+ std::vector<wchar_t> buf(len+1);
+ GetTimeFormatW(l.lcid,0,tm,format,&buf.front(),len);
+ return &buf.front();
+ }
+
+ inline std::wstring wcsfold(wchar_t const *begin,wchar_t const *end)
+ {
+ winlocale l;
+ l.lcid = 0x0409; // en-US
+ return win_map_string_l(LCMAP_LOWERCASE,begin,end,l);
+ }
+
+ inline std::wstring wcsnormalize(norm_type norm,wchar_t const *begin,wchar_t const *end)
+ {
+ // We use FoldString, under Vista it actually does normalization;
+ // under XP and below it does something similar, half job, better then nothing
+ unsigned flags = 0;
+ switch(norm) {
+ case norm_nfd:
+ flags = MAP_COMPOSITE;
+ break;
+ case norm_nfc:
+ flags = MAP_PRECOMPOSED;
+ break;
+ case norm_nfkd:
+ flags = MAP_FOLDCZONE;
+ break;
+ case norm_nfkc:
+ flags = MAP_FOLDCZONE | MAP_COMPOSITE;
+ break;
+ default:
+ flags = MAP_PRECOMPOSED;
+ }
+
+ int len = FoldStringW(flags,begin,end-begin,0,0);
+ if(len == 0)
+ return std::wstring();
+ std::vector<wchar_t> v(len+1);
+ len = FoldStringW(flags,begin,end-begin,&v.front(),len+1);
+ return std::wstring(&v.front(),len);
+ }
+
+
+ #endif
+
+ inline std::wstring wcsxfrm_l(collator_base::level_type level,wchar_t const *begin,wchar_t const *end,winlocale const &l)
+ {
+ int flag = LCMAP_SORTKEY | collation_level_to_flag(level);
+
+ return win_map_string_l(flag,begin,end,l);
+ }
+
+ inline std::wstring towupper_l(wchar_t const *begin,wchar_t const *end,winlocale const &l)
+ {
+ return win_map_string_l(LCMAP_UPPERCASE | LCMAP_LINGUISTIC_CASING,begin,end,l);
+ }
+
+ inline std::wstring towlower_l(wchar_t const *begin,wchar_t const *end,winlocale const &l)
+ {
+ return win_map_string_l(LCMAP_LOWERCASE | LCMAP_LINGUISTIC_CASING,begin,end,l);
+ }
+
+ inline std::wstring wcsftime_l(char c,std::tm const *tm,winlocale const &l)
+ {
+ SYSTEMTIME wtm=SYSTEMTIME();
+ wtm.wYear = tm->tm_year + 1900;
+ wtm.wMonth = tm->tm_mon+1;
+ wtm.wDayOfWeek = tm->tm_wday;
+ wtm.wDay = tm->tm_mday;
+ wtm.wHour = tm->tm_hour;
+ wtm.wMinute = tm->tm_min;
+ wtm.wSecond = tm->tm_sec;
+ switch(c) {
+ case 'a': // Abbr Weekday
+ return wcs_format_date_l(L"ddd",&wtm,l);
+ case 'A': // Full Weekday
+ return wcs_format_date_l(L"dddd",&wtm,l);
+ case 'b': // Abbr Month
+ return wcs_format_date_l(L"MMM",&wtm,l);
+ case 'B': // Full Month
+ return wcs_format_date_l(L"MMMM",&wtm,l);
+ case 'c': // DateTile Full
+ return wcs_format_date_l(0,&wtm,l) + L" " + wcs_format_time_l(0,&wtm,l);
+ // not supported by WIN ;(
+ // case 'C': // Century -> 1980 -> 19
+ // retur
+ case 'd': // Day of Month [01,31]
+ return wcs_format_date_l(L"dd",&wtm,l);
+ case 'D': // %m/%d/%y
+ return wcs_format_date_l(L"MM/dd/yy",&wtm,l);
+ case 'e': // Day of Month [1,31]
+ return wcs_format_date_l(L"d",&wtm,l);
+ case 'h': // == b
+ return wcs_format_date_l(L"MMM",&wtm,l);
+ case 'H': // 24 clock hour 00,23
+ return wcs_format_time_l(L"HH",&wtm,l);
+ case 'I': // 12 clock hour 01,12
+ return wcs_format_time_l(L"hh",&wtm,l);
+ /*
+ case 'j': // day of year 001,366
+ return "D";*/
+ case 'm': // month as [01,12]
+ return wcs_format_date_l(L"MM",&wtm,l);
+ case 'M': // minute [00,59]
+ return wcs_format_time_l(L"mm",&wtm,l);
+ case 'n': // \n
+ return L"\n";
+ case 'p': // am-pm
+ return wcs_format_time_l(L"tt",&wtm,l);
+ case 'r': // time with AM/PM %I:%M:%S %p
+ return wcs_format_time_l(L"hh:mm:ss tt",&wtm,l);
+ case 'R': // %H:%M
+ return wcs_format_time_l(L"HH:mm",&wtm,l);
+ case 'S': // second [00,61]
+ return wcs_format_time_l(L"ss",&wtm,l);
+ case 't': // \t
+ return L"\t";
+ case 'T': // %H:%M:%S
+ return wcs_format_time_l(L"HH:mm:ss",&wtm,l);
+/* case 'u': // weekday 1,7 1=Monday
+ case 'U': // week number of year [00,53] Sunday first
+ case 'V': // week number of year [01,53] Moday first
+ case 'w': // weekday 0,7 0=Sunday
+ case 'W': // week number of year [00,53] Moday first, */
+ case 'x': // Date
+ return wcs_format_date_l(0,&wtm,l);
+ case 'X': // Time
+ return wcs_format_time_l(0,&wtm,l);
+ case 'y': // Year [00-99]
+ return wcs_format_date_l(L"yy",&wtm,l);
+ case 'Y': // Year 1998
+ return wcs_format_date_l(L"yyyy",&wtm,l);
+ case '%': // %
+ return L"%";
+ default:
+ return L"";
+ }
+ }
+
+
+
+} // win
+} // locale
+} // boost
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/src/win32/collate.cpp b/src/boost/libs/locale/src/win32/collate.cpp
new file mode 100644
index 000000000..40e8c3d21
--- /dev/null
+++ b/src/boost/libs/locale/src/win32/collate.cpp
@@ -0,0 +1,127 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <locale>
+#include <string>
+#include <ios>
+#include <boost/locale/encoding.hpp>
+#include <boost/locale/generator.hpp>
+#include "api.hpp"
+#include "../shared/mo_hash.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_win {
+
+class utf8_collator : public collator<char> {
+public:
+ utf8_collator(winlocale lc,size_t refs = 0) :
+ collator<char>(refs),
+ lc_(lc)
+ {
+ }
+ virtual int do_compare(collator_base::level_type level,char const *lb,char const *le,char const *rb,char const *re) const
+ {
+ std::wstring l=conv::to_utf<wchar_t>(lb,le,"UTF-8");
+ std::wstring r=conv::to_utf<wchar_t>(rb,re,"UTF-8");
+ return wcscoll_l(level,l.c_str(),l.c_str()+l.size(),r.c_str(),r.c_str()+r.size(),lc_);
+ }
+ virtual long do_hash(collator_base::level_type level,char const *b,char const *e) const
+ {
+ std::string key = do_transform(level,b,e);
+ return gnu_gettext::pj_winberger_hash_function(key.c_str(),key.c_str() + key.size());
+ }
+ virtual std::string do_transform(collator_base::level_type level,char const *b,char const *e) const
+ {
+ std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8");
+ std::wstring wkey = wcsxfrm_l(level,tmp.c_str(),tmp.c_str()+tmp.size(),lc_);
+ std::string key;
+ if(sizeof(wchar_t)==2)
+ key.reserve(wkey.size()*2);
+ else
+ key.reserve(wkey.size()*3);
+ for(unsigned i=0;i<wkey.size();i++) {
+ if(sizeof(wchar_t)==2) {
+ uint16_t tv = static_cast<uint16_t>(wkey[i]);
+ key += char(tv >> 8);
+ key += char(tv & 0xFF);
+ }
+ else { // 4
+ uint32_t tv = static_cast<uint32_t>(wkey[i]);
+ // 21 bit
+ key += char((tv >> 16) & 0xFF);
+ key += char((tv >> 8) & 0xFF);
+ key += char(tv & 0xFF);
+ }
+ }
+ return key;
+ }
+private:
+ winlocale lc_;
+};
+
+
+class utf16_collator : public collator<wchar_t> {
+public:
+ typedef std::collate<wchar_t> wfacet;
+ utf16_collator(winlocale lc,size_t refs = 0) :
+ collator<wchar_t>(refs),
+ lc_(lc)
+ {
+ }
+ virtual int do_compare(collator_base::level_type level,wchar_t const *lb,wchar_t const *le,wchar_t const *rb,wchar_t const *re) const
+ {
+ return wcscoll_l(level,lb,le,rb,re,lc_);
+ }
+ virtual long do_hash(collator_base::level_type level,wchar_t const *b,wchar_t const *e) const
+ {
+ std::wstring key = do_transform(level,b,e);
+ char const *begin = reinterpret_cast<char const *>(key.c_str());
+ char const *end = begin + key.size()*sizeof(wchar_t);
+ return gnu_gettext::pj_winberger_hash_function(begin,end);
+ }
+ virtual std::wstring do_transform(collator_base::level_type level,wchar_t const *b,wchar_t const *e) const
+ {
+ return wcsxfrm_l(level,b,e,lc_);
+ }
+private:
+ winlocale lc_;
+};
+
+
+std::locale create_collate( std::locale const &in,
+ winlocale const &lc,
+ character_facet_type type)
+{
+ if(lc.is_c()) {
+ switch(type) {
+ case char_facet:
+ return std::locale(in,new std::collate_byname<char>("C"));
+ case wchar_t_facet:
+ return std::locale(in,new std::collate_byname<wchar_t>("C"));
+ }
+ }
+ else {
+ switch(type) {
+ case char_facet:
+ return std::locale(in,new utf8_collator(lc));
+ case wchar_t_facet:
+ return std::locale(in,new utf16_collator(lc));
+ }
+ }
+ return in;
+}
+
+
+} // impl_std
+} // locale
+} //boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/win32/converter.cpp b/src/boost/libs/locale/src/win32/converter.cpp
new file mode 100644
index 000000000..fffb0c7b8
--- /dev/null
+++ b/src/boost/libs/locale/src/win32/converter.cpp
@@ -0,0 +1,106 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+
+#include <locale>
+#include <stdexcept>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/encoding.hpp>
+#include <vector>
+#include <string.h>
+#include "api.hpp"
+#include "all_generator.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_win {
+
+class utf16_converter : public converter<wchar_t>
+{
+public:
+ utf16_converter(winlocale const &lc,size_t refs = 0) :
+ converter<wchar_t>(refs),
+ lc_(lc)
+ {
+ }
+ virtual std::wstring convert(converter_base::conversion_type how,wchar_t const *begin,wchar_t const *end,int flags = 0) const
+ {
+ switch(how) {
+ case converter_base::upper_case:
+ return towupper_l(begin,end,lc_);
+ case converter_base::lower_case:
+ return towlower_l(begin,end,lc_);
+ case converter_base::case_folding:
+ return wcsfold(begin,end);
+ case converter_base::normalization:
+ return wcsnormalize(static_cast<norm_type>(flags),begin,end);
+ default:
+ return std::wstring(begin,end-begin);
+ }
+ }
+private:
+ winlocale lc_;
+};
+
+class utf8_converter : public converter<char> {
+public:
+ utf8_converter(winlocale const &lc,size_t refs = 0) :
+ converter<char>(refs),
+ lc_(lc)
+ {
+ }
+ virtual std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int flags = 0) const
+ {
+ std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8");
+ wchar_t const *wb=tmp.c_str();
+ wchar_t const *we=wb+tmp.size();
+
+ std::wstring res;
+
+ switch(how) {
+ case upper_case:
+ res = towupper_l(wb,we,lc_);
+ break;
+ case lower_case:
+ res = towlower_l(wb,we,lc_);
+ break;
+ case case_folding:
+ res = wcsfold(wb,we);
+ break;
+ case normalization:
+ res = wcsnormalize(static_cast<norm_type>(flags),wb,we);
+ break;
+ default:
+ res = tmp; // make gcc happy
+ }
+ return conv::from_utf(res,"UTF-8");
+ }
+private:
+ winlocale lc_;
+};
+
+std::locale create_convert( std::locale const &in,
+ winlocale const &lc,
+ character_facet_type type)
+{
+ switch(type) {
+ case char_facet:
+ return std::locale(in,new utf8_converter(lc));
+ case wchar_t_facet:
+ return std::locale(in,new utf16_converter(lc));
+ default:
+ return in;
+ }
+}
+
+
+} // namespace impl_win32
+} // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/win32/lcid.cpp b/src/boost/libs/locale/src/win32/lcid.cpp
new file mode 100644
index 000000000..67542e6c6
--- /dev/null
+++ b/src/boost/libs/locale/src/win32/lcid.cpp
@@ -0,0 +1,127 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include "lcid.hpp"
+#include <string.h>
+#include <string>
+#include <sstream>
+#include <map>
+
+#include "../util/locale_data.hpp"
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <windows.h>
+
+#include <boost/thread/mutex.hpp>
+
+namespace boost {
+namespace locale {
+namespace impl_win {
+
+typedef std::map<std::string,unsigned> table_type;
+
+static table_type * volatile table = 0;
+
+boost::mutex &lcid_table_mutex()
+{
+ static boost::mutex m;
+ return m;
+}
+
+table_type &real_lcid_table()
+{
+ static table_type table;
+ return table;
+}
+
+BOOL CALLBACK proc(char *s)
+{
+ table_type &tbl = real_lcid_table();
+ try {
+ std::istringstream ss;
+ ss.str(s);
+ ss >> std::hex;
+
+ unsigned lcid ;
+ ss >>lcid;
+ if(ss.fail() || !ss.eof()) {
+ return FALSE;
+ }
+
+ char iso_639_lang[16];
+ char iso_3166_country[16];
+ if(GetLocaleInfoA(lcid,LOCALE_SISO639LANGNAME,iso_639_lang,sizeof(iso_639_lang))==0)
+ return FALSE;
+ std::string lc_name = iso_639_lang;
+ if(GetLocaleInfoA(lcid,LOCALE_SISO3166CTRYNAME,iso_3166_country,sizeof(iso_3166_country))!=0) {
+ lc_name += "_";
+ lc_name += iso_3166_country;
+ }
+ table_type::iterator p = tbl.find(lc_name);
+ if(p!=tbl.end()) {
+ if(p->second > lcid)
+ p->second = lcid;
+ }
+ else {
+ tbl[lc_name]=lcid;
+ }
+ }
+ catch(...) {
+ tbl.clear();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+table_type const &get_ready_lcid_table()
+{
+ if(table)
+ return *table;
+ else {
+ boost::unique_lock<boost::mutex> lock(lcid_table_mutex());
+ if(table)
+ return *table;
+ EnumSystemLocalesA(proc,LCID_INSTALLED);
+ table = &real_lcid_table();
+ return *table;
+ }
+}
+
+unsigned locale_to_lcid(std::string const &locale_name)
+{
+ if(locale_name.empty()) {
+ return LOCALE_USER_DEFAULT;
+ }
+ boost::locale::util::locale_data d;
+ d.parse(locale_name);
+ std::string id = d.language;
+
+ if(!d.country.empty()) {
+ id+="_"+d.country;
+ }
+ if(!d.variant.empty()) {
+ id+="@" + d.variant;
+ }
+
+ table_type const &tbl = get_ready_lcid_table();
+ table_type::const_iterator p = tbl.find(id);
+
+ unsigned lcid = 0;
+ if(p!=tbl.end())
+ lcid = p->second;
+ return lcid;
+}
+
+
+} // impl_win
+} // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/win32/lcid.hpp b/src/boost/libs/locale/src/win32/lcid.hpp
new file mode 100644
index 000000000..ed988394e
--- /dev/null
+++ b/src/boost/libs/locale/src/win32/lcid.hpp
@@ -0,0 +1,25 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_WIN32_LCID_HPP
+#define BOOST_LOCALE_IMPL_WIN32_LCID_HPP
+
+#include <string>
+#include <boost/locale/config.hpp>
+
+namespace boost {
+ namespace locale {
+ namespace impl_win {
+
+ BOOST_LOCALE_DECL unsigned locale_to_lcid(std::string const &locale_name);
+
+ } // impl_win
+ } // locale
+} // boost
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/win32/numeric.cpp b/src/boost/libs/locale/src/win32/numeric.cpp
new file mode 100644
index 000000000..00bc94fd6
--- /dev/null
+++ b/src/boost/libs/locale/src/win32/numeric.cpp
@@ -0,0 +1,245 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <locale>
+#include <string>
+#include <ios>
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/encoding.hpp>
+#include <boost/shared_ptr.hpp>
+#include <sstream>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <wctype.h>
+#include <ctype.h>
+
+#include "all_generator.hpp"
+#include "api.hpp"
+#include "../util/numeric.hpp"
+
+namespace boost {
+namespace locale {
+namespace impl_win {
+ namespace {
+
+ std::ostreambuf_iterator<wchar_t> write_it(std::ostreambuf_iterator<wchar_t> out,std::wstring const &s)
+ {
+ for(size_t i=0;i<s.size();i++)
+ *out++ = s[i];
+ return out;
+ }
+
+ std::ostreambuf_iterator<char> write_it(std::ostreambuf_iterator<char> out,std::wstring const &s)
+ {
+ std::string tmp = conv::from_utf(s,"UTF-8");
+ for(size_t i=0;i<tmp.size();i++)
+ *out++ = tmp[i];
+ return out;
+ }
+ }
+
+
+template<typename CharType>
+class num_format : public util::base_num_format<CharType>
+{
+public:
+ typedef typename std::num_put<CharType>::iter_type iter_type;
+ typedef std::basic_string<CharType> string_type;
+ typedef CharType char_type;
+
+ num_format(winlocale const &lc,size_t refs = 0) :
+ util::base_num_format<CharType>(refs),
+ lc_(lc)
+ {
+ }
+private:
+
+ virtual
+ iter_type do_format_currency(bool /*intl*/,iter_type out,std::ios_base &ios,char_type fill,long double val) const
+ {
+ if(lc_.is_c()) {
+ std::locale loc = ios.getloc();
+ int digits = std::use_facet<std::moneypunct<char_type> >(loc).frac_digits();
+ while(digits > 0) {
+ val*=10;
+ digits --;
+ }
+ std::ios_base::fmtflags f=ios.flags();
+ ios.flags(f | std::ios_base::showbase);
+ out = std::use_facet<std::money_put<char_type> >(loc).put(out,false,ios,fill,val);
+ ios.flags(f);
+ return out;
+ }
+ else {
+ std::wstring cur = wcsfmon_l(val,lc_);
+ return write_it(out,cur);
+ }
+ }
+
+private:
+ winlocale lc_;
+
+}; /// num_format
+
+template<typename CharType>
+class time_put_win : public std::time_put<CharType> {
+public:
+ time_put_win(winlocale const &lc, size_t refs = 0) :
+ std::time_put<CharType>(refs),
+ lc_(lc)
+ {
+ }
+ virtual ~time_put_win()
+ {
+ }
+ typedef typename std::time_put<CharType>::iter_type iter_type;
+ typedef CharType char_type;
+ typedef std::basic_string<char_type> string_type;
+
+ virtual iter_type do_put( iter_type out,
+ std::ios_base &/*ios*/,
+ CharType /*fill*/,
+ std::tm const *tm,
+ char format,
+ char /*modifier*/) const
+ {
+ return write_it(out,wcsftime_l(format,tm,lc_));
+ }
+
+private:
+ winlocale lc_;
+};
+
+
+template<typename CharType>
+class num_punct_win : public std::numpunct<CharType> {
+public:
+ typedef std::basic_string<CharType> string_type;
+ num_punct_win(winlocale const &lc,size_t refs = 0) :
+ std::numpunct<CharType>(refs)
+ {
+ numeric_info np = wcsnumformat_l(lc) ;
+ if(sizeof(CharType) == 1 && np.thousands_sep == L"\xA0")
+ np.thousands_sep=L" ";
+
+ to_str(np.thousands_sep,thousands_sep_);
+ to_str(np.decimal_point,decimal_point_);
+ grouping_ = np.grouping;
+ if(thousands_sep_.size() > 1)
+ grouping_ = std::string();
+ if(decimal_point_.size() > 1)
+ decimal_point_ = CharType('.');
+ }
+
+ void to_str(std::wstring &s1,std::wstring &s2)
+ {
+ s2.swap(s1);
+ }
+
+ void to_str(std::wstring &s1,std::string &s2)
+ {
+ s2=conv::from_utf(s1,"UTF-8");
+ }
+ virtual CharType do_decimal_point() const
+ {
+ return *decimal_point_.c_str();
+ }
+ virtual CharType do_thousands_sep() const
+ {
+ return *thousands_sep_.c_str();
+ }
+ virtual std::string do_grouping() const
+ {
+ return grouping_;
+ }
+ virtual string_type do_truename() const
+ {
+ static const char t[]="true";
+ return string_type(t,t+sizeof(t)-1);
+ }
+ virtual string_type do_falsename() const
+ {
+ static const char t[]="false";
+ return string_type(t,t+sizeof(t)-1);
+ }
+private:
+ string_type decimal_point_;
+ string_type thousands_sep_;
+ std::string grouping_;
+};
+
+template<typename CharType>
+std::locale create_formatting_impl(std::locale const &in,winlocale const &lc)
+{
+ if(lc.is_c()) {
+ std::locale tmp(in,new std::numpunct_byname<CharType>("C"));
+ tmp=std::locale(tmp,new std::time_put_byname<CharType>("C"));
+ tmp = std::locale(tmp,new num_format<CharType>(lc));
+ return tmp;
+ }
+ else {
+ std::locale tmp(in,new num_punct_win<CharType>(lc));
+ tmp = std::locale(tmp,new time_put_win<CharType>(lc));
+ tmp = std::locale(tmp,new num_format<CharType>(lc));
+ return tmp;
+ }
+}
+
+template<typename CharType>
+std::locale create_parsing_impl(std::locale const &in,winlocale const &lc)
+{
+ std::numpunct<CharType> *np = 0;
+ if(lc.is_c())
+ np = new std::numpunct_byname<CharType>("C");
+ else
+ np = new num_punct_win<CharType>(lc);
+ std::locale tmp(in,np);
+ tmp = std::locale(tmp,new util::base_num_parse<CharType>());
+ return tmp;
+}
+
+
+std::locale create_formatting( std::locale const &in,
+ winlocale const &lc,
+ character_facet_type type)
+{
+ switch(type) {
+ case char_facet:
+ return create_formatting_impl<char>(in,lc);
+ case wchar_t_facet:
+ return create_formatting_impl<wchar_t>(in,lc);
+ default:
+ return in;
+ }
+}
+
+std::locale create_parsing( std::locale const &in,
+ winlocale const &lc,
+ character_facet_type type)
+{
+ switch(type) {
+ case char_facet:
+ return create_parsing_impl<char>(in,lc);
+ case wchar_t_facet:
+ return create_parsing_impl<wchar_t>(in,lc);
+ default:
+ return in;
+ }
+}
+
+
+
+} // impl_std
+} // locale
+} //boost
+
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/win32/win_backend.cpp b/src/boost/libs/locale/src/win32/win_backend.cpp
new file mode 100644
index 000000000..cd9ec8375
--- /dev/null
+++ b/src/boost/libs/locale/src/win32/win_backend.cpp
@@ -0,0 +1,153 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_LOCALE_SOURCE
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/gnu_gettext.hpp>
+#include <boost/locale/info.hpp>
+#include "all_generator.hpp"
+#include "win_backend.hpp"
+#include <boost/locale/util.hpp>
+#include "../util/gregorian.hpp"
+#include "../util/locale_data.hpp"
+#include "api.hpp"
+#include <algorithm>
+#include <iterator>
+
+namespace boost {
+namespace locale {
+namespace impl_win {
+
+ class winapi_localization_backend : public localization_backend {
+ public:
+ winapi_localization_backend() :
+ invalid_(true)
+ {
+ }
+ winapi_localization_backend(winapi_localization_backend const &other) :
+ localization_backend(),
+ paths_(other.paths_),
+ domains_(other.domains_),
+ locale_id_(other.locale_id_),
+ invalid_(true)
+ {
+ }
+ virtual winapi_localization_backend *clone() const
+ {
+ return new winapi_localization_backend(*this);
+ }
+
+ void set_option(std::string const &name,std::string const &value)
+ {
+ invalid_ = true;
+ if(name=="locale")
+ locale_id_ = value;
+ else if(name=="message_path")
+ paths_.push_back(value);
+ else if(name=="message_application")
+ domains_.push_back(value);
+
+ }
+ void clear_options()
+ {
+ invalid_ = true;
+ locale_id_.clear();
+ paths_.clear();
+ domains_.clear();
+ }
+
+ void prepare_data()
+ {
+ if(!invalid_)
+ return;
+ invalid_ = false;
+ if(locale_id_.empty()) {
+ real_id_ = util::get_system_locale(true); // always UTF-8
+ lc_ = winlocale(real_id_);
+ }
+ else {
+ lc_=winlocale(locale_id_);
+ real_id_ = locale_id_;
+ }
+ util::locale_data d;
+ d.parse(real_id_);
+ if(!d.utf8) {
+ lc_ = winlocale();
+ // Make it C as non-UTF8 locales are not supported
+ }
+ }
+
+ virtual std::locale install(std::locale const &base,
+ locale_category_type category,
+ character_facet_type type = nochar_facet)
+ {
+ prepare_data();
+
+ switch(category) {
+ case convert_facet:
+ return create_convert(base,lc_,type);
+ case collation_facet:
+ return create_collate(base,lc_,type);
+ case formatting_facet:
+ return create_formatting(base,lc_,type);
+ case parsing_facet:
+ return create_parsing(base,lc_,type);
+ case calendar_facet:
+ {
+ util::locale_data inf;
+ inf.parse(real_id_);
+ return util::install_gregorian_calendar(base,inf.country);
+ }
+ case message_facet:
+ {
+ gnu_gettext::messages_info minf;
+ std::locale tmp=util::create_info(std::locale::classic(),real_id_);
+ boost::locale::info const &inf=std::use_facet<boost::locale::info>(tmp);
+ minf.language = inf.language();
+ minf.country = inf.country();
+ minf.variant = inf.variant();
+ minf.encoding = inf.encoding();
+ std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
+ minf.paths = paths_;
+ switch(type) {
+ case char_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
+ case wchar_t_facet:
+ return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
+ default:
+ return base;
+ }
+ }
+ case information_facet:
+ return util::create_info(base,real_id_);
+ case codepage_facet:
+ return util::create_utf8_codecvt(base,type);
+ default:
+ return base;
+ }
+ }
+
+ private:
+
+ std::vector<std::string> paths_;
+ std::vector<std::string> domains_;
+ std::string locale_id_;
+ std::string real_id_;
+
+ bool invalid_;
+ winlocale lc_;
+ };
+
+ localization_backend *create_localization_backend()
+ {
+ return new winapi_localization_backend();
+ }
+
+} // impl win
+} // locale
+} // boost
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/src/win32/win_backend.hpp b/src/boost/libs/locale/src/win32/win_backend.hpp
new file mode 100644
index 000000000..82f5401f6
--- /dev/null
+++ b/src/boost/libs/locale/src/win32/win_backend.hpp
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_IMPL_WIN32_LOCALIZATION_BACKEND_HPP
+#define BOOST_LOCALE_IMPL_WIN32_LOCALIZATION_BACKEND_HPP
+namespace boost {
+ namespace locale {
+ class localization_backend;
+ namespace impl_win {
+ localization_backend *create_localization_backend();
+ } // impl_win
+ } // locale
+} // boost
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/test/Jamfile.v2 b/src/boost/libs/locale/test/Jamfile.v2
new file mode 100644
index 000000000..db66db2c8
--- /dev/null
+++ b/src/boost/libs/locale/test/Jamfile.v2
@@ -0,0 +1,56 @@
+#
+# Copyright 2011 Artyom Beilis
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt.
+
+
+project
+ : requirements
+ <library>/boost/locale//boost_locale
+ <use>../build//build_flags
+ # Make sure we get all defines we need
+ # Otherwise we would have problem knowing
+ # what backends are actually in use
+ <link>shared
+ <define>BOOST_LOCALE_DYN_LINK=1
+ ;
+
+# Shared boost.locale tests
+
+test-suite "boost_locale_test"
+ :
+ # Configuration Information
+ [ run test_config.cpp : : : <test-info>always_show_run_output ]
+ # Shared
+ [ run test_utf.cpp ]
+ [ run test_date_time.cpp ]
+ [ run test_ios_prop.cpp ]
+ [ run test_codecvt.cpp ]
+ [ run test_codepage_converter.cpp ]
+ [ run test_codepage.cpp ]
+ [ run test_message.cpp : $(BOOST_ROOT)/libs/locale/test ]
+ [ run test_generator.cpp ]
+ # icu
+ [ run test_collate.cpp ]
+ [ run test_convert.cpp ]
+ [ run test_boundary.cpp ]
+ [ run test_formatting.cpp : : : <optimization>off ]
+ [ run test_icu_vs_os_timezone.cpp ]
+ # winapi
+ [ run test_winapi_collate.cpp ]
+ [ run test_winapi_convert.cpp ]
+ [ run test_winapi_formatting.cpp ]
+ # posix
+ [ run test_posix_collate.cpp ]
+ [ run test_posix_convert.cpp ]
+ [ run test_posix_formatting.cpp ]
+ # std
+ [ run test_std_collate.cpp ]
+ [ run test_std_convert.cpp ]
+ [ run test_std_formatting.cpp ]
+ ;
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/test/generate_catalogs.sh b/src/boost/libs/locale/test/generate_catalogs.sh
new file mode 100755
index 000000000..c3a0bb06f
--- /dev/null
+++ b/src/boost/libs/locale/test/generate_catalogs.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+msgfmt --endianness=big he/LC_MESSAGES/simple.po -o he/LC_MESSAGES/simple.mo
+msgfmt he/LC_MESSAGES/default.po -o he/LC_MESSAGES/default.mo
+msgfmt he/LC_MESSAGES/fall.po -o he/LC_MESSAGES/fall.mo
+msgfmt he_IL/LC_MESSAGES/full.po -o he_IL/LC_MESSAGES/full.mo
+
diff --git a/src/boost/libs/locale/test/he/LC_MESSAGES/default.mo b/src/boost/libs/locale/test/he/LC_MESSAGES/default.mo
new file mode 100644
index 000000000..de43713c4
--- /dev/null
+++ b/src/boost/libs/locale/test/he/LC_MESSAGES/default.mo
Binary files differ
diff --git a/src/boost/libs/locale/test/he/LC_MESSAGES/default.po b/src/boost/libs/locale/test/he/LC_MESSAGES/default.po
new file mode 100644
index 000000000..f79dfbd43
--- /dev/null
+++ b/src/boost/libs/locale/test/he/LC_MESSAGES/default.po
@@ -0,0 +1,35 @@
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural= (n==1 ? 0 : (n==2 ? 1 : (n>10 ? 3 : 2))) ;\n"
+
+msgid "בדיקה"
+msgstr "test"
+
+msgid "hello"
+msgstr "שלום"
+
+msgid "#hello"
+msgstr "#שלום"
+
+msgctxt "context"
+msgid "hello"
+msgstr "שלום בהקשר אחר"
+
+msgid "x day"
+msgid_plural "x days"
+msgstr[0] "יום x"
+msgstr[1] "יומיים"
+msgstr[2] "x ימים"
+msgstr[3] "x יום"
+
+msgctxt "context"
+msgid "x day"
+msgid_plural "בהקשר x days"
+msgstr[0] "בהקשר יום x"
+msgstr[1] "בהקשר יומיים"
+msgstr[2] "בהקשר x ימים"
+msgstr[3] "בהקשר x יום"
+
diff --git a/src/boost/libs/locale/test/he/LC_MESSAGES/fall.mo b/src/boost/libs/locale/test/he/LC_MESSAGES/fall.mo
new file mode 100644
index 000000000..ebc9a9ca2
--- /dev/null
+++ b/src/boost/libs/locale/test/he/LC_MESSAGES/fall.mo
Binary files differ
diff --git a/src/boost/libs/locale/test/he/LC_MESSAGES/fall.po b/src/boost/libs/locale/test/he/LC_MESSAGES/fall.po
new file mode 100644
index 000000000..5d3b6d28a
--- /dev/null
+++ b/src/boost/libs/locale/test/he/LC_MESSAGES/fall.po
@@ -0,0 +1,10 @@
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "test"
+msgstr "he"
+
+
diff --git a/src/boost/libs/locale/test/he/LC_MESSAGES/simple.mo b/src/boost/libs/locale/test/he/LC_MESSAGES/simple.mo
new file mode 100644
index 000000000..54549c182
--- /dev/null
+++ b/src/boost/libs/locale/test/he/LC_MESSAGES/simple.mo
Binary files differ
diff --git a/src/boost/libs/locale/test/he/LC_MESSAGES/simple.po b/src/boost/libs/locale/test/he/LC_MESSAGES/simple.po
new file mode 100644
index 000000000..9120b7fbb
--- /dev/null
+++ b/src/boost/libs/locale/test/he/LC_MESSAGES/simple.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n!=1;\n"
+
+msgid "hello"
+msgstr "היי"
+
+msgid "#hello"
+msgstr "#היי"
+
+msgctxt "context"
+msgid "hello"
+msgstr "היי בהקשר אחר"
+
+
+#: test_message.cpp:47
+msgid "test"
+msgid_plural "tests"
+msgstr[0] ""
+msgstr[1] ""
diff --git a/src/boost/libs/locale/test/he_IL/LC_MESSAGES/full.mo b/src/boost/libs/locale/test/he_IL/LC_MESSAGES/full.mo
new file mode 100644
index 000000000..844f9d8d1
--- /dev/null
+++ b/src/boost/libs/locale/test/he_IL/LC_MESSAGES/full.mo
Binary files differ
diff --git a/src/boost/libs/locale/test/he_IL/LC_MESSAGES/full.po b/src/boost/libs/locale/test/he_IL/LC_MESSAGES/full.po
new file mode 100644
index 000000000..32dbdeaaf
--- /dev/null
+++ b/src/boost/libs/locale/test/he_IL/LC_MESSAGES/full.po
@@ -0,0 +1,10 @@
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "test"
+msgstr "he_IL"
+
+
diff --git a/src/boost/libs/locale/test/test_boundary.cpp b/src/boost/libs/locale/test/test_boundary.cpp
new file mode 100644
index 000000000..56b62f243
--- /dev/null
+++ b/src/boost/libs/locale/test/test_boundary.cpp
@@ -0,0 +1,537 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_LOCALE_WITH_ICU
+#include <iostream>
+int main()
+{
+ std::cout << "ICU is not build... Skipping" << std::endl;
+}
+#else
+
+#define BOOST_LOCALE_ERROR_LIMIT 100000
+
+#include <boost/locale/boundary.hpp>
+#include <boost/locale/generator.hpp>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <list>
+#include <unicode/uversion.h>
+
+// Debugging code
+
+template<typename Char>
+void print_str(std::basic_string<Char> const &/*s*/)
+{
+}
+
+template<>
+void print_str<char>(std::basic_string<char> const &s)
+{
+ std::cout << "[" << s <<"]" << std::endl;
+}
+
+
+namespace lb = boost::locale::boundary;
+
+template<typename Char,typename Iterator>
+void test_word_container(Iterator begin,Iterator end,
+ std::vector<int> const &ipos,
+ std::vector<int> const &imasks,
+ std::vector<std::basic_string<Char> > const &ichunks,
+ std::locale l,
+ lb::boundary_type bt=lb::word
+ )
+{
+ for(int sm=(bt == lb::word ? 31 : 3 ) ;sm>=0;sm--) {
+ unsigned mask =
+ ((sm & 1 ) != 0) * 0xF
+ + ((sm & 2 ) != 0) * 0xF0
+ + ((sm & 4 ) != 0) * 0xF00
+ + ((sm & 8 ) != 0) * 0xF000
+ + ((sm & 16) != 0) * 0xF0000;
+
+ std::vector<int> masks,pos;
+ std::vector<unsigned> bmasks;
+ std::basic_string<Char> empty_chunk;
+
+ std::vector<std::basic_string<Char> > chunks;
+ std::vector<std::basic_string<Char> > fchunks;
+ std::vector<Iterator> iters;
+ iters.push_back(begin);
+ bmasks.push_back(0);
+
+ for(unsigned i=0;i<imasks.size();i++) {
+ if(imasks[i] & mask) {
+ masks.push_back(imasks[i]);
+ chunks.push_back(ichunks[i]);
+ fchunks.push_back(empty_chunk + ichunks[i]);
+ empty_chunk.clear();
+ pos.push_back(ipos[i]);
+ }
+ else {
+ empty_chunk+=ichunks[i];
+ }
+
+ if((imasks[i] & mask) || i==imasks.size()-1){
+ Iterator ptr=begin;
+ std::advance(ptr,ipos[i]);
+ iters.push_back(ptr);
+ bmasks.push_back(imasks[i]);
+ }
+ }
+
+ //
+ // segment iterator tests
+ //
+ {
+ lb::segment_index<Iterator> map(bt,begin,end,l);
+ typedef typename lb::segment_index<Iterator>::iterator iter_type;
+
+ map.rule(mask);
+
+ {
+ unsigned i=0;
+ iter_type p;
+ map.full_select(false);
+ for(p=map.begin();p!=map.end();++p,i++) {
+ TEST(p->str()==chunks[i]);
+ TEST(p->rule() == unsigned(masks[i]));
+ }
+
+ TEST(chunks.size() == i);
+ for(;;) {
+ if(p==map.begin()) {
+ TEST(i==0);
+ break;
+ }
+ else {
+ --p;
+ TEST(p->str()==chunks[--i]);
+ TEST(p->rule() == unsigned(masks[i]));
+ }
+ }
+ for(i=0,p=map.end();i<chunks.size();i++){
+ --p;
+ unsigned index = chunks.size() - i - 1;
+ TEST(p->str()==chunks[index]);
+ TEST(p->rule() == unsigned(masks[index]));
+ }
+ TEST(p==map.begin());
+ }
+
+ {
+ unsigned i=0;
+ iter_type p;
+ map.full_select(true);
+ for(p=map.begin();p!=map.end();++p,i++) {
+ TEST(p->str()==fchunks[i]);
+ TEST(p->rule() == unsigned(masks[i]));
+ }
+
+ TEST(chunks.size() == i);
+
+ for(;;) {
+ if(p==map.begin()) {
+ TEST(i==0);
+ break;
+ }
+ else {
+ --p;
+ if(p->str()!=fchunks[i-1]) {
+ print_str(p->str());
+ print_str(fchunks[i-1]);
+ }
+ TEST(p->str()==fchunks[--i]);
+ TEST(p->rule() == unsigned(masks[i]));
+ }
+ }
+
+ for(i=0,p=map.end();i<chunks.size();i++){
+ --p;
+ unsigned index = chunks.size() - i - 1;
+ TEST(p->str()==fchunks[index]);
+ TEST(p->rule() == unsigned(masks[index]));
+ }
+ TEST(p==map.begin());
+ }
+
+ {
+ iter_type p;
+ unsigned chunk_ptr=0;
+ unsigned i=0;
+ map.full_select(false);
+ for(Iterator optr=begin;optr!=end;optr++,i++) {
+ p=map.find(optr);
+ if(chunk_ptr < pos.size() && i>=unsigned(pos[chunk_ptr])){
+ chunk_ptr++;
+ }
+ if(chunk_ptr>=pos.size()) {
+ TEST(p==map.end());
+ }
+ else {
+ TEST(p->str()==chunks[chunk_ptr]);
+ TEST(p->rule()==unsigned(masks[chunk_ptr]));
+ }
+ }
+ }
+ {
+ iter_type p;
+ unsigned chunk_ptr=0;
+ unsigned i=0;
+ map.full_select(true);
+ for(Iterator optr=begin;optr!=end;optr++,i++) {
+ p=map.find(optr);
+ if(chunk_ptr < pos.size() && i>=unsigned(pos[chunk_ptr])){
+ chunk_ptr++;
+ }
+ if(chunk_ptr>=pos.size()) {
+ TEST(p==map.end());
+ }
+ else {
+ TEST(p->str()==fchunks[chunk_ptr]);
+ TEST(p->rule()==unsigned(masks[chunk_ptr]));
+ }
+ }
+ }
+
+ } // segment iterator tests
+
+ { // break iterator tests
+ lb::boundary_point_index<Iterator> map(bt,begin,end,l);
+ typedef typename lb::boundary_point_index<Iterator>::iterator iter_type;
+
+ map.rule(mask);
+
+ unsigned i=0;
+ iter_type p;
+ for(p=map.begin();p!=map.end();++p,i++) {
+ TEST(p->iterator()==iters[i]);
+ TEST(p->rule()==bmasks[i]);
+ }
+
+ TEST(iters.size() == i);
+
+ do {
+ --p;
+ --i;
+ TEST(p->iterator()==iters.at(i));
+ } while(p!=map.begin());
+ TEST(i==0);
+
+ unsigned iters_ptr=0;
+ for(Iterator optr=begin;optr!=end;optr++) {
+ p=map.find(optr);
+ TEST(p->iterator()==iters[iters_ptr]);
+ if(iters.at(iters_ptr)==optr)
+ iters_ptr++;
+ }
+
+ } // break iterator tests
+
+ { // copy test
+ typedef lb::segment_index<Iterator> ti_type;
+ typedef lb::boundary_point_index<Iterator> bi_type;
+ { // segment to bound
+ ti_type ti(bt,begin,end,l);
+ ti.rule(mask);
+ {
+ bi_type bi(ti);
+ bi.rule(mask);
+ unsigned i=0;
+ typename bi_type::iterator p;
+ for(p=bi.begin();p!=bi.end();++p,i++) {
+ TEST(p->iterator()==iters[i]);
+ TEST(p->rule()==bmasks[i]);
+ }
+ }
+ {
+ bi_type bi;
+ bi.rule(mask);
+ bi = ti;
+ unsigned i=0;
+ typename bi_type::iterator p;
+ for(p=bi.begin();p!=bi.end();++p,i++) {
+ TEST(p->iterator()==iters[i]);
+ TEST(p->rule()==bmasks[i]);
+ }
+ }
+ // boundary_point to bound
+ bi_type bi_2(bt,begin,end,l);
+ bi_2.rule(mask);
+ {
+ bi_type bi(bi_2);
+ unsigned i=0;
+ typename bi_type::iterator p;
+ for(p=bi.begin();p!=bi.end();++p,i++) {
+ TEST(p->iterator()==iters[i]);
+ TEST(p->rule()==bmasks[i]);
+ }
+ }
+ {
+ bi_type bi;
+ bi = bi_2;
+ unsigned i=0;
+ typename bi_type::iterator p;
+ for(p=bi.begin();p!=bi.end();++p,i++) {
+ TEST(p->iterator()==iters[i]);
+ TEST(p->rule()==bmasks[i]);
+ }
+ }
+ }
+ { // boundary_point to segment
+ bi_type bi(bt,begin,end,l);
+ {
+ ti_type ti(bi);
+ ti.rule(mask);
+ unsigned i=0;
+ typename ti_type::iterator p;
+ for(p=ti.begin();p!=ti.end();++p,i++) {
+ TEST(p->str()==chunks[i]);
+ TEST(p->rule()==unsigned(masks[i]));
+ }
+ }
+ {
+ ti_type ti;
+ ti.rule(mask);
+ ti = (bi);
+ unsigned i=0;
+ typename ti_type::iterator p;
+ for(p=ti.begin();p!=ti.end();++p,i++) {
+ TEST(p->str()==chunks[i]);
+ TEST(p->rule()==unsigned(masks[i]));
+ }
+ }
+ ti_type ti_2(bt,begin,end,l);
+ ti_2.rule(mask);
+ {
+ ti_type ti(ti_2);
+ unsigned i=0;
+ typename ti_type::iterator p;
+ for(p=ti.begin();p!=ti.end();++p,i++) {
+ TEST(p->str()==chunks[i]);
+ TEST(p->rule()==unsigned(masks[i]));
+ }
+ }
+ {
+ ti_type ti;
+ ti = (ti_2);
+ unsigned i=0;
+ typename ti_type::iterator p;
+ for(p=ti.begin();p!=ti.end();++p,i++) {
+ TEST(p->str()==chunks[i]);
+ TEST(p->rule()==unsigned(masks[i]));
+ }
+ }
+ }
+ }
+ } // for mask
+
+}
+
+template<typename Char>
+void run_word(std::string *original,int *none,int *num,int *word,int *kana,int *ideo,std::locale l,lb::boundary_type b=lb::word)
+{
+ std::vector<int> pos;
+ std::vector<std::basic_string<Char> > chunks;
+ std::vector<int> masks;
+ std::basic_string<Char> test_string;
+ for(int i=0;!original[i].empty();i++) {
+ chunks.push_back(to_correct_string<Char>(original[i],l));
+ test_string+=chunks.back();
+ pos.push_back(test_string.size());
+ masks.push_back(
+ ( none ? none[i]*15 : 0)
+ | ( num ? ((num[i]*15) << 4) : 0)
+ | ( word ? ((word[i]*15) << 8) : 0)
+ | ( kana ? ((kana[i]*15) << 12) : 0)
+ | ( ideo ? ((ideo[i]*15) << 16) : 0)
+ );
+ }
+
+ std::list<Char> lst(test_string.begin(),test_string.end());
+ test_word_container<Char>(lst.begin(),lst.end(),pos,masks,chunks,l,b);
+ test_word_container<Char>(test_string.begin(),test_string.end(),pos,masks,chunks,l,b);
+}
+
+std::string character[]={"שָ","ל","וֹ","ם","!",""};
+int nones[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+
+std::string sentence1[]={"To be\n","or not\n","to be?\n"," That is the question. ","Or maybe not",""};
+int sentence1a[]={ 0, 0, 1, 1, 0, 0};
+int sentence1b[]={ 1, 1, 0, 0, 1, 0};
+
+std::string line1[]={"To ","be\n","or ","not\n","to ","be",""};
+int line1a[]={ 1, 0, 1 , 0, 1, 1 , 0 };
+int line1b[]={ 0, 1, 0 , 1, 0, 0 , 0 };
+
+
+void test_boundaries(std::string *all,int *first,int *second,lb::boundary_type t)
+{
+ boost::locale::generator g;
+ std::cout << " char UTF-8" << std::endl;
+ run_word<char>(all,first,second,0,0,0,g("he_IL.UTF-8"),t);
+ std::cout << " char CP1255" << std::endl;
+ run_word<char>(all,first,second,0,0,0,g("he_IL.cp1255"),t);
+ std::cout << " wchar_t"<<std::endl;
+ run_word<wchar_t>(all,first,second,0,0,0,g("he_IL.UTF-8"),t);
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::cout << " char16_t"<<std::endl;
+ run_word<char16_t>(all,first,second,0,0,0,g("he_IL.UTF-8"),t);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::cout << " char32_t"<<std::endl;
+ run_word<char32_t>(all,first,second,0,0,0,g("he_IL.UTF-8"),t);
+ #endif
+
+}
+
+void word_boundary()
+{
+ boost::locale::generator g;
+ //std::string all1[]={"10"," ","Hello"," ","Windows7"," ","平仮名","ひらがな","ヒラガナ",""};
+ //std::string all1[]={"10"," ","Hello"," ","Windows7"," ","平仮名","ひん","アヒル",""};
+ std::string all1[]={"10"," ","Hello"," ","Windows7"," ","平仮名","アヒル",""};
+ int none1[]={ 0, 1, 0, 1, 0, 1, 0, 0, 0};
+ int num1[]={ 1, 0, 0, 0, 1, 0, 0 , 0 , 0};
+ int word1[]={ 0, 0, 1, 0, 1, 0, 0 , 0 , 0};
+#if U_ICU_VERSION_MAJOR_NUM >= 50
+ int kana1[]={ 0, 0, 0, 0, 0, 0, 0, 0 , 0};
+ int ideo1[]={ 0, 0, 0, 0, 0, 0, 1, 1 , 1};
+#else
+ int kana1[]={ 0, 0, 0, 0, 0, 0, 0, 1 , 1};
+ int ideo1[]={ 0, 0, 0, 0, 0, 0, 1, 0 , 0};
+#endif
+
+
+ int zero[25]={0};
+ std::string all2[]={""};
+
+ std::string all3[]={" "," ","Hello",",","World","!"," ",""};
+ int none3[]={ 1, 1, 0, 1, 0, 1, 1, 0};
+ int word3[]={ 0, 0, 1, 0, 1, 0, 0, 0};
+
+ std::cout << " char UTF-8" << std::endl;
+ run_word<char>(all1,none1,num1,word1,kana1,ideo1,g("ja_JP.UTF-8"));
+ run_word<char>(all2,zero,zero,zero,zero,zero,g("en_US.UTF-8"));
+ run_word<char>(all3,none3,zero,word3,zero,zero,g("en_US.UTF-8"));
+
+ std::cout << " char Shift-JIS" << std::endl;
+ run_word<char>(all1,none1,num1,word1,kana1,ideo1,g("ja_JP.Shift-JIS"));
+ run_word<char>(all2,zero,zero,zero,zero,zero,g("ja_JP.Shift-JIS"));
+ run_word<char>(all3,none3,zero,word3,zero,zero,g("ja_JP.Shift-JIS"));
+
+ std::cout << " wchar_t"<<std::endl;
+ run_word<wchar_t>(all1,none1,num1,word1,kana1,ideo1,g("ja_JP.UTF-8"));
+ run_word<wchar_t>(all2,zero,zero,zero,zero,zero,g("en_US.UTF-8"));
+ run_word<wchar_t>(all3,none3,zero,word3,zero,zero,g("en_US.UTF-8"));
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::cout << " char16_t"<<std::endl;
+ run_word<char16_t>(all1,none1,num1,word1,kana1,ideo1,g("ja_JP.UTF-8"));
+ run_word<char16_t>(all2,zero,zero,zero,zero,zero,g("en_US.UTF-8"));
+ run_word<char16_t>(all3,none3,zero,word3,zero,zero,g("en_US.UTF-8"));
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::cout << " char32_t"<<std::endl;
+ run_word<char32_t>(all1,none1,num1,word1,kana1,ideo1,g("ja_JP.UTF-8"));
+ run_word<char32_t>(all2,zero,zero,zero,zero,zero,g("en_US.UTF-8"));
+ run_word<char32_t>(all3,none3,zero,word3,zero,zero,g("en_US.UTF-8"));
+ #endif
+}
+void test_op_one_side(std::string const &sl,std::string const &sr,int val)
+{
+ boost::locale::boundary::ssegment l(sl.begin(),sl.end(),0),r(sr.begin(),sr.end(),0);
+
+ // segment
+ TEST( (l==r) == (val==0));
+ TEST( (l!=r) == (val!=0));
+ TEST( (l<=r) == (val<=0));
+ TEST( (l< r) == (val<0));
+ TEST( (l>=r) == (val>=0));
+ TEST( (l> r) == (val>0));
+
+ // C string
+ TEST( (l==sr.c_str()) == (val==0));
+ TEST( (l!=sr.c_str()) == (val!=0));
+ TEST( (l<=sr.c_str()) == (val<=0));
+ TEST( (l< sr.c_str()) == (val<0));
+ TEST( (l>=sr.c_str()) == (val>=0));
+ TEST( (l> sr.c_str()) == (val>0));
+
+ TEST( (sl.c_str()==r) == (val==0));
+ TEST( (sl.c_str()!=r) == (val!=0));
+ TEST( (sl.c_str()<=r) == (val<=0));
+ TEST( (sl.c_str()< r) == (val<0));
+ TEST( (sl.c_str()>=r) == (val>=0));
+ TEST( (sl.c_str()> r) == (val>0));
+
+
+ // C++ string
+ TEST( (l==sr) == (val==0));
+ TEST( (l!=sr) == (val!=0));
+ TEST( (l<=sr) == (val<=0));
+ TEST( (l< sr) == (val<0));
+ TEST( (l>=sr) == (val>=0));
+ TEST( (l> sr) == (val>0));
+
+ TEST( (sl==r) == (val==0));
+ TEST( (sl!=r) == (val!=0));
+ TEST( (sl<=r) == (val<=0));
+ TEST( (sl< r) == (val<0));
+ TEST( (sl>=r) == (val>=0));
+ TEST( (sl> r) == (val>0));
+ // self check
+ TEST( (sl==sr) == (val==0));
+ TEST( (sl!=sr) == (val!=0));
+ TEST( (sl<=sr) == (val<=0));
+ TEST( (sl< sr) == (val<0));
+ TEST( (sl>=sr) == (val>=0));
+ TEST( (sl> sr) == (val>0));
+
+}
+
+void test_op(std::string const &sl,std::string const &sr,int val)
+{
+ test_op_one_side(sl,sr,val);
+ test_op_one_side(sr,sl,-val);
+}
+void segment_operator()
+{
+ test_op("","a",-1);
+ test_op("","",0);
+ test_op("aa","aaa",-1);
+ test_op("aa","ab",-1);
+}
+
+int main()
+{
+ try {
+ std::cout << "Testing segment operators" << std::endl;
+ segment_operator();
+ std::cout << "Testing word boundary" << std::endl;
+ word_boundary();
+ std::cout << "Testing character boundary" << std::endl;
+ test_boundaries(character,nones,0,lb::character);
+ std::cout << "Testing sentence boundary" << std::endl;
+ test_boundaries(sentence1,sentence1a,sentence1b,lb::sentence);
+ std::cout << "Testing line boundary" << std::endl;
+ test_boundaries(line1,line1a,line1b,lb::line);
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+}
+
+#endif // NOICU
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_codecvt.cpp b/src/boost/libs/locale/test/test_codecvt.cpp
new file mode 100644
index 000000000..026a5aeaa
--- /dev/null
+++ b/src/boost/libs/locale/test/test_codecvt.cpp
@@ -0,0 +1,283 @@
+//
+// Copyright (c) 2015 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include <boost/locale/utf8_codecvt.hpp>
+#include <locale>
+#include <iostream>
+#include <iomanip>
+#include <string.h>
+#include <wchar.h>
+#include <memory.h>
+#define BOOST_LOCALE_ERROR_LIMIT -1
+#include "test_locale.hpp"
+
+static char const *utf8_name = "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt";
+static wchar_t const *wide_name = L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt";
+
+char const *res(std::codecvt_base::result r)
+{
+ switch(r){
+ case std::codecvt_base::ok: return "ok";
+ case std::codecvt_base::partial: return "partial";
+ case std::codecvt_base::error: return "error";
+ case std::codecvt_base::noconv: return "noconv";
+ default:
+ return "error";
+ }
+}
+
+typedef std::codecvt<wchar_t,char,std::mbstate_t> cvt_type;
+
+void test_codecvt_in_n_m(cvt_type const &cvt,int n,int m)
+{
+ wchar_t const *wptr = wide_name;
+ int wlen = wcslen(wide_name);
+ int u8len = strlen(utf8_name);
+ char const *from = utf8_name;
+ char const *end = from;
+ char const *real_end = utf8_name + u8len;
+ char const *from_next = from;
+ std::mbstate_t mb=std::mbstate_t();
+ while(from_next < real_end) {
+ if(from == end) {
+ end = from + n;
+ if(end > real_end)
+ end = real_end;
+ }
+
+ wchar_t buf[128];
+ wchar_t *to = buf;
+ wchar_t *to_end = to + m;
+ wchar_t *to_next = to;
+
+
+ std::mbstate_t mb2 = mb;
+ std::codecvt_base::result r = cvt.in(mb,from,end,from_next,to,to_end,to_next);
+ //std::cout << "In from_size=" << (end-from) << " from move=" << (from_next - from) << " to move= " << to_next - to << " state = " << res(r) << std::endl;
+
+ int count = cvt.length(mb2,from,end,to_end - to);
+ #ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST
+ TEST(memcmp(&mb,&mb2,sizeof(mb))==0);
+ if(count != from_next - from) {
+ std::cout << count << " " << from_next - from << std::endl;
+ }
+ TEST(count == from_next - from);
+ #else
+ TEST(count == to_next - to);
+ #endif
+
+
+ if(r == cvt_type::partial) {
+ end+=n;
+ if(end > real_end)
+ end = real_end;
+ }
+ else
+ TEST(r == cvt_type::ok);
+ while(to!=to_next) {
+ TEST(*wptr == *to);
+ wptr++;
+ to++;
+ }
+ to=to_next;
+ from = from_next;
+ }
+ TEST(wptr == wide_name + wlen);
+ TEST(from == real_end);
+
+}
+
+void test_codecvt_out_n_m(cvt_type const &cvt,int n,int m)
+{
+ char const *nptr = utf8_name;
+ int wlen = wcslen(wide_name);
+ int u8len = strlen(utf8_name);
+
+ std::mbstate_t mb=std::mbstate_t();
+
+ wchar_t const *from_next = wide_name;
+ wchar_t const *real_from_end = wide_name + wlen;
+
+ char buf[256];
+ char *to = buf;
+ char *to_next = to;
+ char *to_end = to + n;
+ char *real_to_end = buf + sizeof(buf);
+
+ while(from_next < real_from_end) {
+ wchar_t const *from = from_next;
+ wchar_t const *from_end = from + m;
+ if(from_end > real_from_end)
+ from_end = real_from_end;
+ if(to_end == to) {
+ to_end = to+n;
+ }
+
+ std::codecvt_base::result r = cvt.out(mb,from,from_end,from_next,to,to_end,to_next);
+ //std::cout << "In from_size=" << (end-from) << " from move=" << (from_next - from) << " to move= " << to_next - to << " state = " << res(r) << std::endl;
+ if(r == cvt_type::partial) {
+ TEST(to_end - to_next < cvt.max_length());
+ to_end += n;
+ if(to_end > real_to_end)
+ to_end = real_to_end;
+ }
+ else {
+ TEST(r == cvt_type::ok);
+ }
+
+ while(to!=to_next) {
+ TEST(*nptr == *to);
+ nptr++;
+ to++;
+ }
+ from = from_next;
+ }
+ TEST(nptr == utf8_name + u8len);
+ TEST(from_next == real_from_end);
+ TEST(cvt.unshift(mb,to,to+n,to_next)==cvt_type::ok);
+ TEST(to_next == to);
+
+}
+
+
+void test_codecvt_conv()
+{
+ std::cout << "Conversions " << std::endl;
+ std::locale l(std::locale::classic(),new boost::locale::utf8_codecvt<wchar_t>());
+
+ cvt_type const &cvt = std::use_facet<cvt_type>(l);
+
+ TEST(cvt.max_length()==4);
+
+ for(int i=1;i<=(int)strlen(utf8_name)+1;i++) {
+ for(int j=1;j<=(int)wcslen(wide_name)+1;j++) {
+ try {
+ test_codecvt_in_n_m(cvt,i,j);
+ test_codecvt_out_n_m(cvt,i,j);
+ }
+ catch(...) {
+ std::cerr << "Wlen=" <<j << " Nlen=" << i << std::endl;
+ throw;
+ }
+ }
+ }
+}
+
+void test_codecvt_err()
+{
+ std::cout << "Errors " << std::endl;
+ std::locale l(std::locale::classic(),new boost::locale::utf8_codecvt<wchar_t>());
+
+ cvt_type const &cvt = std::use_facet<cvt_type>(l);
+
+ std::cout << "- UTF-8" << std::endl;
+ {
+
+ wchar_t buf[2];
+ wchar_t *to=buf;
+ wchar_t *to_end = buf+2;
+ wchar_t *to_next = to;
+ char const *err_utf="1\xFF\xFF";
+ {
+ std::mbstate_t mb=std::mbstate_t();
+ char const *from=err_utf;
+ char const *from_end = from + strlen(from);
+ char const *from_next = from;
+ to_next = to;
+ TEST(cvt.in(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::error);
+ TEST(from_next == from+1);
+ TEST(to_next == to + 1);
+ TEST(*to == '1');
+ }
+ err_utf++;
+ {
+ std::mbstate_t mb=std::mbstate_t();
+ char const *from=err_utf;
+ char const *from_end = from + strlen(from);
+ char const *from_next = from;
+ TEST(cvt.in(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::error);
+ TEST(from_next == from);
+ TEST(to_next == to);
+ }
+ }
+
+ std::cout << "- UTF-16/32" << std::endl;
+ {
+
+ char buf[32];
+ char *to=buf;
+ char *to_end = buf+32;
+ char *to_next = to;
+ wchar_t err_buf[3] = { '1' , 0xDC9E }; // second surrogate not works both for UTF-16 and 32
+ wchar_t const *err_utf = err_buf;
+ {
+ std::mbstate_t mb=std::mbstate_t();
+ wchar_t const *from=err_utf;
+ wchar_t const *from_end = from + wcslen(from);
+ wchar_t const *from_next = from;
+ TEST(cvt.out(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::error);
+ TEST(from_next == from+1);
+ TEST(to_next == to + 1);
+ TEST(*to == '1');
+ }
+ err_utf++;
+ {
+ std::mbstate_t mb=std::mbstate_t();
+ wchar_t const *from=err_utf;
+ wchar_t const *from_end = from + wcslen(from);
+ wchar_t const *from_next = from;
+ to_next = to;
+ TEST(cvt.out(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::error);
+ TEST(from_next == from);
+ TEST(to_next == to);
+ }
+ }
+
+}
+
+
+void test_char_char()
+{
+ std::cout << "Char-char specialization"<<std::endl;
+ std::locale l(std::locale::classic(),new boost::locale::utf8_codecvt<char>());
+ std::codecvt<char,char,std::mbstate_t> const &cvt=std::use_facet<std::codecvt<char,char,std::mbstate_t> >(l);
+ std::mbstate_t mb=std::mbstate_t();
+ char const *from = "a";
+ char const *from_end = from+1;
+ char const *from_next = from;
+ char buf[2];
+ char *to = buf;
+ char *to_end = buf+1;
+ char *to_next = to;
+ TEST(cvt.always_noconv()==true);
+ TEST(cvt.in(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::noconv);
+ TEST(from_next == from);
+ TEST(to_next == to);
+ TEST(cvt.out(mb,from,from_end,from_next,to,to_end,to_next)==cvt_type::noconv);
+ TEST(from_next == from);
+ TEST(to_next == to);
+ TEST(cvt.encoding()==1);
+ TEST(cvt.max_length()==1);
+}
+
+int main()
+{
+ try {
+ test_codecvt_conv();
+ test_codecvt_err();
+ test_char_char();
+
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed : " << e.what() << std::endl;
+ return 1;
+ }
+ std::cout << "Ok" << std::endl;
+ return 0;
+}
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/test/test_codepage.cpp b/src/boost/libs/locale/test/test_codepage.cpp
new file mode 100644
index 000000000..389c811eb
--- /dev/null
+++ b/src/boost/libs/locale/test/test_codepage.cpp
@@ -0,0 +1,517 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/locale/encoding.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/info.hpp>
+#include <boost/locale/config.hpp>
+#include <fstream>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+
+
+#ifndef BOOST_LOCALE_NO_POSIX_BACKEND
+# ifdef __APPLE__
+# include <xlocale.h>
+# endif
+# include <locale.h>
+#endif
+
+#if !defined(BOOST_LOCALE_WITH_ICU) && !defined(BOOST_LOCALE_WITH_ICONV) && (defined(BOOST_WINDOWS) || defined(__CYGWIN__))
+#ifndef NOMINMAX
+# define NOMINMAX
+#endif
+#include <windows.h>
+#endif
+
+
+bool test_iso;
+bool test_iso_8859_8 = true;
+bool test_utf;
+bool test_sjis;
+
+std::string he_il_8bit;
+std::string en_us_8bit;
+std::string ja_jp_shiftjis;
+
+
+template<typename Char>
+std::basic_string<Char> read_file(std::basic_istream<Char> &in)
+{
+ std::basic_string<Char> res;
+ Char c;
+ while(in.get(c))
+ res+=c;
+ return res;
+}
+
+
+template<typename Char>
+void test_ok(std::string file,std::locale const &l,std::basic_string<Char> cmp=std::basic_string<Char>())
+{
+ if(cmp.empty())
+ cmp=to<Char>(file);
+ std::ofstream test("testi.txt");
+ test << file;
+ test.close();
+ typedef std::basic_fstream<Char> stream_type;
+
+ stream_type f1("testi.txt",stream_type::in);
+ f1.imbue(l);
+ TEST(read_file<Char>(f1) == cmp);
+ f1.close();
+
+ stream_type f2("testo.txt",stream_type::out);
+ f2.imbue(l);
+ f2 << cmp;
+ f2.close();
+
+ std::ifstream testo("testo.txt");
+ TEST(read_file<char>(testo) == file);
+}
+
+template<typename Char>
+void test_rfail(std::string file,std::locale const &l,int pos)
+{
+ std::ofstream test("testi.txt");
+ test << file;
+ test.close();
+ typedef std::basic_fstream<Char> stream_type;
+
+ stream_type f1("testi.txt",stream_type::in);
+ f1.imbue(l);
+ Char c;
+ for(int i=0;i<pos;i++) {
+ f1.get(c);
+ if(f1.fail()) { // failed before as detected errors at forward;
+ return;
+ }
+ TEST(f1);
+ }
+ // if the pos above suceed, at this point
+ // it MUST fail
+ TEST(f1.get(c).fail());
+}
+
+template<typename Char>
+void test_wfail(std::string file,std::locale const &l,int pos)
+{
+ typedef std::basic_fstream<Char> stream_type;
+ stream_type f1("testo.txt",stream_type::out);
+ f1.imbue(l);
+ std::basic_string<Char> out=to<Char>(file);
+ int i;
+ for(i=0;i<pos;i++) {
+ f1 << out.at(i);
+ f1<<std::flush;
+ TEST(f1.good());
+ }
+ f1 << out.at(i);
+ TEST(f1.fail() || (f1<<std::flush).fail());
+}
+
+
+template<typename Char>
+void test_for_char()
+{
+ boost::locale::generator g;
+ if(test_utf) {
+ std::cout << " UTF-8" << std::endl;
+ test_ok<Char>("grüße\nn i",g("en_US.UTF-8"));
+ test_rfail<Char>("abc\xFF\xFF",g("en_US.UTF-8"),3);
+ std::cout << " Testing codepoints above 0xFFFF" << std::endl;
+ std::cout << " Single U+2008A" << std::endl;
+ test_ok<Char>("\xf0\xa0\x82\x8a",g("en_US.UTF-8")); // U+2008A
+ std::cout << " Single U+2008A withing text" << std::endl;
+ test_ok<Char>("abc\"\xf0\xa0\x82\x8a\"",g("en_US.UTF-8")); // U+2008A
+ std::string one = "\xf0\xa0\x82\x8a";
+ std::string res;
+ for(unsigned i=0;i<1000;i++)
+ res+=one;
+ std::cout << " U+2008A x 1000" << std::endl;
+ test_ok<Char>(res.c_str(),g("en_US.UTF-8")); // U+2008A
+ }
+ else {
+ std::cout << " UTF-8 Not supported " << std::endl;
+ }
+
+ if(test_iso) {
+ if(test_iso_8859_8) {
+ std::cout << " ISO8859-8" << std::endl;
+ test_ok<Char>("hello \xf9\xec\xe5\xed",g(he_il_8bit),to<Char>("hello שלום"));
+ }
+ std::cout << " ISO8859-1" << std::endl;
+ test_ok<Char>(to<char>("grüße\nn i"),g(en_us_8bit),to<Char>("grüße\nn i"));
+ test_wfail<Char>("grüßen שלום",g(en_us_8bit),7);
+ }
+
+ if(test_sjis) {
+ std::cout << " Shift-JIS" << std::endl;
+ test_ok<Char>("\x93\xfa\x96\x7b",g(ja_jp_shiftjis),
+ boost::locale::conv::to_utf<Char>("\xe6\x97\xa5\xe6\x9c\xac","UTF-8")); // Japan
+ }
+}
+void test_wide_io()
+{
+ std::cout << " wchar_t" << std::endl;
+ test_for_char<wchar_t>();
+
+ #if defined BOOST_LOCALE_ENABLE_CHAR16_T && !defined(BOOST_NO_CHAR16_T_CODECVT)
+ std::cout << " char16_t" << std::endl;
+ test_for_char<char16_t>();
+ #endif
+ #if defined BOOST_LOCALE_ENABLE_CHAR32_T && !defined(BOOST_NO_CHAR32_T_CODECVT)
+ std::cout << " char32_t" << std::endl;
+ test_for_char<char32_t>();
+ #endif
+}
+
+template<typename Char>
+void test_pos(std::string source,std::basic_string<Char> target,std::string encoding)
+{
+ using namespace boost::locale::conv;
+ boost::locale::generator g;
+ std::locale l= encoding == "ISO8859-8" ? g("he_IL."+encoding) : g("en_US."+encoding);
+ TEST(to_utf<Char>(source,encoding)==target);
+ TEST(to_utf<Char>(source.c_str(),encoding)==target);
+ TEST(to_utf<Char>(source.c_str(),source.c_str()+source.size(),encoding)==target);
+
+ TEST(to_utf<Char>(source,l)==target);
+ TEST(to_utf<Char>(source.c_str(),l)==target);
+ TEST(to_utf<Char>(source.c_str(),source.c_str()+source.size(),l)==target);
+
+ TEST(from_utf<Char>(target,encoding)==source);
+ TEST(from_utf<Char>(target.c_str(),encoding)==source);
+ TEST(from_utf<Char>(target.c_str(),target.c_str()+target.size(),encoding)==source);
+
+ TEST(from_utf<Char>(target,l)==source);
+ TEST(from_utf<Char>(target.c_str(),l)==source);
+ TEST(from_utf<Char>(target.c_str(),target.c_str()+target.size(),l)==source);
+}
+
+#define TESTF(X) TEST_THROWS(X,boost::locale::conv::conversion_error)
+
+template<typename Char>
+void test_to_neg(std::string source,std::basic_string<Char> target,std::string encoding)
+{
+ using namespace boost::locale::conv;
+ boost::locale::generator g;
+ std::locale l=g("en_US."+encoding);
+
+ TEST(to_utf<Char>(source,encoding)==target);
+ TEST(to_utf<Char>(source.c_str(),encoding)==target);
+ TEST(to_utf<Char>(source.c_str(),source.c_str()+source.size(),encoding)==target);
+ TEST(to_utf<Char>(source,l)==target);
+ TEST(to_utf<Char>(source.c_str(),l)==target);
+ TEST(to_utf<Char>(source.c_str(),source.c_str()+source.size(),l)==target);
+
+ TESTF(to_utf<Char>(source,encoding,stop));
+ TESTF(to_utf<Char>(source.c_str(),encoding,stop));
+ TESTF(to_utf<Char>(source.c_str(),source.c_str()+source.size(),encoding,stop));
+ TESTF(to_utf<Char>(source,l,stop));
+ TESTF(to_utf<Char>(source.c_str(),l,stop));
+ TESTF(to_utf<Char>(source.c_str(),source.c_str()+source.size(),l,stop));
+}
+
+template<typename Char>
+void test_from_neg(std::basic_string<Char> source,std::string target,std::string encoding)
+{
+ using namespace boost::locale::conv;
+ boost::locale::generator g;
+ std::locale l=g("en_US."+encoding);
+
+ TEST(from_utf<Char>(source,encoding)==target);
+ TEST(from_utf<Char>(source.c_str(),encoding)==target);
+ TEST(from_utf<Char>(source.c_str(),source.c_str()+source.size(),encoding)==target);
+ TEST(from_utf<Char>(source,l)==target);
+ TEST(from_utf<Char>(source.c_str(),l)==target);
+ TEST(from_utf<Char>(source.c_str(),source.c_str()+source.size(),l)==target);
+
+ TESTF(from_utf<Char>(source,encoding,stop));
+ TESTF(from_utf<Char>(source.c_str(),encoding,stop));
+ TESTF(from_utf<Char>(source.c_str(),source.c_str()+source.size(),encoding,stop));
+ TESTF(from_utf<Char>(source,l,stop));
+ TESTF(from_utf<Char>(source.c_str(),l,stop));
+ TESTF(from_utf<Char>(source.c_str(),source.c_str()+source.size(),l,stop));
+}
+
+template<typename Char>
+std::basic_string<Char> utf(char const *s)
+{
+ return to<Char>(s);
+}
+
+template<>
+std::basic_string<char> utf(char const *s)
+{
+ return s;
+}
+
+template<typename Char>
+void test_with_0()
+{
+ std::string a("abc\0\0 yz\0",3+2+3+1);
+ TEST(boost::locale::conv::from_utf<Char>(boost::locale::conv::to_utf<Char>(a,"UTF-8"),"UTF-8") == a);
+ TEST(boost::locale::conv::from_utf<Char>(boost::locale::conv::to_utf<Char>(a,"ISO8859-1"),"ISO8859-1") == a);
+}
+
+template<typename Char,int n=sizeof(Char)>
+struct utfutf;
+
+template<>
+struct utfutf<char,1> {
+ static char const *ok() {return "grüßen";}
+ static char const *bad() { return "gr\xFF" "üßen"; }
+ // split into 2 to make SunCC happy
+};
+
+template<>
+struct utfutf<wchar_t,2> {
+ static wchar_t const *ok(){ return L"\x67\x72\xfc\xdf\x65\x6e"; }
+ static wchar_t const *bad() {
+ static wchar_t buf[256] = L"\x67\x72\xFF\xfc\xFE\xFD\xdf\x65\x6e";
+ buf[2]=0xDC01; // second surrogate must not be
+ buf[4]=0xD801; // First
+ buf[5]=0xD801; // Must be surrogate trail
+ return buf;
+ }
+};
+template<>
+struct utfutf<wchar_t,4> {
+ static wchar_t const *ok(){ return L"\x67\x72\xfc\xdf\x65\x6e"; }
+ static wchar_t const *bad() {
+ static wchar_t buf[256] = L"\x67\x72\xFF\xfc\xdf\x65\x6e";
+ buf[2]=static_cast<wchar_t>(0x1000000); // > 10FFFF
+ return buf;
+ }
+};
+
+
+template<typename CharOut,typename CharIn>
+void test_combinations()
+{
+ using boost::locale::conv::utf_to_utf;
+ typedef utfutf<CharOut> out;
+ typedef utfutf<CharIn> in;
+ TEST( (utf_to_utf<CharOut,CharIn>(in::ok())==out::ok()) );
+ TESTF( (utf_to_utf<CharOut,CharIn>(in::bad(),boost::locale::conv::stop)) );
+ TEST( (utf_to_utf<CharOut,CharIn>(in::bad())==out::ok()) );
+}
+
+void test_all_combinations()
+{
+ std::cout << "Testing utf_to_utf" << std::endl;
+ std::cout <<" char<-char"<<std::endl;
+ test_combinations<char,char>();
+ std::cout <<" char<-wchar"<<std::endl;
+ test_combinations<char,wchar_t>();
+ std::cout <<" wchar<-char"<<std::endl;
+ test_combinations<wchar_t,char>();
+ std::cout <<" wchar<-wchar"<<std::endl;
+ test_combinations<wchar_t,wchar_t>();
+}
+
+template<typename Char>
+void test_to()
+{
+ test_pos<Char>(to<char>("grüßen"),utf<Char>("grüßen"),"ISO8859-1");
+ if(test_iso_8859_8)
+ test_pos<Char>("\xf9\xec\xe5\xed",utf<Char>("שלום"),"ISO8859-8");
+ test_pos<Char>("grüßen",utf<Char>("grüßen"),"UTF-8");
+ test_pos<Char>("abc\"\xf0\xa0\x82\x8a\"",utf<Char>("abc\"\xf0\xa0\x82\x8a\""),"UTF-8");
+
+ test_to_neg<Char>("g\xFFrüßen",utf<Char>("grüßen"),"UTF-8");
+ test_from_neg<Char>(utf<Char>("hello שלום"),"hello ","ISO8859-1");
+
+ test_with_0<Char>();
+}
+
+
+void test_skip(char const *enc,char const *utf,char const *name,char const *opt=0)
+{
+ if(opt!=0) {
+ if(boost::locale::conv::to_utf<char>(enc,name) == opt) {
+ test_skip(enc,opt,name);
+ return;
+ }
+ }
+ TEST(boost::locale::conv::to_utf<char>(enc,name) == utf);
+ TEST(boost::locale::conv::to_utf<wchar_t>(enc,name) == boost::locale::conv::utf_to_utf<wchar_t>(utf));
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ TEST(boost::locale::conv::to_utf<char16_t>(enc,name) == boost::locale::conv::utf_to_utf<char16_t>(utf));
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ TEST(boost::locale::conv::to_utf<char32_t>(enc,name) == boost::locale::conv::utf_to_utf<char32_t>(utf));
+ #endif
+}
+
+void test_simple_conversions()
+{
+ namespace blc=boost::locale::conv;
+ std::cout << "- Testing correct invalid bytes skipping" << std::endl;
+ try {
+ std::cout << "-- ISO-8859-8" << std::endl;
+ test_skip("test \xE0\xE1\xFB-","test \xd7\x90\xd7\x91-","ISO-8859-8");
+ test_skip("\xFB","","ISO-8859-8");
+ test_skip("test \xE0\xE1\xFB","test \xd7\x90\xd7\x91","ISO-8859-8");
+ test_skip("\xFB-","-","ISO-8859-8");
+ }
+ catch(blc::invalid_charset_error const &) {
+ std::cout <<"--- not supported" << std::endl;
+ }
+ try {
+ std::cout << "-- cp932" << std::endl;
+ test_skip("test\xE0\xA0 \x83\xF8-","test\xe7\x87\xbf -","cp932","test\xe7\x87\xbf ");
+ test_skip("\x83\xF8","","cp932");
+ test_skip("test\xE0\xA0 \x83\xF8","test\xe7\x87\xbf ","cp932");
+ test_skip("\x83\xF8-","-","cp932","");
+ }
+ catch(blc::invalid_charset_error const &) {
+ std::cout <<"--- not supported" << std::endl;
+ }
+}
+
+
+int main()
+{
+ try {
+ std::vector<std::string> def;
+ #ifdef BOOST_LOCALE_WITH_ICU
+ def.push_back("icu");
+ #endif
+ #ifndef BOOST_LOCALE_NO_STD_BACKEND
+ def.push_back("std");
+ #endif
+ #ifndef BOOST_LOCALE_NO_WINAPI_BACKEND
+ def.push_back("winapi");
+ #endif
+ #ifndef BOOST_LOCALE_NO_POSIX_BACKEND
+ def.push_back("posix");
+ #endif
+
+ #if !defined(BOOST_LOCALE_WITH_ICU) && !defined(BOOST_LOCALE_WITH_ICONV) && (defined(BOOST_WINDOWS) || defined(__CYGWIN__))
+ test_iso_8859_8 = IsValidCodePage(28598)!=0;
+ #endif
+
+ test_simple_conversions();
+
+
+ for(int type = 0; type < int(def.size()); type ++ ) {
+ boost::locale::localization_backend_manager tmp_backend = boost::locale::localization_backend_manager::global();
+ tmp_backend.select(def[type]);
+ boost::locale::localization_backend_manager::global(tmp_backend);
+
+ std::string bname = def[type];
+
+ if(bname=="std") {
+ en_us_8bit = get_std_name("en_US.ISO8859-1");
+ he_il_8bit = get_std_name("he_IL.ISO8859-8");
+ ja_jp_shiftjis = get_std_name("ja_JP.SJIS");
+ if(!ja_jp_shiftjis.empty() && !test_std_supports_SJIS_codecvt(ja_jp_shiftjis))
+ {
+ std::cout << "Warning: detected unproper support of " << ja_jp_shiftjis << " locale, disableling it" << std::endl;
+ ja_jp_shiftjis = "";
+ }
+ }
+ else {
+ en_us_8bit = "en_US.ISO8859-1";
+ he_il_8bit = "he_IL.ISO8859-8";
+ ja_jp_shiftjis = "ja_JP.SJIS";
+ }
+
+ std::cout << "Testing for backend " << def[type] << std::endl;
+
+ test_iso = true;
+ if(bname=="std" && (he_il_8bit.empty() || en_us_8bit.empty())) {
+ std::cout << "no iso locales availible, passing" << std::endl;
+ test_iso = false;
+ }
+ test_sjis = true;
+ if(bname=="std" && ja_jp_shiftjis.empty()) {
+ test_sjis = false;
+ }
+ if(bname=="winapi") {
+ test_iso = false;
+ test_sjis = false;
+ }
+ test_utf = true;
+ #ifndef BOOST_LOCALE_NO_POSIX_BACKEND
+ if(bname=="posix") {
+ {
+ locale_t l = newlocale(LC_ALL_MASK,he_il_8bit.c_str(),0);
+ if(!l)
+ test_iso = false;
+ else
+ freelocale(l);
+ }
+ {
+ locale_t l = newlocale(LC_ALL_MASK,en_us_8bit.c_str(),0);
+ if(!l)
+ test_iso = false;
+ else
+ freelocale(l);
+ }
+ {
+ locale_t l = newlocale(LC_ALL_MASK,"en_US.UTF-8",0);
+ if(!l)
+ test_utf = false;
+ else
+ freelocale(l);
+ }
+ #ifdef BOOST_LOCALE_WITH_ICONV
+ {
+ locale_t l = newlocale(LC_ALL_MASK,ja_jp_shiftjis.c_str(),0);
+ if(!l)
+ test_sjis = false;
+ else
+ freelocale(l);
+ }
+ #else
+ test_sjis = false;
+ #endif
+ }
+ #endif
+
+ if(def[type]=="std" && (get_std_name("en_US.UTF-8").empty() || get_std_name("he_IL.UTF-8").empty()))
+ {
+ test_utf = false;
+ }
+
+ std::cout << "Testing wide I/O" << std::endl;
+ test_wide_io();
+ std::cout << "Testing charset to/from UTF conversion functions" << std::endl;
+ std::cout << " char" << std::endl;
+ test_to<char>();
+ std::cout << " wchar_t" << std::endl;
+ test_to<wchar_t>();
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ if(bname == "icu" || bname == "std") {
+ std::cout << " char16_t" << std::endl;
+ test_to<char16_t>();
+ }
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ if(bname == "icu" || bname == "std") {
+ std::cout << " char32_t" << std::endl;
+ test_to<char32_t>();
+ }
+ #endif
+
+ test_all_combinations();
+ }
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_codepage_converter.cpp b/src/boost/libs/locale/test/test_codepage_converter.cpp
new file mode 100644
index 000000000..a246b2923
--- /dev/null
+++ b/src/boost/libs/locale/test/test_codepage_converter.cpp
@@ -0,0 +1,323 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <boost/locale/util.hpp>
+#ifdef BOOST_LOCALE_WITH_ICU
+#include "../src/icu/codecvt.hpp"
+#endif
+#if defined(BOOST_LOCALE_WITH_ICONV) && !defined(BOOST_LOCALE_NO_POSIX_BACKEND)
+#include "../src/posix/codecvt.hpp"
+#endif
+
+#include <string.h>
+
+char *make2(unsigned v)
+{
+ static unsigned char buf[3] = {0};
+ buf[0] = 0xC0 | (v >> 6);
+ buf[1] = 0x80 | (v & 0x3F );
+ return reinterpret_cast<char*>(buf);
+}
+
+char *make3(unsigned v)
+{
+ static unsigned char buf[4] = {0};
+ buf[0] = 0xE0 | ((v >> 12) ) ;
+ buf[1] = 0x80 | ((v >> 6) & 0x3F );
+ buf[2] = 0x80 | ((v >> 0) & 0x3F );
+ return reinterpret_cast<char*>(buf);
+}
+
+char *make4(unsigned v)
+{
+ static unsigned char buf[5] = {0};
+ buf[0] = 0xF0 | ((v >> 18) ) ;
+ buf[1] = 0x80 | ((v >> 12) & 0x3F );
+ buf[2] = 0x80 | ((v >> 6) & 0x3F );
+ buf[3] = 0x80 | ((v >> 0) & 0x3F );
+ return reinterpret_cast<char*>(buf);
+}
+
+static const unsigned illegal=0xFFFFFFFF;
+static const unsigned incomplete=0xFFFFFFFE;
+
+
+bool test_to(boost::locale::util::base_converter &cvt,char const *s,unsigned codepoint)
+{
+ size_t len = strlen(s);
+ char const *end = s + len;
+ return cvt.to_unicode(s,end) == codepoint;
+}
+
+bool test_from(boost::locale::util::base_converter &cvt,unsigned codepoint,char const *str)
+{
+ char buf[32];
+ unsigned res = cvt.from_unicode(codepoint,buf,buf+sizeof(buf));
+ if(res == boost::locale::util::base_converter::illegal) {
+ return str == 0;
+ }
+ else {
+ return str!=0 && strlen(str) == res && memcmp(str,buf,res) == 0;
+ }
+}
+
+bool test_incomplete(boost::locale::util::base_converter &cvt,unsigned codepoint,int len)
+{
+ char buf[32];
+ unsigned res = cvt.from_unicode(codepoint,buf,buf+len);
+ return res == incomplete;
+}
+
+
+
+#define TEST_TO(str,codepoint) TEST(test_to(*cvt,str,codepoint))
+#define TEST_FROM(str,codepoint) TEST(test_from(*cvt,codepoint,str))
+#define TEST_INC(codepoint,len) TEST(test_incomplete(*cvt,codepoint,len))
+
+void test_shiftjis(boost::locale::util::base_converter* pcvt)
+{
+ boost::locale::hold_ptr<boost::locale::util::base_converter> cvt(pcvt);
+
+ std::cout << "- Correct" << std::endl;
+ TEST_TO("a",'a');
+ TEST_TO("X",'X');
+ TEST_TO("\xCB",0xFF8b); // half width katakana Hi ヒ
+ TEST_TO("\x83\x71",0x30d2); // Full width katakana Hi ヒ
+ TEST_TO("\x82\xd0",0x3072); // Full width hiragana Hi ひ
+
+ TEST_FROM("a",'a');
+ TEST_FROM("X",'X');
+ TEST_FROM("\xCB",0xFF8b); // half width katakana Hi ヒ
+ TEST_FROM("\x83\x71",0x30d2); // Full width katakana Hi ヒ
+ TEST_FROM("\x82\xd0",0x3072); // Full width hiragana Hi ひ
+
+ std::cout << "- Illegal/incomplete" << std::endl;
+
+ TEST_TO("\xa0",illegal);
+ TEST_TO("\x82",incomplete);
+ TEST_TO("\x83\xf0",illegal);
+
+ TEST_INC(0x30d2,1); // Full width katakana Hi ヒ
+ TEST_INC(0x3072,1); // Full width hiragana Hi ひ
+
+ TEST_FROM(0,0x5e9); // Hebrew ש not in ShiftJIS
+}
+
+
+int main()
+{
+ try {
+ using namespace boost::locale::util;
+
+ #ifndef BOOST_NO_CXX11_SMART_PTR
+ std::unique_ptr<base_converter> cvt;
+ #else
+ std::auto_ptr<base_converter> cvt;
+ #endif
+
+ std::cout << "Test UTF-8" << std::endl;
+ std::cout << "- From UTF-8" << std::endl;
+
+
+ #ifndef BOOST_NO_CXX11_SMART_PTR
+ cvt = std::move(create_utf8_converter_unique_ptr());
+ #else
+ cvt = create_utf8_converter();
+ #endif
+
+ TEST(cvt.get());
+ TEST(cvt->is_thread_safe());
+ TEST(cvt->max_len() == 4);
+
+ std::cout << "-- Correct" << std::endl;
+
+ TEST_TO("\x7f",0x7f);
+ TEST_TO("\xC2\x80",0x80);
+ TEST_TO("\xdf\xBF",0x7FF);
+ TEST_TO("\xe0\xa0\x80",0x800);
+ TEST_TO("\xef\xbf\xbf",0xFFFF);
+ TEST_TO("\xf0\x90\x80\x80",0x10000);
+ TEST_TO("\xf4\x8f\xbf\xbf",0x10FFFF);
+
+ std::cout << "-- Too big" << std::endl;
+ TEST_TO("\xf4\x9f\x80\x80",illegal); // 11 0000
+ TEST_TO("\xfb\xbf\xbf\xbf",illegal); // 3FF FFFF
+ TEST_TO("\xf8\x90\x80\x80\x80",illegal); // 400 0000
+ TEST_TO("\xfd\xbf\xbf\xbf\xbf\xbf",illegal); // 7fff ffff
+
+ std::cout << "-- Invalid trail" << std::endl;
+ TEST_TO("\xC2\x7F",illegal);
+ TEST_TO("\xdf\x7F",illegal);
+ TEST_TO("\xe0\x7F\x80",illegal);
+ TEST_TO("\xef\xbf\x7F",illegal);
+ TEST_TO("\xe0\x7F\x80",illegal);
+ TEST_TO("\xef\xbf\x7F",illegal);
+ TEST_TO("\xf0\x7F\x80\x80",illegal);
+ TEST_TO("\xf4\x7f\xbf\xbf",illegal);
+ TEST_TO("\xf0\x90\x7F\x80",illegal);
+ TEST_TO("\xf4\x8f\x7F\xbf",illegal);
+ TEST_TO("\xf0\x90\x80\x7F",illegal);
+ TEST_TO("\xf4\x8f\xbf\x7F",illegal);
+
+ std::cout << "-- Invalid length" << std::endl;
+
+ /// Test that this actually works
+ TEST_TO(make2(0x80),0x80);
+ TEST_TO(make2(0x7ff),0x7ff);
+
+ TEST_TO(make3(0x800),0x800);
+ TEST_TO(make3(0xffff),0xffff);
+
+ TEST_TO(make4(0x10000),0x10000);
+ TEST_TO(make4(0x10ffff),0x10ffff);
+
+ TEST_TO(make4(0x110000),illegal);
+ TEST_TO(make4(0x1fffff),illegal);
+
+ TEST_TO(make2(0),illegal);
+ TEST_TO(make3(0),illegal);
+ TEST_TO(make4(0),illegal);
+ TEST_TO(make2(0x7f),illegal);
+ TEST_TO(make3(0x7f),illegal);
+ TEST_TO(make4(0x7f),illegal);
+
+ TEST_TO(make3(0x80),illegal);
+ TEST_TO(make4(0x80),illegal);
+ TEST_TO(make3(0x7ff),illegal);
+ TEST_TO(make4(0x7ff),illegal);
+
+ TEST_TO(make4(0x8000),illegal);
+ TEST_TO(make4(0xffff),illegal);
+
+ std::cout << "-- Invalid surrogate" << std::endl;
+
+ TEST_TO(make3(0xD800),illegal);
+ TEST_TO(make3(0xDBFF),illegal);
+ TEST_TO(make3(0xDC00),illegal);
+ TEST_TO(make3(0xDFFF),illegal);
+
+ TEST_TO(make4(0xD800),illegal);
+ TEST_TO(make4(0xDBFF),illegal);
+ TEST_TO(make4(0xDC00),illegal);
+ TEST_TO(make4(0xDFFF),illegal);
+
+ std::cout <<"-- Incomplete" << std::endl;
+
+ TEST_TO("\x80",illegal);
+ TEST_TO("\xC2",incomplete);
+
+ TEST_TO("\xdf",incomplete);
+
+ TEST_TO("\xe0",incomplete);
+ TEST_TO("\xe0\xa0",incomplete);
+
+ TEST_TO("\xef\xbf",incomplete);
+ TEST_TO("\xef",incomplete);
+
+ TEST_TO("\xf0\x90\x80",incomplete);
+ TEST_TO("\xf0\x90",incomplete);
+ TEST_TO("\xf0",incomplete);
+
+ TEST_TO("\xf4\x8f\xbf",incomplete);
+ TEST_TO("\xf4\x8f",incomplete);
+ TEST_TO("\xf4",incomplete);
+
+ std::cout << "- To UTF-8" << std::endl;
+
+ std::cout << "-- Test correct" << std::endl;
+
+ TEST_FROM("\x7f",0x7f);
+ TEST_FROM("\xC2\x80",0x80);
+ TEST_FROM("\xdf\xBF",0x7FF);
+ TEST_INC(0x7FF,1);
+ TEST_FROM("\xe0\xa0\x80",0x800);
+ TEST_INC(0x800,2);
+ TEST_INC(0x800,1);
+ TEST_FROM("\xef\xbf\xbf",0xFFFF);
+ TEST_INC(0x10000,3);
+ TEST_INC(0x10000,2);
+ TEST_INC(0x10000,1);
+ TEST_FROM("\xf0\x90\x80\x80",0x10000);
+ TEST_FROM("\xf4\x8f\xbf\xbf",0x10FFFF);
+
+ std::cout << "-- Test no surrogate " << std::endl;
+
+ TEST_FROM(0,0xD800);
+ TEST_FROM(0,0xDBFF);
+ TEST_FROM(0,0xDC00);
+ TEST_FROM(0,0xDFFF);
+
+ std::cout << "-- Test invalid " << std::endl;
+
+ TEST_FROM(0,0x110000);
+ TEST_FROM(0,0x1FFFFF);
+
+
+ std::cout << "Test windows-1255" << std::endl;
+
+ #ifndef BOOST_NO_CXX11_SMART_PTR
+ cvt = std::move(create_simple_converter_unique_ptr("windows-1255"));
+ #else
+ cvt = create_simple_converter("windows-1255");
+ #endif
+
+ TEST(cvt.get());
+ TEST(cvt->is_thread_safe());
+ TEST(cvt->max_len() == 1);
+
+ std::cout << "- From 1255" << std::endl;
+
+ TEST_TO("\xa4",0x20aa);
+ TEST_TO("\xe0",0x05d0);
+ TEST_TO("\xc4",0x5b4);
+ TEST_TO("\xfb",illegal);
+ TEST_TO("\xdd",illegal);
+ TEST_TO("\xff",illegal);
+ TEST_TO("\xfe",0x200f);
+
+ std::cout << "- To 1255" << std::endl;
+
+ TEST_FROM("\xa4",0x20aa);
+ TEST_FROM("\xe0",0x05d0);
+ TEST_FROM("\xc4",0x5b4);
+ TEST_FROM("\xfe",0x200f);
+
+ TEST_FROM(0,0xe4);
+ TEST_FROM(0,0xd0);
+
+ #ifdef BOOST_LOCALE_WITH_ICU
+ std::cout << "Testing Shift-JIS using ICU/uconv" << std::endl;
+
+ cvt.reset(boost::locale::impl_icu::create_uconv_converter("Shift-JIS"));
+ TEST(cvt.get());
+ test_shiftjis(cvt.release());
+ #endif
+
+ #if defined(BOOST_LOCALE_WITH_ICONV) && !defined(BOOST_LOCALE_NO_POSIX_BACKEND)
+ std::cout << "Testing Shift-JIS using POSIX/iconv" << std::endl;
+
+ cvt.reset(boost::locale::impl_posix::create_iconv_converter("Shift-JIS"));
+ if(cvt.get()) {
+ test_shiftjis(cvt.release());
+ }
+ else {
+ std::cout<< "- Shift-JIS is not supported!" << std::endl;
+ }
+ #endif
+
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_collate.cpp b/src/boost/libs/locale/test/test_collate.cpp
new file mode 100644
index 000000000..60f63abe9
--- /dev/null
+++ b/src/boost/libs/locale/test/test_collate.cpp
@@ -0,0 +1,139 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_LOCALE_WITH_ICU
+#include <iostream>
+int main()
+{
+ std::cout << "ICU is not build... Skipping" << std::endl;
+}
+#else
+
+#include <boost/locale/collator.hpp>
+#include <boost/locale/generator.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+
+
+template<typename Char>
+void test_comp(std::locale l,std::basic_string<Char> left,std::basic_string<Char> right,int ilevel,int expected)
+{
+ typedef std::basic_string<Char> string_type;
+ boost::locale::collator_base::level_type level = static_cast<boost::locale::collator_base::level_type>(ilevel);
+ TEST(boost::locale::comparator<Char>(l,level)(left,right) == (expected < 0));
+ if(ilevel==4) {
+ std::collate<Char> const &coll=std::use_facet<std::collate<Char> >(l);
+ string_type lt=coll.transform(left.c_str(),left.c_str()+left.size());
+ string_type rt=coll.transform(right.c_str(),right.c_str()+right.size());
+ if(expected < 0)
+ TEST(lt<rt);
+ else if(expected == 0) {
+ TEST(lt==rt);
+ }
+ else
+ TEST(lt > rt);
+ long lh=coll.hash(left.c_str(),left.c_str()+left.size());
+ long rh=coll.hash(right.c_str(),right.c_str()+right.size());
+ if(expected == 0)
+ TEST(lh==rh);
+ else
+ TEST(lh!=rh);
+ }
+ boost::locale::collator<Char> const &coll=std::use_facet<boost::locale::collator<Char> >(l);
+ string_type lt=coll.transform(level,left.c_str(),left.c_str()+left.size());
+ TEST(lt==coll.transform(level,left));
+ string_type rt=coll.transform(level,right.c_str(),right.c_str()+right.size());
+ TEST(rt==coll.transform(level,right));
+ if(expected < 0)
+ TEST(lt<rt);
+ else if(expected == 0)
+ TEST(lt==rt);
+ else
+ TEST(lt > rt);
+ long lh=coll.hash(level,left.c_str(),left.c_str()+left.size());
+ TEST(lh==coll.hash(level,left));
+ long rh=coll.hash(level,right.c_str(),right.c_str()+right.size());
+ TEST(rh==coll.hash(level,right));
+ if(expected == 0)
+ TEST(lh==rh);
+ else
+ TEST(lh!=rh);
+
+}
+
+#define TEST_COMP(c,_l,_r) test_comp<c>(l,_l,_r,level,expected)
+
+
+void compare(std::string left,std::string right,int level,int expected)
+{
+ boost::locale::generator gen;
+ std::locale l=gen("en_US.UTF-8");
+ if(level == 4)
+ TEST(l(left,right) == (expected < 0));
+ TEST_COMP(char,left,right);
+ TEST_COMP(wchar_t,to<wchar_t>(left),to<wchar_t>(right));
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ TEST_COMP(char16_t,to<char16_t>(left),to<char16_t>(right));
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ TEST_COMP(char32_t,to<char32_t>(left),to<char32_t>(right));
+ #endif
+ l=gen("en_US.ISO8859-1");
+ if(level == 4)
+ TEST(l(to<char>(left),to<char>(right)) == (expected < 0));
+ TEST_COMP(char,to<char>(left),to<char>(right));
+}
+
+
+void test_collate()
+{
+ int
+ primary = 0,
+ secondary = 1,
+ tertiary = 2,
+ quaternary = 3,
+ identical = 4;
+ int le = -1,gt = 1,eq = 0;
+
+
+ compare("a","A",primary,eq);
+ compare("a","A",secondary,eq);
+ compare("A","a",tertiary,gt);
+ compare("a","A",tertiary,le);
+ compare("a","A",quaternary,le);
+ compare("A","a",quaternary,gt);
+ compare("a","A",identical,le);
+ compare("A","a",identical,gt);
+ compare("a","ä",primary,eq); // a , ä
+ compare("a","ä",secondary,le); // a , ä
+ compare("ä","a",secondary,gt); // a , ä
+ compare("a","ä",quaternary,le); // a , ä
+ compare("ä","a",quaternary,gt); // a , ä
+ compare("a","ä",identical,le); // a , ä
+ compare("ä","a",identical,gt); // a , ä
+}
+
+
+
+
+int main()
+{
+ try {
+ test_collate();
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // NOICU
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_config.cpp b/src/boost/libs/locale/test/test_config.cpp
new file mode 100644
index 000000000..2205a8659
--- /dev/null
+++ b/src/boost/libs/locale/test/test_config.cpp
@@ -0,0 +1,133 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <iostream>
+#include <iomanip>
+#include <stdlib.h>
+#include <locale.h>
+#include <locale>
+#include <time.h>
+#include <stdexcept>
+
+#include <boost/locale.hpp>
+#ifdef BOOST_LOCALE_WITH_ICU
+#include <unicode/uversion.h>
+#endif
+
+#include "test_locale_tools.hpp"
+
+
+char const *env(char const *s)
+{
+ char const *r=getenv(s);
+ if(r)
+ return r;
+ return "";
+}
+
+void check_locale(char const **names)
+{
+ std::cout << " " << std::setw(32) << "locale" << std::setw(4) << "C" << std::setw(4) << "C++" << std::endl;
+ while(*names) {
+ char const *name = *names;
+ std::cout << " " << std::setw(32) << name << std::setw(4);
+ if(setlocale(LC_ALL,name)!=0)
+ std::cout << "Yes";
+ else
+ std::cout << "No";
+ std::cout << std::setw(4);
+ try {
+ std::locale l(name);
+ std::cout << "Yes";
+ }
+ catch(std::exception const &) {
+ std::cout << "No";
+ }
+ std::cout << std::endl;
+ names++;
+ }
+}
+
+int main()
+{
+ std::cout << "- Backends: ";
+ #ifdef BOOST_LOCALE_WITH_ICU
+ std::cout << "icu:" << U_ICU_VERSION << " ";
+ #endif
+ #ifndef BOOST_LOCALE_NO_STD_BACKEND
+ std::cout << "std ";
+ #endif
+ #ifndef BOOST_LOCALE_NO_POSIX_BACKEND
+ std::cout << "posix ";
+ #endif
+ #ifndef BOOST_LOCALE_NO_WINAPI_BACKEND
+ std::cout << "winapi";
+ #endif
+ std::cout << std::endl;
+ #ifdef BOOST_LOCALE_WITH_ICONV
+ std::cout << "- With iconv" << std::endl;
+ #else
+ std::cout << "- Without iconv" << std::endl;
+ #endif
+ std::cout << "- Environment " << std::endl;
+ std::cout << " LANG="<< env("LANG") << std::endl;
+ std::cout << " LC_ALL="<< env("LC_ALL") << std::endl;
+ std::cout << " LC_CTYPE="<< env("LC_CTYPE") << std::endl;
+ std::cout << " TZ="<< env("TZ") << std::endl;
+
+ char const *clocale=setlocale(LC_ALL,"");
+ if(!clocale)
+ clocale= "undetected";
+ std::cout <<"- C locale: " << clocale << std::endl;
+
+ try {
+ std::locale loc("");
+ std::cout << "- C++ locale: " << loc.name() << std::endl;
+ }
+ catch(std::exception const &) {
+ std::cout << "- C++ locale: is not supported" << std::endl;
+ }
+
+ char const *locales_to_check[] = {
+ "en_US.UTF-8", "en_US.ISO8859-1", "English_United States.1252",
+ "he_IL.UTF-8", "he_IL.ISO8859-8", "Hebrew_Israel.1255",
+ "ru_RU.UTF-8", "Russian_Russia.1251",
+ "tr_TR.UTF-8", "Turkish_Turkey.1254",
+ "ja_JP.UTF-8", "ja_JP.SJIS", "Japanese_Japan.932",
+ 0
+ };
+ std::cout << "- Testing locales availability on the operation system:" << std::endl;
+ check_locale(locales_to_check);
+ std::cout << "--- Testing Japanese_Japan.932 is working: " << test_std_supports_SJIS_codecvt("Japanese_Japan.932") << std::endl;
+
+ std::cout << "- Testing timezone and time " << std::endl;
+ {
+ setlocale(LC_ALL,"C");
+ time_t now = time(0);
+ char buf[1024];
+ strftime(buf,sizeof(buf),"%%c=%c; %%Z=%Z; %%z=%z",localtime(&now));
+ std::cout << " Local Time :" << buf << std::endl;
+ strftime(buf,sizeof(buf),"%%c=%c; %%Z=%Z; %%z=%z",gmtime(&now));
+ std::cout << " Universal Time:" << buf << std::endl;
+ }
+ std::cout << "- Boost.Locale's locale: ";
+ try {
+ boost::locale::generator gen;
+ std::locale l = gen("");
+ std::cout << std::use_facet<boost::locale::info>(l).name() << std::endl;
+ }
+ catch(std::exception const &) {
+ std::cout << " undetected" << std::endl;
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_convert.cpp b/src/boost/libs/locale/test/test_convert.cpp
new file mode 100644
index 000000000..36f6e572b
--- /dev/null
+++ b/src/boost/libs/locale/test/test_convert.cpp
@@ -0,0 +1,129 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_WITH_ICU
+#include <iostream>
+int main()
+{
+ std::cout << "ICU is not build... Skipping" << std::endl;
+}
+#else
+
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/info.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+
+
+template<typename Char>
+void test_normc(std::basic_string<Char> orig,std::basic_string<Char> normal,boost::locale::norm_type type)
+{
+ std::locale l = boost::locale::generator().generate("en_US.UTF-8");
+ TEST(normalize(orig,type,l)==normal);
+ TEST(normalize(orig.c_str(),type,l)==normal);
+ TEST(normalize(orig.c_str(),orig.c_str()+orig.size(),type,l)==normal);
+}
+
+void test_norm(std::string orig,std::string normal,boost::locale::norm_type type)
+{
+ test_normc<char>(orig,normal,type);
+ test_normc<wchar_t>(to<wchar_t>(orig),to<wchar_t>(normal),type);
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ test_normc<char16_t>(to<char16_t>(orig),to<char16_t>(normal),type);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ test_normc<char32_t>(to<char32_t>(orig),to<char32_t>(normal),type);
+ #endif
+}
+
+#define TEST_A(Chr,how,source,dest) \
+ do { \
+ boost::locale::info const &inf=std::use_facet<boost::locale::info>(std::locale()); \
+ std::cout <<"Testing " #how " for " #Chr ", lang="<<inf.language(); \
+ if(std::string("char")==#Chr) std::cout <<" charset="<< inf.encoding(); \
+ std::cout << std::endl; \
+ std::basic_string<Chr> source_s=(source),dest_s=(dest); \
+ TEST(boost::locale::how(source_s)==dest_s); \
+ TEST(boost::locale::how(source_s.c_str())==dest_s); \
+ TEST(boost::locale::how(source_s.c_str(),source_s.c_str()+source_s.size())==dest_s);\
+ }while(0)
+
+#define TEST_ALL_CASES \
+ do { \
+ eight_bit=true; \
+ std::locale::global(gen("en_US.UTF-8")); \
+ TEST_V(to_upper,"grüßen i","GRÜSSEN I"); \
+ TEST_V(to_lower,"Façade","façade"); \
+ TEST_V(to_title,"façadE world","Façade World"); \
+ TEST_V(fold_case,"Hello World","hello world"); \
+ std::locale::global(gen("tr_TR.UTF-8")); \
+ eight_bit=false; \
+ TEST_V(to_upper,"i","İ"); \
+ TEST_V(to_lower,"İ","i"); \
+ }while(0)
+
+
+int main()
+{
+ try {
+ {
+ using namespace boost::locale;
+ std::cout << "Testing Unicode normalization" << std::endl;
+ test_norm("\xEF\xAC\x81","\xEF\xAC\x81",norm_nfd); /// ligature fi
+ test_norm("\xEF\xAC\x81","\xEF\xAC\x81",norm_nfc);
+ test_norm("\xEF\xAC\x81","fi",norm_nfkd);
+ test_norm("\xEF\xAC\x81","fi",norm_nfkc);
+ test_norm("ä","ä",norm_nfd); // ä to a and accent
+ test_norm("ä","ä",norm_nfc);
+ }
+
+ boost::locale::generator gen;
+ bool eight_bit=true;
+
+ #define TEST_V(how,source_s,dest_s) \
+ do { \
+ TEST_A(char,how,source_s,dest_s); \
+ if(eight_bit) { \
+ std::locale tmp=std::locale(); \
+ std::locale::global(gen("en_US.ISO8859-1")); \
+ TEST_A(char,how,to<char>(source_s),to<char>(dest_s)); \
+ std::locale::global(tmp); \
+ } \
+ }while(0)
+
+ TEST_ALL_CASES;
+ #undef TEST_V
+
+ #define TEST_V(how,source_s,dest_s) TEST_A(wchar_t,how,to<wchar_t>(source_s),to<wchar_t>(dest_s))
+ TEST_ALL_CASES;
+ #undef TEST_V
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ #define TEST_V(how,source_s,dest_s) TEST_A(char16_t,how,to<char16_t>(source_s),to<char16_t>(dest_s))
+ TEST_ALL_CASES;
+ #undef TEST_V
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ #define TEST_V(how,source_s,dest_s) TEST_A(char32_t,how,to<char32_t>(source_s),to<char32_t>(dest_s))
+ TEST_ALL_CASES;
+ #undef TEST_V
+ #endif
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+#endif // NO ICU
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_date_time.cpp b/src/boost/libs/locale/test/test_date_time.cpp
new file mode 100644
index 000000000..91af52870
--- /dev/null
+++ b/src/boost/libs/locale/test/test_date_time.cpp
@@ -0,0 +1,302 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/locale/date_time.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+
+#ifdef BOOST_LOCALE_WITH_ICU
+#include <unicode/uversion.h>
+#define BOOST_ICU_VER (U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM)
+#else
+#define BOOST_ICU_VER 406
+#endif
+
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4244) // loose data
+#endif
+
+#define RESET() do { time_point = base_time_point; ss.str(""); } while(0)
+#define TESTR(X) do { TEST(X); RESET(); } while(0)
+//#define TESTEQSR(t,X) do { ss << (t); TESTR(ss.str() == X); } while(0)
+#define TESTEQSR(t,X) do { ss << (t); if(ss.str()!=X) { std::cerr <<"[" << ss.str() <<"]!=[" <<X<<"]" << std::endl; } TESTR(ss.str() == X); } while(0)
+
+int main()
+{
+ try {
+ using namespace boost::locale;
+ using namespace boost::locale::period;
+ std::string def[] = {
+ #ifdef BOOST_LOCALE_WITH_ICU
+ "icu" ,
+ #endif
+ #ifndef BOOST_LOCALE_NO_STD_BACKEND
+ "std" ,
+ #endif
+ #ifndef BOOST_LOCALE_NO_POSIX_BACKEND
+ "posix",
+ #endif
+ #ifndef BOOST_LOCALE_NO_WINAPI_BACKEND
+ "winapi",
+ #endif
+ };
+ for(int type = 0 ; type < int(sizeof(def)/sizeof(def[0])) ; type ++ ) {
+ boost::locale::localization_backend_manager tmp_backend = boost::locale::localization_backend_manager::global();
+ tmp_backend.select(def[type]);
+ boost::locale::localization_backend_manager::global(tmp_backend);
+ std::cout << "Testing for backend: " << def[type] << std::endl;
+ std::string backend_name = def[type];
+ {
+
+ boost::locale::generator g;
+
+ std::locale loc=g("en_US.UTF-8");
+
+ std::locale::global(loc);
+
+ std::string tz("GMT");
+ time_zone::global(tz);
+ calendar cal(loc,tz);
+
+ TEST(calendar() == cal);
+ TEST(calendar(loc) == cal);
+ TEST(calendar(tz) == cal);
+ TEST(calendar(loc,"GMT+01:00") != cal);
+ TEST(calendar(g("ru_RU.UTF-8")) != cal);
+
+ TEST(cal.minimum(month())==0);
+ TEST(cal.maximum(month())==11);
+ TEST(cal.minimum(day())==1);
+ TEST(cal.greatest_minimum(day())==1);
+ TEST(cal.least_maximum(day())==28);
+ TEST(cal.maximum(day())==31);
+
+ TEST(calendar(g("ar_EG.UTF-8")).first_day_of_week() == 7);
+ TEST(calendar(g("he_IL.UTF-8")).first_day_of_week() == 1);
+ TEST(calendar(g("ru_RU.UTF-8")).first_day_of_week() == 2);
+
+ std::ostringstream ss;
+ ss.imbue(loc);
+ ss<<boost::locale::as::time_zone(tz);
+
+ date_time time_point;
+
+ time_point=year(1970) + february() + day(5);
+
+ ss << as::ftime("%Y-%m-%d")<< time_point;
+
+ TEST(ss.str() == "1970-02-05");
+ time_point = 3 * hour_12() + 1 * am_pm() + 33 * minute() + 13 * second();
+ ss.str("");
+ ss << as::ftime("%Y-%m-%d %H:%M:%S") << time_point;
+ TEST( ss.str() == "1970-02-05 15:33:13"); ss.str("");
+
+ time_t a_date = 3600*24*(31+4); // Feb 5th
+ time_t a_time = 3600*15+60*33; // 15:33:05
+ time_t a_timesec = 13;
+ time_t a_datetime = a_date + a_time + a_timesec;
+
+ date_time base_time_point=date_time(a_datetime);
+
+ RESET();
+
+ time_point += hour();
+ TESTEQSR(time_point,"1970-02-05 16:33:13");
+
+ TEST(time_point.minimum(day())==1);
+ TEST(time_point.maximum(day())==28);
+
+ time_point += year() * 2 + 1 *month();
+ TESTEQSR(time_point,"1972-03-05 15:33:13");
+
+ time_point -= minute();
+ TESTEQSR( time_point, "1970-02-05 15:32:13");
+
+ time_point <<= minute() * 30;
+ TESTEQSR( time_point, "1970-02-05 15:03:13");
+
+ time_point >>= minute(40);
+ TESTEQSR( time_point, "1970-02-05 15:53:13");
+
+ TEST((time_point + month()) / month() == 2);
+ TEST(month(time_point + month(1)) == 2);
+ TEST(time_point / month() == 1);
+ TEST((time_point - month()) / month()== 0);
+ TEST(time_point / month() == 1);
+ TEST((time_point << month()) / month()== 2);
+ TEST(time_point / month()== 1);
+ TEST((time_point >> month()) / month()== 0);
+ TEST(time_point / month()== 1);
+
+
+
+ TEST( (time_point + 2 * hour() - time_point) / minute() == 120);
+ TEST( (time_point + month()- time_point) / day() == 28);
+ TEST( (time_point + 2* month()- (time_point+month())) / day() == 31);
+ TEST( day(time_point + 2* month()- (time_point+month())) == 31);
+
+ TESTEQSR( time_point + hour(), "1970-02-05 16:33:13");
+ TESTEQSR( time_point - hour(2), "1970-02-05 13:33:13");
+ TESTEQSR( time_point >> minute(), "1970-02-05 15:32:13");
+ TESTEQSR( time_point << second(), "1970-02-05 15:33:14");
+
+ TEST(time_point == time_point);
+ TEST(!(time_point != time_point));
+ TEST(time_point.get(hour()) == 15);
+ TEST(time_point/hour() == 15);
+ TEST(time_point+year() != time_point);
+ TEST(time_point - minute() <= time_point);
+ TEST(time_point <= time_point);
+ TEST(time_point + minute() >= time_point);
+ TEST(time_point >= time_point);
+
+ TEST(time_point < time_point + second());
+ TEST(!(time_point < time_point - second()));
+ TEST(time_point > time_point - second());
+ TEST(!(time_point > time_point + second()));
+
+ TEST(time_point.get(day()) == 5);
+ TEST(time_point.get(year()) == 1970);
+
+ TEST(time_point.get(era()) == 1);
+ TEST(time_point.get(year()) == 1970);
+ TEST(time_point.get(extended_year()) == 1970);
+ if(backend_name == "icu") {
+ time_point=extended_year(-3);
+ TEST(time_point.get(era()) == 0);
+ TEST(time_point.get(year()) == 4);
+ }
+ RESET();
+ TEST(time_point.get(month()) == 1);
+ TEST(time_point.get(day()) == 5);
+ TEST(time_point.get(day_of_year()) == 36);
+ TEST(time_point.get(day_of_week()) == 5);
+ TEST(time_point.get(day_of_week_in_month())==1);
+ time_point=date_time(a_datetime,calendar(g("ru_RU.UTF-8")));
+ TEST(time_point.get(day_of_week_local()) == 4);
+ time_point = year(2026) + january() + day(1);
+ TEST(time_point.get(day_of_week()) == 5);
+ TEST(time_point.get(week_of_year()) == 1);
+ TEST(time_point.get(week_of_month()) == 1);
+ time_point = day_of_week() * 1;
+ TEST(time_point.get(day()) == 4);
+ TEST(time_point.get(week_of_year()) == 1);
+ TEST(time_point.get(week_of_month()) == 1);
+ time_point += day() * 1;
+ TEST(time_point.get(week_of_year()) == 2);
+ TEST(time_point.get(week_of_month()) == 2);
+ time_point = february() + day() * 2;
+
+
+ TEST(time_point.get(week_of_year()) == 6);
+
+ if(backend_name!="icu" || BOOST_ICU_VER<408 || BOOST_ICU_VER > 6000) {
+ TEST(time_point.get(week_of_month()) == 1);
+ }
+ else {
+ // cldr changes
+ TEST(time_point.get(week_of_month()) == 2);
+ }
+
+ time_point = year(2010) + january() + day() * 3;
+
+ if(backend_name!="icu" || BOOST_ICU_VER<408 || BOOST_ICU_VER > 6000) {
+ TEST(time_point.get(week_of_year()) == 53);
+ }
+ else {
+ TEST(time_point.get(week_of_year()) == 1);
+ }
+
+ time_point = year()*2010 + january() + day() * 4;
+
+ if(backend_name!="icu" || BOOST_ICU_VER<408 || BOOST_ICU_VER > 6000) {
+ TEST(time_point.get(week_of_year()) == 1);
+ }
+ else {
+ TEST(time_point.get(week_of_year()) == 2);
+ }
+ time_point = year()*2010 + january() + day() * 10;
+
+ if(backend_name!="icu" || BOOST_ICU_VER<408 || BOOST_ICU_VER > 6000) {
+ TEST(time_point.get(week_of_year()) == 1);
+ }
+ else {
+ TEST(time_point.get(week_of_year()) == 2);
+ }
+
+ time_point = year()*2010 + january() + day() * 11;
+ if(backend_name!="icu" || BOOST_ICU_VER<408 || BOOST_ICU_VER > 6000) {
+ TEST(time_point.get(week_of_year()) == 2);
+ }
+ else {
+ TEST(time_point.get(week_of_year()) == 3);
+ }
+ RESET();
+ TEST(time_point.get(hour()) == 15);
+ TEST(date_time(a_datetime,calendar("GMT+01:00")).get(hour()) ==16);
+ TEST(time_point.get(hour_12()) == 3);
+ TEST(time_point.get(am_pm()) == 1);
+ TEST(time_point.get(minute()) == 33);
+ TEST(time_point.get(second()) == 13);
+ TEST(date_time(year()* 1984 + february() + day()).get(week_of_year())==5);
+ TEST(time_point.get(week_of_month()) == 1);
+ RESET();
+
+ // Make sure we don't get year() < 1970 so the test would
+ // work on windows where mktime supports positive time_t
+ // only
+ time_point = year() * 2010;
+
+ TEST((time_point + year() *1 - hour() * 1 - time_point) / year() == 0);
+ TEST((time_point + year() *1 - time_point) / year() == 1);
+ TEST((time_point + year() *1 + hour() * 1 - time_point) / year() == 1);
+ TEST((time_point - year() *1 + hour() * 1 - time_point) / year() == 0);
+ TEST((time_point - year() *1 - time_point) / year() == -1);
+ TEST((time_point - year() *1 - hour() * 1 - time_point) / year() == -1);
+
+ RESET();
+
+ time_point.time(24*3600 * 2);
+
+ time_point = year() * 2011;
+ time_point = march();
+ time_point = day() * 29;
+
+ date_time tmp_save = time_point;
+
+ time_point = year() * 2011;
+ time_point = february();
+ time_point = day() * 5;
+
+ TEST(time_point.get(year()) == 2011);
+ TEST(time_point.get(month()) == 2); // march
+ TEST(time_point.get(day()) == 5);
+
+ time_point = tmp_save;
+
+ time_point = year() * 2011 + february() + day() * 5;
+ TEST(time_point.get(year()) == 2011);
+ TEST(time_point.get(month()) == 1); // february
+ TEST(time_point.get(day()) == 5);
+
+ } // test
+ } // for loop
+
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_formatting.cpp b/src/boost/libs/locale/test/test_formatting.cpp
new file mode 100644
index 000000000..4a337f26c
--- /dev/null
+++ b/src/boost/libs/locale/test/test_formatting.cpp
@@ -0,0 +1,576 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_LOCALE_WITH_ICU
+#include <iostream>
+int main()
+{
+ std::cout << "ICU is not build... Skipping" << std::endl;
+}
+#else
+
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+// Disable this "security crap"
+#endif
+
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/format.hpp>
+#include <boost/locale/date_time.hpp>
+#include <boost/locale/generator.hpp>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+#include <limits>
+
+#include <unicode/uversion.h>
+
+using namespace boost::locale;
+
+//#define TEST_DEBUG
+#ifdef BOOST_MSVC
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#ifdef TEST_DEBUG
+#undef BOOST_LOCALE_ENABLE_CHAR16_T
+#undef BOOST_LOCALE_ENABLE_CHAR32_T
+template<typename T>
+void print_diff(T const &,T const &,int)
+{
+}
+template<>
+void print_diff(std::string const &l,std::string const &r,int line)
+{
+ if(l!=r) {
+ std::cerr << "----[" << l <<"]!=\n----["<<r<<"] in " << line << std::endl;
+ }
+}
+
+#define TESTEQ(x,y) do { print_diff((x),(y),__LINE__); TEST((x)==(y)); } while(0)
+#else
+#define TESTEQ(x,y) TEST((x)==(y))
+#endif
+
+#define TEST_FMT(manip,value,expected) \
+do{ \
+ std::basic_ostringstream<CharType> ss; \
+ ss.imbue(loc); \
+ ss << manip << value; \
+ TESTEQ(ss.str(),to_correct_string<CharType>(expected,loc)); \
+}while(0)
+
+#ifndef _LIBCPP_VERSION
+static bool parsing_fails()
+{
+ return true;
+}
+#else
+static bool parsing_fails()
+{
+ static bool checked=false;
+ static bool fails;
+ if(!checked) {
+ try {
+ std::istringstream ss("x");
+ ss.exceptions(std::ios_base::failbit);
+ int x;
+ ss>>x;
+ fails =false;
+ }
+ catch(std::ios_base::failure const &) {
+ fails=true;
+ }
+ catch(...) {
+ fails=false;
+ }
+ checked=true;
+ if(!fails) {
+ std::cerr << "!!! Warning: libc++ library does not throw an exception on failbit !!!" << std::endl;
+ }
+ }
+ return fails;
+}
+#endif
+
+
+#define TEST_NOPAR(manip,actual,type) \
+do{ \
+ type v; \
+ std::basic_string<CharType> act= \
+ to_correct_string<CharType>(actual,loc); \
+ { \
+ std::basic_istringstream<CharType> ss; \
+ ss.imbue(loc); \
+ ss.str(act); \
+ ss >> manip >> v ; \
+ TEST(ss.fail()); \
+ } \
+ if(parsing_fails()){ \
+ std::basic_istringstream<CharType> ss; \
+ ss.imbue(loc); \
+ ss.str(act); \
+ ss.exceptions(std::ios_base::failbit); \
+ ss >> manip; \
+ TEST_THROWS(ss >> v,std::ios_base::failure); \
+ } \
+}while(0)
+
+#define TEST_PAR(manip,type,actual,expected) \
+do{ \
+ type v; \
+ {std::basic_istringstream<CharType> ss; \
+ ss.imbue(loc); \
+ ss.str(to_correct_string<CharType>(actual,loc)); \
+ ss >> manip >> v >> std::ws; \
+ TESTEQ(v,expected); \
+ TEST(ss.eof()); }\
+ {std::basic_istringstream<CharType> ss; \
+ ss.imbue(loc); \
+ ss.str(to_correct_string<CharType>(std::string(actual)+"@",loc)); \
+ CharType tmp_c; \
+ ss >> manip >> v >> std::skipws >> tmp_c; \
+ TESTEQ(v,expected); \
+ TEST(tmp_c=='@'); } \
+}while(0)
+
+#define TEST_FP1(manip,value_in,str,type,value_out) \
+do { \
+ TEST_FMT(manip,value_in,str); \
+ TEST_PAR(manip,type,str,value_out); \
+}while(0)
+
+#define TEST_FP2(m1,m2,value_in,str,type,value_out) \
+do { \
+ TEST_FMT(m1<<m2,value_in,str); \
+ TEST_PAR(m1>>m2,type,str,value_out); \
+}while(0)
+
+#define TEST_FP3(m1,m2,m3,value_in,str,type,value_out) \
+do { \
+ TEST_FMT(m1<<m2<<m3,value_in,str); \
+ TEST_PAR(m1>>m2>>m3,type,str,value_out); \
+}while(0)
+
+#define TEST_FP4(m1,m2,m3,m4,value_in,str,type,value_out) \
+do { \
+ TEST_FMT(m1<<m2<<m3<<m4,value_in,str); \
+ TEST_PAR(m1>>m2>>m3>>m4,type,str,value_out); \
+}while(0)
+
+
+#define FORMAT(f,v,exp) \
+ do{\
+ std::basic_ostringstream<CharType> ss; \
+ ss.imbue(loc); \
+ std::basic_string<CharType> fmt = to_correct_string<CharType>(f,loc); \
+ ss << boost::locale::basic_format<CharType>(fmt) % v; \
+ TESTEQ(ss.str(),to_correct_string<CharType>(exp,loc)); \
+ ss.str(to_correct_string<CharType>("",loc)); \
+ ss << boost::locale::basic_format<CharType>(boost::locale::translate(fmt.c_str())) % v; \
+ /*ss << boost::locale::basic_format<CharType>(fmt) % v; */ \
+ TESTEQ(ss.str(),to_correct_string<CharType>(exp,loc)); \
+ TESTEQ( (boost::locale::basic_format<CharType>(fmt) % v).str(loc),to_correct_string<CharType>(exp,loc)); \
+ } while(0)
+
+
+#define TEST_MIN_MAX_FMT(type,minval,maxval) \
+ do { \
+ TEST_FMT(as::number,std::numeric_limits<type>::min(),minval); \
+ TEST_FMT(as::number,std::numeric_limits<type>::max(),maxval); \
+ }while(0)
+
+#define TEST_MIN_MAX_PAR(type,minval,maxval) \
+ do {\
+ TEST_PAR(as::number,type,minval,std::numeric_limits<type>::min()); \
+ TEST_PAR(as::number,type,maxval,std::numeric_limits<type>::max()); \
+ }while(0)
+
+#define TEST_MIN_MAX(type,minval,maxval) \
+ do { \
+ TEST_MIN_MAX_FMT(type,minval,maxval); \
+ TEST_MIN_MAX_PAR(type,minval,maxval); \
+ }while(0)
+
+
+#define BOOST_ICU_VER (U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM)
+#define BOOST_ICU_EXACT_VER (U_ICU_VERSION_MAJOR_NUM*10000 + U_ICU_VERSION_MINOR_NUM * 100 + U_ICU_VERSION_PATCHLEVEL_NUM)
+
+bool short_parsing_fails()
+{
+ static bool fails = false;
+ static bool get_result = false;
+ if(get_result)
+ return fails;
+ std::stringstream ss("65000");
+ ss.imbue(std::locale::classic());
+ short v=0;
+ ss >> v;
+ fails = ss.fail();
+ get_result = true;
+ return fails;
+}
+
+template<typename CharType>
+void test_manip(std::string e_charset="UTF-8")
+{
+ boost::locale::generator g;
+ std::locale loc=g("en_US."+e_charset);
+
+ TEST_FP1(as::posix,1200.1,"1200.1",double,1200.1);
+ TEST_FP1(as::number,1200.1,"1,200.1",double,1200.1);
+ TEST_FMT(as::number<<std::setfill(CharType('_'))<<std::setw(6),1534,"_1,534");
+ TEST_FMT(as::number<<std::left<<std::setfill(CharType('_'))<<std::setw(6),1534,"1,534_");
+
+ // Ranges
+ if(sizeof(short) == 2) {
+ TEST_MIN_MAX(short,"-32,768","32,767");
+ TEST_MIN_MAX(unsigned short,"0","65,535");
+ TEST_NOPAR(as::number,"-1",unsigned short);
+ if(short_parsing_fails()) {
+ TEST_NOPAR(as::number,"65,535",short);
+ }
+ }
+ if(sizeof(int)==4) {
+ TEST_MIN_MAX(int,"-2,147,483,648","2,147,483,647");
+ TEST_MIN_MAX(unsigned int,"0","4,294,967,295");
+ TEST_NOPAR(as::number,"-1",unsigned int);
+ TEST_NOPAR(as::number,"4,294,967,295",int);
+ }
+ if(sizeof(long)==4) {
+ TEST_MIN_MAX(long,"-2,147,483,648","2,147,483,647");
+ TEST_MIN_MAX(unsigned long,"0","4,294,967,295");
+ TEST_NOPAR(as::number,"-1",unsigned long);
+ TEST_NOPAR(as::number,"4,294,967,295",long);
+ }
+ if(sizeof(long)==8) {
+ TEST_MIN_MAX(long,"-9,223,372,036,854,775,808","9,223,372,036,854,775,807");
+ TEST_MIN_MAX_FMT(unsigned long,"0","18446744073709551615"); // Unsupported range by icu - ensure fallback
+ TEST_NOPAR(as::number,"-1",unsigned long);
+ }
+ #ifndef BOOST_NO_LONG_LONG
+ if(sizeof(long long)==8) {
+ TEST_MIN_MAX(long long,"-9,223,372,036,854,775,808","9,223,372,036,854,775,807");
+ // we can't really parse this as ICU does not support this range, only format
+ TEST_MIN_MAX_FMT(unsigned long long,"0","18446744073709551615"); // Unsupported range by icu - ensure fallback
+ TEST_FMT(as::number,9223372036854775807ULL,"9,223,372,036,854,775,807");
+ TEST_FMT(as::number,9223372036854775808ULL,"9223372036854775808"); // Unsupported range by icu - ensure fallback
+ TEST_NOPAR(as::number,"-1",unsigned long long);
+ }
+ #endif
+
+
+
+ TEST_FP3(as::number,std::left,std::setw(3),15,"15 ",int,15);
+ TEST_FP3(as::number,std::right,std::setw(3),15," 15",int,15);
+ TEST_FP3(as::number,std::setprecision(3),std::fixed,13.1,"13.100",double,13.1);
+ #if BOOST_ICU_VER < 5601
+ // bug #13276
+ TEST_FP3(as::number,std::setprecision(3),std::scientific,13.1,"1.310E1",double,13.1);
+ #endif
+
+ TEST_NOPAR(as::number,"",int);
+ TEST_NOPAR(as::number,"--3",int);
+ TEST_NOPAR(as::number,"y",int);
+
+ TEST_FP1(as::percent,0.1,"10%",double,0.1);
+ TEST_FP3(as::percent,std::fixed,std::setprecision(1),0.10,"10.0%",double,0.1);
+
+ TEST_NOPAR(as::percent,"1",double);
+
+ TEST_FP1(as::currency,1345,"$1,345.00",int,1345);
+ TEST_FP1(as::currency,1345.34,"$1,345.34",double,1345.34);
+
+ TEST_NOPAR(as::currency,"$",double);
+
+
+ #if BOOST_ICU_VER >= 402
+ TEST_FP2(as::currency,as::currency_national,1345,"$1,345.00",int,1345);
+ TEST_FP2(as::currency,as::currency_national,1345.34,"$1,345.34",double,1345.34);
+ TEST_FP2(as::currency,as::currency_iso,1345,"USD1,345.00",int,1345);
+ TEST_FP2(as::currency,as::currency_iso,1345.34,"USD1,345.34",double,1345.34);
+ #endif
+ TEST_FP1(as::spellout,10,"ten",int,10);
+ #if 402 <= BOOST_ICU_VER && BOOST_ICU_VER < 408
+ if(e_charset=="UTF-8") {
+ TEST_FMT(as::ordinal,1,"1\xcb\xa2\xe1\xb5\x97"); // 1st with st as ligatures
+ }
+ #else
+ TEST_FMT(as::ordinal,1,"1st");
+ #endif
+
+ time_t a_date = 3600*24*(31+4); // Feb 5th
+ time_t a_time = 3600*15+60*33; // 15:33:05
+ time_t a_timesec = 13;
+ time_t a_datetime = a_date + a_time + a_timesec;
+
+ TEST_FP2(as::date, as::gmt,a_datetime,"Feb 5, 1970",time_t,a_date);
+ TEST_FP3(as::date,as::date_short ,as::gmt,a_datetime,"2/5/70",time_t,a_date);
+ TEST_FP3(as::date,as::date_medium,as::gmt,a_datetime,"Feb 5, 1970",time_t,a_date);
+ TEST_FP3(as::date,as::date_long ,as::gmt,a_datetime,"February 5, 1970",time_t,a_date);
+ TEST_FP3(as::date,as::date_full ,as::gmt,a_datetime,"Thursday, February 5, 1970",time_t,a_date);
+
+ TEST_NOPAR(as::date>>as::date_short,"aa/bb/cc",double);
+
+#if BOOST_ICU_VER >= 5901
+#define GMT_FULL "Greenwich Mean Time"
+#else
+#define GMT_FULL "GMT"
+#endif
+
+ TEST_FP2(as::time, as::gmt,a_datetime,"3:33:13 PM",time_t,a_time+a_timesec);
+ TEST_FP3(as::time,as::time_short ,as::gmt,a_datetime,"3:33 PM",time_t,a_time);
+ TEST_FP3(as::time,as::time_medium,as::gmt,a_datetime,"3:33:13 PM",time_t,a_time+a_timesec);
+ #if BOOST_ICU_VER >= 408
+ TEST_FP3(as::time,as::time_long ,as::gmt,a_datetime,"3:33:13 PM GMT",time_t,a_time+a_timesec);
+ #if BOOST_ICU_EXACT_VER != 40800
+ // know bug #8675
+ TEST_FP3(as::time,as::time_full ,as::gmt,a_datetime,"3:33:13 PM " GMT_FULL,time_t,a_time+a_timesec);
+ #endif
+ #else
+ TEST_FP3(as::time,as::time_long ,as::gmt,a_datetime,"3:33:13 PM GMT+00:00",time_t,a_time+a_timesec);
+ TEST_FP3(as::time,as::time_full ,as::gmt,a_datetime,"3:33:13 PM GMT+00:00",time_t,a_time+a_timesec);
+ #endif
+
+ TEST_NOPAR(as::time,"AM",double);
+
+ TEST_FP2(as::time, as::time_zone("GMT+01:00"),a_datetime,"4:33:13 PM",time_t,a_time+a_timesec);
+ TEST_FP3(as::time,as::time_short ,as::time_zone("GMT+01:00"),a_datetime,"4:33 PM",time_t,a_time);
+ TEST_FP3(as::time,as::time_medium,as::time_zone("GMT+01:00"),a_datetime,"4:33:13 PM",time_t,a_time+a_timesec);
+
+#if U_ICU_VERSION_MAJOR_NUM >= 52
+#define GMT_P100 "GMT+1"
+#else
+#define GMT_P100 "GMT+01:00"
+#endif
+
+
+#if U_ICU_VERSION_MAJOR_NUM >= 50
+#define PERIOD ","
+#define ICUAT " at"
+#else
+#define PERIOD ""
+#define ICUAT ""
+#endif
+
+ TEST_FP3(as::time,as::time_long ,as::time_zone("GMT+01:00"),a_datetime,"4:33:13 PM " GMT_P100,time_t,a_time+a_timesec);
+ #if BOOST_ICU_VER == 308 && defined(__CYGWIN__)
+ // Known faliture ICU issue
+ #else
+ TEST_FP3(as::time,as::time_full ,as::time_zone("GMT+01:00"),a_datetime,"4:33:13 PM GMT+01:00",time_t,a_time+a_timesec);
+ #endif
+
+ TEST_FP2(as::datetime, as::gmt,a_datetime,"Feb 5, 1970" PERIOD " 3:33:13 PM",time_t,a_datetime);
+ TEST_FP4(as::datetime,as::date_short ,as::time_short ,as::gmt,a_datetime,"2/5/70" PERIOD " 3:33 PM",time_t,a_date+a_time);
+ TEST_FP4(as::datetime,as::date_medium,as::time_medium,as::gmt,a_datetime,"Feb 5, 1970" PERIOD " 3:33:13 PM",time_t,a_datetime);
+ #if BOOST_ICU_VER >= 408
+ TEST_FP4(as::datetime,as::date_long ,as::time_long ,as::gmt,a_datetime,"February 5, 1970" ICUAT " 3:33:13 PM GMT",time_t,a_datetime);
+ #if BOOST_ICU_EXACT_VER != 40800
+ // know bug #8675
+ TEST_FP4(as::datetime,as::date_full ,as::time_full ,as::gmt,a_datetime,"Thursday, February 5, 1970" ICUAT " 3:33:13 PM " GMT_FULL,time_t,a_datetime);
+ #endif
+ #else
+ TEST_FP4(as::datetime,as::date_long ,as::time_long ,as::gmt,a_datetime,"February 5, 1970" PERIOD " 3:33:13 PM GMT+00:00",time_t,a_datetime);
+ TEST_FP4(as::datetime,as::date_full ,as::time_full ,as::gmt,a_datetime,"Thursday, February 5, 1970" PERIOD " 3:33:13 PM GMT+00:00",time_t,a_datetime);
+ #endif
+
+ time_t now=time(0);
+ time_t lnow = now + 3600 * 4;
+ char local_time_str[256];
+ std::string format="%H:%M:%S";
+ std::basic_string<CharType> format_string(format.begin(),format.end());
+ strftime(local_time_str,sizeof(local_time_str),format.c_str(),gmtime(&lnow));
+ TEST_FMT(as::ftime(format_string),now,local_time_str);
+ TEST_FMT(as::ftime(format_string)<<as::gmt<<as::local_time,now,local_time_str);
+
+ std::string marks =
+ "aAbB"
+ "cdeh"
+ "HIjm"
+ "Mnpr"
+ "RStT"
+ "xXyY"
+ "Z%";
+
+ std::string result[]= {
+ "Thu","Thursday","Feb","February", // aAbB
+ #if BOOST_ICU_VER >= 408
+ "Thursday, February 5, 1970" ICUAT " 3:33:13 PM " GMT_FULL, // c
+ #else
+ "Thursday, February 5, 1970 3:33:13 PM GMT+00:00", // c
+ #endif
+ "05","5","Feb", // deh
+ "15","03","36","02", // HIjm
+ "33","\n","PM", "03:33:13 PM",// Mnpr
+ "15:33","13","\t","15:33:13", // RStT
+ "Feb 5, 1970","3:33:13 PM","70","1970", // xXyY
+ #if BOOST_ICU_VER >= 408
+ GMT_FULL // Z
+ #else
+ "GMT+00:00" // Z
+ #endif
+ ,"%" }; // %
+
+ for(unsigned i=0;i<marks.size();i++) {
+ format_string.clear();
+ format_string+=static_cast<CharType>('%');
+ format_string+=static_cast<CharType>(marks[i]);
+ TEST_FMT(as::ftime(format_string)<<as::gmt,a_datetime,result[i]);
+ }
+
+ std::string sample_f[]={
+ "Now is %A, %H o'clo''ck ' or not ' ",
+ "'test %H'",
+ "%H'",
+ "'%H'"
+ };
+ std::string expected_f[] = {
+ "Now is Thursday, 15 o'clo''ck ' or not ' ",
+ "'test 15'",
+ "15'",
+ "'15'"
+ };
+
+ for(unsigned i=0;i<sizeof(sample_f)/sizeof(sample_f[0]);i++) {
+ format_string.assign(sample_f[i].begin(),sample_f[i].end());
+ TEST_FMT(as::ftime(format_string)<<as::gmt,a_datetime,expected_f[i]);
+ }
+
+}
+
+template<typename CharType>
+void test_format(std::string charset="UTF-8")
+{
+ boost::locale::generator g;
+ std::locale loc=g("en_US."+charset);
+
+ FORMAT("{3} {1} {2}", 1 % 2 % 3,"3 1 2");
+ FORMAT("{1} {2}", "hello" % 2,"hello 2");
+ FORMAT("{1}",1200.1,"1200.1");
+ FORMAT("Test {1,num}",1200.1,"Test 1,200.1");
+ FORMAT("{{}} {1,number}",1200.1,"{} 1,200.1");
+ #if BOOST_ICU_VER < 5601
+ // bug #13276
+ FORMAT("{1,num=sci,p=3}",13.1,"1.310E1");
+ FORMAT("{1,num=scientific,p=3}",13.1,"1.310E1");
+ #endif
+ FORMAT("{1,num=fix,p=3}",13.1,"13.100");
+ FORMAT("{1,num=fixed,p=3}",13.1,"13.100");
+ FORMAT("{1,<,w=3,num}",-1,"-1 ");
+ FORMAT("{1,>,w=3,num}",1," 1");
+ FORMAT("{per,1}",0.1,"10%");
+ FORMAT("{percent,1}",0.1,"10%");
+ FORMAT("{1,cur}",1234,"$1,234.00");
+ FORMAT("{1,currency}",1234,"$1,234.00");
+ if(charset=="UTF-8") {
+ if(U_ICU_VERSION_MAJOR_NUM >=4)
+ FORMAT("{1,cur,locale=de_DE}",10,"10,00\xC2\xA0€");
+ else
+ FORMAT("{1,cur,locale=de_DE}",10,"10,00 €");
+ }
+ #if BOOST_ICU_VER >= 402
+ FORMAT("{1,cur=nat}",1234,"$1,234.00");
+ FORMAT("{1,cur=national}",1234,"$1,234.00");
+ FORMAT("{1,cur=iso}",1234,"USD1,234.00");
+ #endif
+ FORMAT("{1,spell}",10,"ten");
+ FORMAT("{1,spellout}",10,"ten");
+ #if 402 <= BOOST_ICU_VER && BOOST_ICU_VER < 408
+ if(charset=="UTF-8") {
+ FORMAT("{1,ord}",1,"1\xcb\xa2\xe1\xb5\x97");
+ FORMAT("{1,ordinal}",1,"1\xcb\xa2\xe1\xb5\x97");
+ }
+ #else
+ FORMAT("{1,ord}",1,"1st");
+ FORMAT("{1,ordinal}",1,"1st");
+ #endif
+
+ time_t now=time(0);
+ time_t lnow = now + 3600 * 4;
+ char local_time_str[256];
+ std::string format="'%H:%M:%S'";
+ std::basic_string<CharType> format_string(format.begin(),format.end());
+ strftime(local_time_str,sizeof(local_time_str),format.c_str(),gmtime(&lnow));
+
+ FORMAT("{1,ftime='''%H:%M:%S'''}",now,local_time_str);
+ FORMAT("{1,local,ftime='''%H:%M:%S'''}",now,local_time_str);
+ FORMAT("{1,ftime='''%H:%M:%S'''}",now,local_time_str);
+
+ time_t a_date = 3600*24*(31+4); // Feb 5th
+ time_t a_time = 3600*15+60*33; // 15:33:05
+ time_t a_timesec = 13;
+ time_t a_datetime = a_date + a_time + a_timesec;
+ FORMAT("{1,date,gmt};{1,time,gmt};{1,datetime,gmt};{1,dt,gmt}",a_datetime,
+ "Feb 5, 1970;3:33:13 PM;Feb 5, 1970" PERIOD " 3:33:13 PM;Feb 5, 1970" PERIOD " 3:33:13 PM");
+ #if BOOST_ICU_VER >= 408
+ FORMAT("{1,time=short,gmt};{1,time=medium,gmt};{1,time=long,gmt};{1,date=full,gmt}",a_datetime,
+ "3:33 PM;3:33:13 PM;3:33:13 PM GMT;Thursday, February 5, 1970");
+ FORMAT("{1,time=s,gmt};{1,time=m,gmt};{1,time=l,gmt};{1,date=f,gmt}",a_datetime,
+ "3:33 PM;3:33:13 PM;3:33:13 PM GMT;Thursday, February 5, 1970");
+ #else
+ FORMAT("{1,time=short,gmt};{1,time=medium,gmt};{1,time=long,gmt};{1,date=full,gmt}",a_datetime,
+ "3:33 PM;3:33:13 PM;3:33:13 PM GMT+00:00;Thursday, February 5, 1970");
+ FORMAT("{1,time=s,gmt};{1,time=m,gmt};{1,time=l,gmt};{1,date=f,gmt}",a_datetime,
+ "3:33 PM;3:33:13 PM;3:33:13 PM GMT+00:00;Thursday, February 5, 1970");
+ #endif
+ FORMAT("{1,time=s,tz=GMT+01:00}",a_datetime,"4:33 PM");
+ FORMAT("{1,time=s,timezone=GMT+01:00}",a_datetime,"4:33 PM");
+
+ FORMAT("{1,gmt,ftime='%H'''}",a_datetime,"15'");
+ FORMAT("{1,gmt,ftime='''%H'}",a_datetime,"'15");
+ FORMAT("{1,gmt,ftime='%H o''clock'}",a_datetime,"15 o'clock");
+
+ // Test not a year of the week
+ a_datetime=1388491200; // 2013-12-31 12:00 - check we don't use week of year
+
+ FORMAT("{1,gmt,ftime='%Y'}",a_datetime,"2013");
+ FORMAT("{1,gmt,ftime='%y'}",a_datetime,"13");
+ FORMAT("{1,gmt,ftime='%D'}",a_datetime,"12/31/13");
+}
+
+
+int main()
+{
+ try {
+ boost::locale::time_zone::global("GMT+4:00");
+ std::cout << "Testing char, UTF-8" << std::endl;
+ test_manip<char>();
+ test_format<char>();
+ std::cout << "Testing char, ISO8859-1" << std::endl;
+ test_manip<char>("ISO8859-1");
+ test_format<char>("ISO8859-1");
+
+ std::cout << "Testing wchar_t" << std::endl;
+ test_manip<wchar_t>();
+ test_format<wchar_t>();
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::cout << "Testing char16_t" << std::endl;
+ test_manip<char16_t>();
+ test_format<char16_t>();
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::cout << "Testing char32_t" << std::endl;
+ test_manip<char32_t>();
+ test_format<char32_t>();
+ #endif
+
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // NOICU
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_generator.cpp b/src/boost/libs/locale/test/test_generator.cpp
new file mode 100644
index 000000000..dde161005
--- /dev/null
+++ b/src/boost/libs/locale/test/test_generator.cpp
@@ -0,0 +1,100 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/locale/generator.hpp>
+#include <boost/locale/info.hpp>
+#include <boost/locale/message.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+
+
+bool has_message(std::locale const &l)
+{
+ return std::has_facet<boost::locale::message_format<char> >(l);
+}
+
+struct test_facet : public std::locale::facet {
+ test_facet() : std::locale::facet(0) {}
+ static std::locale::id id;
+};
+
+std::locale::id test_facet::id;
+
+
+int main()
+{
+ try {
+ boost::locale::generator g;
+ std::locale l=g("en_US.UTF-8");
+ TEST(has_message(l));
+
+ g.categories(g.categories() ^ boost::locale::message_facet);
+ g.locale_cache_enabled(true);
+ g("en_US.UTF-8");
+ g.categories(g.categories() | boost::locale::message_facet);
+ l=g("en_US.UTF-8");
+ TEST(!has_message(l));
+ g.clear_cache();
+ g.locale_cache_enabled(false);
+ l=g("en_US.UTF-8");
+ TEST(has_message(l));
+ g.characters(g.characters() ^ boost::locale::char_facet);
+ l=g("en_US.UTF-8");
+ TEST(!has_message(l));
+ g.characters(g.characters() | boost::locale::char_facet);
+ l=g("en_US.UTF-8");
+ TEST(has_message(l));
+
+ l=g("en_US.ISO8859-1");
+ TEST(std::use_facet<boost::locale::info>(l).language()=="en");
+ TEST(std::use_facet<boost::locale::info>(l).country()=="US");
+ TEST(!std::use_facet<boost::locale::info>(l).utf8());
+ TEST(std::use_facet<boost::locale::info>(l).encoding()=="iso8859-1");
+
+ l=g("en_US.UTF-8");
+ TEST(std::use_facet<boost::locale::info>(l).language()=="en");
+ TEST(std::use_facet<boost::locale::info>(l).country()=="US");
+ TEST(std::use_facet<boost::locale::info>(l).utf8());
+
+ l=g("en_US.ISO8859-1");
+ TEST(std::use_facet<boost::locale::info>(l).language()=="en");
+ TEST(std::use_facet<boost::locale::info>(l).country()=="US");
+ TEST(!std::use_facet<boost::locale::info>(l).utf8());
+ TEST(std::use_facet<boost::locale::info>(l).encoding()=="iso8859-1");
+
+ l=g("en_US.ISO8859-1");
+ TEST(std::use_facet<boost::locale::info>(l).language()=="en");
+ TEST(std::use_facet<boost::locale::info>(l).country()=="US");
+ TEST(!std::use_facet<boost::locale::info>(l).utf8());
+ TEST(std::use_facet<boost::locale::info>(l).encoding()=="iso8859-1");
+
+ std::locale l_wt(std::locale::classic(),new test_facet);
+
+ TEST(std::has_facet<test_facet>(g.generate(l_wt,"en_US.UTF-8")));
+ TEST(std::has_facet<test_facet>(g.generate(l_wt,"en_US.ISO8859-1")));
+ TEST(!std::has_facet<test_facet>(g("en_US.UTF-8")));
+ TEST(!std::has_facet<test_facet>(g("en_US.ISO8859-1")));
+
+ g.locale_cache_enabled(true);
+ g.generate(l_wt,"en_US.UTF-8");
+ g.generate(l_wt,"en_US.ISO8859-1");
+ TEST(std::has_facet<test_facet>(g("en_US.UTF-8")));
+ TEST(std::has_facet<test_facet>(g("en_US.ISO8859-1")));
+ TEST(std::use_facet<boost::locale::info>(g("en_US.UTF-8")).utf8());
+ TEST(!std::use_facet<boost::locale::info>(g("en_US.ISO8859-1")).utf8());
+
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_icu_vs_os_timezone.cpp b/src/boost/libs/locale/test/test_icu_vs_os_timezone.cpp
new file mode 100644
index 000000000..fa1fd94dc
--- /dev/null
+++ b/src/boost/libs/locale/test/test_icu_vs_os_timezone.cpp
@@ -0,0 +1,65 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_LOCALE_WITH_ICU
+#include <iostream>
+int main()
+{
+ std::cout << "ICU is not build... Skipping" << std::endl;
+}
+#else
+
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+// Disable this "security crap"
+#endif
+
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/format.hpp>
+#include <boost/locale/generator.hpp>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+
+#include <time.h>
+
+int main()
+{
+ try {
+
+ time_t now=time(0);
+ boost::locale::generator gen;
+ std::locale::global(gen("en_US.UTF-8"));
+
+ for(int i=0;i<366;i++) {
+ time_t point = now + i * 24 * 3600;
+ std::stringstream ss;
+ ss << boost::locale::format("{1,ftime='%H %M %S'}") % point;
+ int icu_hour = 0,icu_min = 0,icu_sec = 0;
+ ss >> icu_hour >> icu_min >> icu_sec;
+ std::tm *tm=localtime(&point);
+ TEST(icu_hour == tm->tm_hour);
+ TEST(icu_min == tm->tm_min);
+ TEST(icu_sec == tm->tm_sec);
+
+ }
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // NO ICU
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_ios_prop.cpp b/src/boost/libs/locale/test/test_ios_prop.cpp
new file mode 100644
index 000000000..e94f7991d
--- /dev/null
+++ b/src/boost/libs/locale/test/test_ios_prop.cpp
@@ -0,0 +1,84 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include "test_locale.hpp"
+#include "../src/shared/ios_prop.hpp"
+#include <sstream>
+#include <locale>
+
+int counter=0;
+int imbued=0;
+struct propery {
+ propery(int xx=-1) : x(xx) { counter ++; }
+ propery(propery const &other) { counter++; x=other.x; }
+ propery const &operator=(propery const &other) {
+ x=other.x;
+ return *this;
+ };
+ int x;
+ void on_imbue() {imbued++; }
+ ~propery() { counter--; }
+};
+typedef boost::locale::impl::ios_prop<propery> prop_type;
+
+struct init {
+ init() { prop_type::global_init(); }
+};
+
+int main()
+{
+ try {
+ {
+ std::stringstream ss;
+ TEST(!prop_type::has(ss));
+ TEST(prop_type::get(ss).x==-1);
+ TEST(prop_type::has(ss));
+ TEST(counter==1);
+ }
+ TEST(counter==0);
+ {
+ std::stringstream ss;
+ prop_type::set(propery(1),ss);
+ TEST(counter==1);
+ TEST(prop_type::get(ss).x==1);
+ }
+ TEST(counter==0);
+ {
+ std::stringstream ss;
+ prop_type::set(propery(1),ss);
+ TEST(counter==1);
+ TEST(prop_type::get(ss).x==1);
+ }
+ TEST(counter==0);
+ {
+ std::stringstream ss,ss2;
+ prop_type::set(propery(2),ss);
+ ss2.copyfmt(ss);
+ TEST(prop_type::get(ss).x==2);
+ TEST(prop_type::has(ss2));
+ TEST(prop_type::has(ss));
+ TEST(prop_type::get(ss2).x==2);
+ prop_type::get(ss2).x=3;
+ TEST(prop_type::get(ss2).x==3);
+ TEST(prop_type::get(ss).x==2);
+ TEST(counter==2);
+ TEST(imbued==0);
+ ss2.imbue(std::locale::classic());
+ TEST(imbued==1);
+ }
+ TEST(counter==0);
+ }catch(std::exception const &e) {
+ std::cerr << "Fail:" << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+ return 0;
+}
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_locale.hpp b/src/boost/libs/locale/test/test_locale.hpp
new file mode 100644
index 000000000..f3b182450
--- /dev/null
+++ b/src/boost/libs/locale/test/test_locale.hpp
@@ -0,0 +1,118 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_LOCALE_TEST_H
+#define BOOST_LOCALE_TEST_H
+#include <stdexcept>
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include <string>
+
+int error_counter=0;
+int test_counter=0;
+
+#ifndef BOOST_LOCALE_ERROR_LIMIT
+#define BOOST_LOCALE_ERROR_LIMIT 20
+#endif
+
+
+#define THROW_IF_TOO_BIG(X) \
+do { \
+ if((X) > BOOST_LOCALE_ERROR_LIMIT) \
+ throw std::runtime_error("Error limits reached, stopping unit test"); \
+}while(0)
+
+#define TEST(X) \
+ do { \
+ test_counter++; \
+ if(X) break; \
+ std::cerr << "Error in line:"<<__LINE__ << " "#X << std::endl; \
+ THROW_IF_TOO_BIG(error_counter++); \
+ }while(0)
+#endif
+
+#define TEST_THROWS(X,E) \
+ do { \
+ test_counter++; \
+ try { X; } catch(E const &/*e*/ ) {break;} catch(...){} \
+ std::cerr << "Error in line:"<<__LINE__ << " "#X << std::endl; \
+ THROW_IF_TOO_BIG(error_counter++); \
+ }while(0)
+
+#define FINALIZE() \
+ do { \
+ int passed=test_counter - error_counter; \
+ std::cout << std::endl; \
+ std::cout << "Passed "<<passed<<" tests" << std::endl; \
+ if(error_counter >0 ) { \
+ std::cout << "Failed "<<error_counter<<" tests"<<std::endl; \
+ } \
+ std::cout <<" "<< std::fixed << std::setprecision(1) \
+ << std::setw(5) << 100.0 * passed / test_counter << \
+ "% of tests completed sucsessefully" << std::endl; \
+ return error_counter == 0 ? EXIT_SUCCESS : EXIT_FAILURE ; \
+ }while(0)
+
+
+inline unsigned utf8_next(std::string const &s,unsigned &pos)
+{
+ unsigned c=(unsigned char)s[pos++];
+ if( (unsigned char)(c - 0xc0) >= 0x35)
+ return c;
+ unsigned l;
+ if(c < 192)
+ l = 0;
+ else if(c < 224)
+ l = 1;
+ else if(c < 240)
+ l = 2;
+ else
+ l = 3;
+
+ c&=(1<<(6-l))-1;
+
+ switch(l) {
+ case 3:
+ c = (c << 6) | (((unsigned char)s[pos++]) & 0x3F);
+ case 2:
+ c = (c << 6) | (((unsigned char)s[pos++]) & 0x3F);
+ case 1:
+ c = (c << 6) | (((unsigned char)s[pos++]) & 0x3F);
+ }
+ return c;
+}
+
+template<typename Char>
+std::basic_string<Char> to(std::string const &utf8)
+{
+ std::basic_string<Char> out;
+ unsigned i=0;
+ while(i<utf8.size()) {
+ unsigned point;
+ unsigned prev=i;
+ point = utf8_next(utf8,i);
+ if(sizeof(Char)==1 && point > 255) {
+ std::ostringstream ss;
+ ss << "Can't convert codepoint U" << std::hex << point <<"(" <<std::string(utf8.begin()+prev,utf8.begin()+i)<<") to Latin1";
+ throw std::runtime_error(ss.str());
+ }
+ else if(sizeof(Char)==2 && point >0xFFFF) { // Deal with surragates
+ point-=0x10000;
+ out+=static_cast<Char>(0xD800 | (point>>10));
+ out+=static_cast<Char>(0xDC00 | (point & 0x3FF));
+ continue;
+ }
+ out+=static_cast<Char>(point);
+ }
+ return out;
+}
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/test/test_locale_tools.hpp b/src/boost/libs/locale/test/test_locale_tools.hpp
new file mode 100644
index 000000000..daaa107c7
--- /dev/null
+++ b/src/boost/libs/locale/test/test_locale_tools.hpp
@@ -0,0 +1,126 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_LOCLAE_TEST_LOCALE_TOOLS_HPP
+#define BOOST_LOCLAE_TEST_LOCALE_TOOLS_HPP
+
+#include <boost/locale/encoding.hpp>
+
+#include <fstream>
+#include <stdlib.h>
+#include <stdio.h>
+
+template<typename Char>
+std::basic_string<Char> to_correct_string(std::string const &e,std::locale /*l*/)
+{
+ return boost::locale::conv::to_utf<Char>(e,"UTF-8");
+}
+
+
+template<>
+inline std::string to_correct_string(std::string const &e,std::locale l)
+{
+ return boost::locale::conv::from_utf(e,l);
+}
+
+bool has_std_locale(std::string const &name)
+{
+ try {
+ std::locale tmp(name.c_str());
+ return true;
+ }
+ catch(...) {
+ return false;
+ }
+}
+
+inline bool test_std_supports_SJIS_codecvt(std::string const &locale_name)
+{
+ bool res = true;
+ {
+ // Japan in Shift JIS/cp932
+ char const *japan_932 = "\x93\xfa\x96\x7b";
+ std::ofstream f("test-siftjis.txt");
+ f<<japan_932;
+ f.close();
+ }
+ try {
+ std::wfstream test;
+ test.imbue(std::locale(locale_name.c_str()));
+ test.open("test-siftjis.txt");
+ // Japan in Unicode
+ std::wstring cmp = L"\u65e5\u672c";
+ std::wstring ref;
+ test >> ref;
+ res = ref == cmp;
+ }
+ catch(std::exception const &)
+ {
+ res = false;
+ }
+ remove("test-siftjis.txt");
+ return res;
+}
+
+std::string get_std_name(std::string const &name,std::string *real_name = 0)
+{
+ if(has_std_locale(name)) {
+ if(real_name)
+ *real_name = name;
+ return name;
+ }
+
+ #ifdef BOOST_WINDOWS
+ bool utf8=name.find("UTF-8")!=std::string::npos;
+
+ if(name=="en_US.UTF-8" || name == "en_US.ISO8859-1") {
+ if(has_std_locale("English_United States.1252")) {
+ if(real_name)
+ *real_name = "English_United States.1252";
+ return utf8 ? name : "en_US.windows-1252";
+ }
+ return "";
+ }
+ else if(name=="he_IL.UTF-8" || name == "he_IL.ISO8859-8") {
+ if(has_std_locale("Hebrew_Israel.1255")) {
+ if(real_name)
+ *real_name = "Hebrew_Israel.1255";
+ return utf8 ? name : "he_IL.windows-1255";
+ return name;
+ }
+ }
+ else if(name=="ru_RU.UTF-8") {
+ if(has_std_locale("Russian_Russia.1251")) {
+ if(real_name)
+ *real_name = "Russian_Russia.1251";
+ return name;
+ }
+ }
+ else if(name == "tr_TR.UTF-8") {
+ if(has_std_locale("Turkish_Turkey.1254")) {
+ if(real_name)
+ *real_name = "Turkish_Turkey.1254";
+ return name;
+ }
+ }
+ if(name == "ja_JP.SJIS") {
+ if(has_std_locale("Japanese_Japan.932")) {
+ if(real_name)
+ *real_name = "Japanese_Japan.932";
+ return name;
+ }
+ return "";
+ }
+ #endif
+ return "";
+}
+
+
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/libs/locale/test/test_message.cpp b/src/boost/libs/locale/test/test_message.cpp
new file mode 100644
index 000000000..2c0d365f3
--- /dev/null
+++ b/src/boost/libs/locale/test/test_message.cpp
@@ -0,0 +1,535 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/locale/generator.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/message.hpp>
+#include <boost/locale/gnu_gettext.hpp>
+#include <boost/locale/encoding.hpp>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <fstream>
+
+namespace bl = boost::locale;
+
+std::string backend;
+
+bool file_loader_is_actually_called = false;
+
+struct file_loader {
+ std::vector<char> operator()(std::string const &name,std::string const &/*encoding*/) const
+ {
+ std::vector<char> buffer;
+ std::ifstream f(name.c_str(),std::ifstream::binary);
+ if(!f)
+ return buffer;
+ f.seekg(0,std::ifstream::end);
+ size_t len = f.tellg();
+ if(len == 0)
+ return buffer;
+ f.seekg(0);
+ buffer.resize(len,'\0');
+ f.read(&buffer[0],len);
+ file_loader_is_actually_called = true;
+ return buffer;
+ }
+};
+
+
+std::string same_s(std::string s)
+{
+ return s;
+}
+
+std::wstring same_w(std::wstring s)
+{
+ return s;
+}
+
+#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+std::u16string same_u16(std::u16string s)
+{
+ return s;
+}
+#endif
+
+#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+std::u32string same_u32(std::u32string s)
+{
+ return s;
+}
+#endif
+
+template<typename Char>
+void strings_equal(std::string n_c,std::string n_s,std::string n_p,int n,std::string iexpected,std::locale const &l,std::string domain)
+{
+ typedef std::basic_string<Char> string_type;
+ string_type expected=to_correct_string<Char>(iexpected,l);
+
+ string_type c = to<Char>(n_c.c_str());
+ string_type s = to<Char>(n_s.c_str());
+ string_type p = to<Char>(n_p.c_str());
+
+ if(domain=="default") {
+ TEST(bl::translate(c,s,p,n).str(l)==expected);
+ Char const *c_c_str = c.c_str(),*s_c_str=s.c_str(), *p_c_str=p.c_str(); // workaround gcc-3.4 bug
+ TEST(bl::translate(c_c_str,s_c_str,p_c_str,n).str(l)==expected);
+ std::locale tmp_locale=std::locale();
+ std::locale::global(l);
+ string_type tmp=bl::translate(c,s,p,n);
+ TEST(tmp==expected);
+ tmp=bl::translate(c,s,p,n).str();
+ TEST(tmp==expected);
+ std::locale::global(tmp_locale);
+
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::translate(c,s,p,n);
+ TEST(ss.str()==expected);
+ }
+ TEST( bl::translate(c,s,p,n).str(l,domain)==expected );
+ std::locale tmp_locale=std::locale();
+ std::locale::global(l);
+ TEST(bl::translate(c,s,p,n).str(domain)==expected);
+ std::locale::global(tmp_locale);
+ {
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::as::domain(domain) << bl::translate(c,s,p,n);
+ TEST(ss.str()==expected);
+ }
+ {
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::as::domain(domain) << bl::translate(c.c_str(),s.c_str(),p.c_str(),n);
+ TEST(ss.str()==expected);
+ }
+}
+
+
+
+
+template<typename Char>
+void strings_equal(std::string n_s,std::string n_p,int n,std::string iexpected,std::locale const &l,std::string domain)
+{
+ typedef std::basic_string<Char> string_type;
+ string_type expected=to_correct_string<Char>(iexpected,l);
+ string_type s = to<Char>(n_s.c_str());
+ string_type p = to<Char>(n_p.c_str());
+ if(domain=="default") {
+ TEST(bl::translate(s,p,n).str(l)==expected);
+ Char const *s_c_str=s.c_str(), *p_c_str=p.c_str(); // workaround gcc-3.4 bug
+ TEST(bl::translate(s_c_str,p_c_str,n).str(l)==expected);
+ std::locale tmp_locale=std::locale();
+ std::locale::global(l);
+ string_type tmp=bl::translate(s,p,n);
+ TEST(tmp==expected);
+ tmp=bl::translate(s,p,n).str();
+ TEST(tmp==expected);
+ std::locale::global(tmp_locale);
+
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::translate(s,p,n);
+ TEST(ss.str()==expected);
+ }
+ TEST(bl::translate(s,p,n).str(l,domain)==expected);
+ std::locale tmp_locale=std::locale();
+ std::locale::global(l);
+ TEST(bl::translate(s,p,n).str(domain)==expected);
+ std::locale::global(tmp_locale);
+ {
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::as::domain(domain) << bl::translate(s,p,n);
+ TEST(ss.str()==expected);
+ }
+ {
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::as::domain(domain) << bl::translate(s.c_str(),p.c_str(),n);
+ TEST(ss.str()==expected);
+ }
+}
+
+
+template<typename Char>
+void strings_equal(std::string n_c,std::string n_original,std::string iexpected,std::locale const &l,std::string domain)
+{
+ typedef std::basic_string<Char> string_type;
+ string_type expected=to_correct_string<Char>(iexpected,l);
+ string_type original = to<Char>(n_original.c_str());
+ string_type c = to<Char>(n_c.c_str());
+ if(domain=="default") {
+ TEST(bl::translate(c,original).str(l)==expected);
+ Char const *original_c_str=original.c_str(); // workaround gcc-3.4 bug
+ Char const *context_c_str = c.c_str();
+ TEST(bl::translate(context_c_str,original_c_str).str(l)==expected);
+ std::locale tmp_locale=std::locale();
+ std::locale::global(l);
+ string_type tmp=bl::translate(c,original);
+ TEST(tmp==expected);
+ tmp=bl::translate(c,original).str();
+ TEST(tmp==expected);
+ std::locale::global(tmp_locale);
+
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::translate(c,original);
+ TEST(ss.str()==expected);
+ }
+ TEST(bl::translate(c,original).str(l,domain)==expected);
+ std::locale tmp_locale=std::locale();
+ std::locale::global(l);
+ TEST(bl::translate(c,original).str(domain)==expected);
+ std::locale::global(tmp_locale);
+ {
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::as::domain(domain) << bl::translate(c,original);
+ TEST(ss.str()==expected);
+ }
+ {
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::as::domain(domain) << bl::translate(c.c_str(),original.c_str());
+ TEST(ss.str()==expected);
+ }
+}
+
+
+
+
+template<typename Char>
+void strings_equal(std::string n_original,std::string iexpected,std::locale const &l,std::string domain)
+{
+ typedef std::basic_string<Char> string_type;
+ string_type expected=to_correct_string<Char>(iexpected,l);
+ string_type original = to<Char>(n_original.c_str());
+ if(domain=="default") {
+ TEST(bl::translate(original).str(l)==expected);
+ Char const *original_c_str=original.c_str(); // workaround gcc-3.4 bug
+ TEST(bl::translate(original_c_str).str(l)==expected);
+ std::locale tmp_locale=std::locale();
+ std::locale::global(l);
+ string_type tmp=bl::translate(original);
+ TEST(tmp==expected);
+ tmp=bl::translate(original).str();
+ TEST(tmp==expected);
+ std::locale::global(tmp_locale);
+
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::translate(original);
+ TEST(ss.str()==expected);
+ }
+ TEST(bl::translate(original).str(l,domain)==expected);
+ std::locale tmp_locale=std::locale();
+ std::locale::global(l);
+ TEST(bl::translate(original).str(domain)==expected);
+ std::locale::global(tmp_locale);
+ {
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::as::domain(domain) << bl::translate(original);
+ TEST(ss.str()==expected);
+ }
+ {
+ std::basic_ostringstream<Char> ss;
+ ss.imbue(l);
+ ss << bl::as::domain(domain) << bl::translate(original.c_str());
+ TEST(ss.str()==expected);
+ }
+}
+
+void test_cntranslate(std::string c,std::string s,std::string p,int n,std::string expected,std::locale const &l,std::string domain)
+{
+ strings_equal<char>(c,s,p,n,expected,l,domain);
+ strings_equal<wchar_t>(c,s,p,n,expected,l,domain);
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ if(backend=="icu" || backend=="std")
+ strings_equal<char16_t>(c,s,p,n,expected,l,domain);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ if(backend=="icu" || backend=="std")
+ strings_equal<char32_t>(c,s,p,n,expected,l,domain);
+ #endif
+}
+
+
+void test_ntranslate(std::string s,std::string p,int n,std::string expected,std::locale const &l,std::string domain)
+{
+ strings_equal<char>(s,p,n,expected,l,domain);
+ strings_equal<wchar_t>(s,p,n,expected,l,domain);
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ if(backend=="icu" || backend=="std")
+ strings_equal<char16_t>(s,p,n,expected,l,domain);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ if(backend=="icu" || backend=="std")
+ strings_equal<char32_t>(s,p,n,expected,l,domain);
+ #endif
+}
+
+void test_ctranslate(std::string c,std::string original,std::string expected,std::locale const &l,std::string domain)
+{
+ strings_equal<char>(c,original,expected,l,domain);
+ strings_equal<wchar_t>(c,original,expected,l,domain);
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ if(backend=="icu" || backend=="std")
+ strings_equal<char16_t>(c,original,expected,l,domain);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ if(backend=="icu" || backend=="std")
+ strings_equal<char32_t>(c,original,expected,l,domain);
+ #endif
+}
+
+
+
+void test_translate(std::string original,std::string expected,std::locale const &l,std::string domain)
+{
+ strings_equal<char>(original,expected,l,domain);
+ strings_equal<wchar_t>(original,expected,l,domain);
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ if(backend=="icu" || backend=="std")
+ strings_equal<char16_t>(original,expected,l,domain);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ if(backend=="icu" || backend=="std")
+ strings_equal<char32_t>(original,expected,l,domain);
+ #endif
+}
+
+bool iso_8859_8_not_supported = false;
+
+
+int main(int argc,char **argv)
+{
+ try {
+ std::string def[] = {
+ #ifdef BOOST_LOCALE_WITH_ICU
+ "icu" ,
+ #endif
+ #ifndef BOOST_LOCALE_NO_STD_BACKEND
+ "std" ,
+ #endif
+ #ifndef BOOST_LOCALE_NO_POSIX_BACKEND
+ "posix",
+ #endif
+ #ifndef BOOST_LOCALE_NO_WINAPI_BACKEND
+ "winapi",
+ #endif
+ };
+ for(int type = 0 ; type < int(sizeof(def)/sizeof(def[0])) ; type ++ ) {
+ boost::locale::localization_backend_manager tmp_backend = boost::locale::localization_backend_manager::global();
+ tmp_backend.select(def[type]);
+ boost::locale::localization_backend_manager::global(tmp_backend);
+
+ backend = def[type];
+
+ std::cout << "Testing for backend --------- " << def[type] << std::endl;
+
+ boost::locale::generator g;
+ g.add_messages_domain("simple");
+ g.add_messages_domain("full");
+ g.add_messages_domain("fall");
+ if(argc==2)
+ g.add_messages_path(argv[1]);
+ else
+ g.add_messages_path("./");
+ g.set_default_messages_domain("default");
+
+
+ std::string locales[] = { "he_IL.UTF-8", "he_IL.ISO8859-8" };
+
+ for(unsigned i=0;i<sizeof(locales)/sizeof(locales[0]);i++){
+ std::locale l;
+
+ if(i==1) {
+ try {
+ l = g(locales[i]);
+ }
+ catch(boost::locale::conv::invalid_charset_error const &e) {
+ std::cout << "Looks like ISO-8859-8 is not supported! skipping" << std::endl;
+ iso_8859_8_not_supported = true;
+ continue;
+ }
+ }
+ else {
+ l = g(locales[i]);
+ }
+
+ std::cout << " Testing "<<locales[i]<<std::endl;
+ std::cout << " single forms" << std::endl;
+
+ test_translate("hello","שלום",l,"default");
+ test_translate("hello","היי",l,"simple");
+ test_translate("hello","hello",l,"undefined");
+ test_translate("untranslated","untranslated",l,"default");
+ // Check removal of old "context" information
+ test_translate("#untranslated","#untranslated",l,"default");
+ test_translate("##untranslated","##untranslated",l,"default");
+ test_ctranslate("context","hello","שלום בהקשר אחר",l,"default");
+ test_translate("#hello","#שלום",l,"default");
+
+ std::cout << " plural forms" << std::endl;
+
+ {
+ test_ntranslate("x day","x days",0,"x ימים",l,"default");
+ test_ntranslate("x day","x days",1,"יום x",l,"default");
+ test_ntranslate("x day","x days",2,"יומיים",l,"default");
+ test_ntranslate("x day","x days",3,"x ימים",l,"default");
+ test_ntranslate("x day","x days",20,"x יום",l,"default");
+
+ test_ntranslate("x day","x days",0,"x days",l,"undefined");
+ test_ntranslate("x day","x days",1,"x day",l,"undefined");
+ test_ntranslate("x day","x days",2,"x days",l,"undefined");
+ test_ntranslate("x day","x days",20,"x days",l,"undefined");
+ }
+ std::cout << " plural forms with context" << std::endl;
+ {
+ std::string inp = "context";
+ std::string out = "בהקשר ";
+
+ test_cntranslate(inp,"x day","x days",0,out+"x ימים",l,"default");
+ test_cntranslate(inp,"x day","x days",1,out+"יום x",l,"default");
+ test_cntranslate(inp,"x day","x days",2,out+"יומיים",l,"default");
+ test_cntranslate(inp,"x day","x days",3,out+"x ימים",l,"default");
+ test_cntranslate(inp,"x day","x days",20,out+"x יום",l,"default");
+
+ test_cntranslate(inp,"x day","x days",0,"x days",l,"undefined");
+ test_cntranslate(inp,"x day","x days",1,"x day",l,"undefined");
+ test_cntranslate(inp,"x day","x days",2,"x days",l,"undefined");
+ test_cntranslate(inp,"x day","x days",20,"x days",l,"undefined");
+ }
+ }
+ std::cout << " Testing fallbacks" <<std::endl;
+ test_translate("test","he_IL",g("he_IL.UTF-8"),"full");
+ test_translate("test","he",g("he_IL.UTF-8"),"fall");
+
+ std::cout << " Testing automatic conversions " << std::endl;
+ std::locale::global(g("he_IL.UTF-8"));
+
+
+ TEST(same_s(bl::translate("hello"))=="שלום");
+ TEST(same_w(bl::translate(to<wchar_t>("hello")))==to<wchar_t>("שלום"));
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ if(backend=="icu" || backend=="std")
+ TEST(same_u16(bl::translate(to<char16_t>("hello")))==to<char16_t>("שלום"));
+ #endif
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ if(backend=="icu" || backend=="std")
+ TEST(same_u32(bl::translate(to<char32_t>("hello")))==to<char32_t>("שלום"));
+ #endif
+
+ }
+
+ std::cout << "Testing custom file system support" << std::endl;
+ {
+ boost::locale::gnu_gettext::messages_info info;
+ info.language = "he";
+ info.country = "IL";
+ info.encoding="UTF-8";
+ if(argc==2)
+ info.paths.push_back(argv[1]);
+ else
+ info.paths.push_back("./");
+
+ info.domains.push_back(bl::gnu_gettext::messages_info::domain("default"));
+ info.callback = file_loader();
+
+ std::locale l(std::locale::classic(),boost::locale::gnu_gettext::create_messages_facet<char>(info));
+ TEST(file_loader_is_actually_called);
+ TEST(bl::translate("hello").str(l)=="שלום");
+ }
+ if(iso_8859_8_not_supported)
+ {
+ std::cout << "ISO 8859-8 not supported so skipping non-US-ASCII keys" << std::endl;
+ }
+ else
+ {
+ std::cout << "Testing non-US-ASCII keys" << std::endl;
+ std::cout << " UTF-8 keys" << std::endl;
+ {
+ boost::locale::generator g;
+ g.add_messages_domain("default");
+ if(argc==2)
+ g.add_messages_path(argv[1]);
+ else
+ g.add_messages_path("./");
+
+ std::locale l = g("he_IL.UTF-8");
+
+ // narrow
+ TEST(bl::gettext("בדיקה",l)=="test");
+ TEST(bl::gettext("לא קיים",l)=="לא קיים");
+
+ // wide
+ std::wstring wtest = bl::conv::to_utf<wchar_t>("בדיקה","UTF-8");
+ std::wstring wmiss = bl::conv::to_utf<wchar_t>("לא קיים","UTF-8");
+ TEST(bl::gettext(wtest.c_str(),l)==L"test");
+ TEST(bl::gettext(wmiss.c_str(),l)==wmiss);
+
+ l=g("he_IL.ISO-8859-8");
+
+ // conversion with substitution
+ TEST(bl::gettext("test-あにま-בדיקה",l)==bl::conv::from_utf("test--בדיקה","ISO-8859-8"));
+ }
+
+ std::cout << " `ANSI' keys" << std::endl;
+
+ {
+ boost::locale::generator g;
+ g.add_messages_domain("default/ISO-8859-8");
+ if(argc==2)
+ g.add_messages_path(argv[1]);
+ else
+ g.add_messages_path("./");
+
+ std::locale l = g("he_IL.UTF-8");
+
+ // narrow non-UTF-8 keys
+ // match
+ TEST(bl::gettext(bl::conv::from_utf("בדיקה","ISO-8859-8").c_str(),l)=="test");
+ // conversion
+ TEST(bl::gettext(bl::conv::from_utf("לא קיים","ISO-8859-8").c_str(),l)=="לא קיים");
+ }
+ }
+ // Test compiles
+ {
+ bl::gettext("");
+ bl::gettext(L"");
+ bl::dgettext("","");
+ bl::dgettext("",L"");
+ bl::pgettext("","");
+ bl::pgettext(L"",L"");
+ bl::dpgettext("","","");
+ bl::dpgettext("",L"",L"");
+ bl::ngettext("","",1);
+ bl::ngettext(L"",L"",1);
+ bl::dngettext("","","",1);
+ bl::dngettext("",L"",L"",1);
+ bl::npgettext("","","",1);
+ bl::npgettext(L"",L"",L"",1);
+ bl::dnpgettext("","","","",1);
+ bl::dnpgettext("",L"",L"",L"",1);
+ }
+
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_posix_collate.cpp b/src/boost/libs/locale/test/test_posix_collate.cpp
new file mode 100644
index 000000000..966302089
--- /dev/null
+++ b/src/boost/libs/locale/test/test_posix_collate.cpp
@@ -0,0 +1,120 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifdef BOOST_LOCALE_NO_POSIX_BACKEND
+#include <iostream>
+int main()
+{
+ std::cout << "POSIX Backend is not build... Skipping" << std::endl;
+}
+#else
+#include <boost/locale/config.hpp>
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/info.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include "test_posix_tools.hpp"
+#include <iostream>
+
+int get_sign(int x)
+{
+ if(x<0)
+ return -1;
+ else if(x==0)
+ return 0;
+ return 1;
+}
+
+template<typename CharType>
+void test_one(std::locale const &l,std::string ia,std::string ib,int diff)
+{
+ std::basic_string<CharType> a=to_correct_string<CharType>(ia,l);
+ std::basic_string<CharType> b=to_correct_string<CharType>(ib,l);
+ if(diff < 0) {
+ TEST(l(a,b));
+ TEST(!l(b,a));
+ }
+ else if(diff == 0) {
+ TEST(!l(a,b));
+ TEST(!l(b,a));
+ }
+ else {
+ TEST(!l(a,b));
+ TEST(l(b,a));
+ }
+
+ std::collate<CharType> const &col = std::use_facet<std::collate<CharType> >(l);
+
+ TEST(diff == col.compare(a.c_str(),a.c_str()+a.size(),b.c_str(),b.c_str()+b.size()));
+ TEST(diff == get_sign(col.transform(a.c_str(),a.c_str()+a.size()).compare(col.transform(b.c_str(),b.c_str()+b.size()))));
+ if(diff == 0) {
+ TEST(col.hash(a.c_str(),a.c_str()+a.size()) == col.hash(b.c_str(),b.c_str()+b.size()));
+ }
+}
+
+template<typename CharType>
+void test_char()
+{
+ boost::locale::generator gen;
+
+ std::cout << "- Testing at least C" << std::endl;
+
+ std::locale l = gen("en_US.UTF-8");
+
+ test_one<CharType>(l,"a","b",-1);
+ test_one<CharType>(l,"a","a",0);
+
+ std::string name;
+
+
+ #if !defined(__APPLE__) && !defined(__FreeBSD__)
+ std::string names[] = { "en_US.UTF-8", "en_US.ISO8859-1" };
+ for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
+ if(have_locale(names[i])) {
+ name = names[i];
+ std::cout << "- Testing " << name << std::endl;
+ std::locale l=gen(name);
+ test_one<CharType>(l,"a","ç",-1);
+ test_one<CharType>(l,"ç","d",-1);
+ }
+ else {
+ std::cout << "- " << names[i] << " not supported, skipping" << std::endl;
+ }
+ }
+ #else
+ std::cout << "- Collation is broken on this OS C standard library, skipping" << std::endl;
+ #endif
+}
+
+
+int main()
+{
+ try {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select("posix");
+ boost::locale::localization_backend_manager::global(mgr);
+
+ std::cout << "Testing char" << std::endl;
+ test_char<char>();
+ std::cout << "Testing wchar_t" << std::endl;
+ test_char<wchar_t>();
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+#endif // NO POSIX
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_posix_convert.cpp b/src/boost/libs/locale/test/test_posix_convert.cpp
new file mode 100644
index 000000000..76d5c6522
--- /dev/null
+++ b/src/boost/libs/locale/test/test_posix_convert.cpp
@@ -0,0 +1,122 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifdef BOOST_LOCALE_NO_POSIX_BACKEND
+#include <iostream>
+int main()
+{
+ std::cout << "POSIX Backend is not build... Skipping" << std::endl;
+}
+#else
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/info.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include "test_posix_tools.hpp"
+#include <iostream>
+
+#include <wctype.h>
+
+
+template<typename CharType>
+void test_one(std::locale const &l,std::string src,std::string tgtl,std::string tgtu)
+{
+ TEST(boost::locale::to_upper(to_correct_string<CharType>(src,l),l) == to_correct_string<CharType>(tgtu,l));
+ TEST(boost::locale::to_lower(to_correct_string<CharType>(src,l),l) == to_correct_string<CharType>(tgtl,l));
+ TEST(boost::locale::fold_case(to_correct_string<CharType>(src,l),l) == to_correct_string<CharType>(tgtl,l));
+}
+
+template<typename CharType>
+void test_char()
+{
+ boost::locale::generator gen;
+
+ std::cout << "- Testing at least C" << std::endl;
+
+ std::locale l = gen("en_US.UTF-8");
+
+ test_one<CharType>(l,"Hello World i","hello world i","HELLO WORLD I");
+
+ std::string name = "en_US.UTF-8";
+ if(have_locale(name)) {
+ std::cout << "- Testing " << name << std::endl;
+ std::locale l=gen(name);
+ test_one<CharType>(l,"Façade","façade","FAÇADE");
+ }
+ else {
+ std::cout << "- en_US.UTF-8 is not supported, skipping" << std::endl;
+ }
+
+ name = "en_US.ISO8859-1";
+ if(have_locale(name)) {
+ std::cout << "Testing " << name << std::endl;
+ std::locale l=gen(name);
+ test_one<CharType>(l,"Hello World","hello world","HELLO WORLD");
+ #if defined(__APPLE__) || defined(__FreeBSD__)
+ if(sizeof(CharType)!=1)
+ #endif
+ test_one<CharType>(l,"Façade","façade","FAÇADE");
+ }
+ else {
+ std::cout << "- en_US.ISO8859-1 is not supported, skipping" << std::endl;
+ }
+
+ name = "tr_TR.UTF-8";
+ if(have_locale(name)) {
+ std::cout << "Testing " << name << std::endl;
+ locale_t cl = newlocale(LC_ALL_MASK,name.c_str(),0);
+ try {
+ TEST(cl);
+ if(towupper_l(L'i',cl) == 0x130) {
+ test_one<CharType>(gen(name),"i","i","İ");
+ }
+ else {
+ std::cout <<" Turkish locale is not supported well" << std::endl;
+ }
+ }
+ catch(...) {
+ if(cl) freelocale(cl);
+ throw;
+ }
+ if(cl) freelocale(cl);
+
+ }
+ else
+ {
+ std::cout << "- tr_TR.UTF-8 is not supported, skipping" << std::endl;
+ }
+}
+
+
+int main()
+{
+ try {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select("posix");
+ boost::locale::localization_backend_manager::global(mgr);
+
+ std::cout << "Testing char" << std::endl;
+ test_char<char>();
+ std::cout << "Testing wchar_t" << std::endl;
+ test_char<wchar_t>();
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // POSIX
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_posix_formatting.cpp b/src/boost/libs/locale/test/test_posix_formatting.cpp
new file mode 100644
index 000000000..55e83cf5d
--- /dev/null
+++ b/src/boost/libs/locale/test/test_posix_formatting.cpp
@@ -0,0 +1,281 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifdef BOOST_LOCALE_NO_POSIX_BACKEND
+#include <iostream>
+int main()
+{
+ std::cout << "POSIX Backend is not build... Skipping" << std::endl;
+}
+#else
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/encoding.hpp>
+#include <boost/locale/info.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include "test_posix_tools.hpp"
+#include <iostream>
+
+#include <time.h>
+#include <monetary.h>
+#include <assert.h>
+#include <langinfo.h>
+
+//#define DEBUG_FMT
+
+bool equal(std::string const &s1,std::string const &s2,locale_t /*lc*/)
+{
+ return s1 == s2;
+}
+
+bool equal(std::wstring const &s1,std::string const &s2,locale_t lc)
+{
+ return s1 == boost::locale::conv::to_utf<wchar_t>(s2,nl_langinfo_l(CODESET,lc));
+}
+
+template<typename CharType>
+std::basic_string<CharType> conv_to_char(char const *p)
+{
+ std::basic_string<CharType> r;
+ while(*p)
+ r+=CharType(*p++);
+ return r;
+}
+
+
+template<typename CharType,typename RefCharType>
+void test_by_char(std::locale const &l,locale_t lreal)
+{
+ typedef std::basic_stringstream<CharType> ss_type;
+
+ using namespace boost::locale;
+
+ {
+ std::cout << "- Testing as::posix" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << 1045.45;
+ TEST(ss);
+ double n;
+ ss >> n;
+ TEST(ss);
+ TEST(n == 1045.45);
+ TEST(ss.str()==to_correct_string<CharType>("1045.45",l));
+ #ifdef DEBUG_FMT
+ std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
+ #endif
+ }
+
+ {
+ std::cout << "- Testing as::number" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << as::number;
+ ss << 1045.45;
+ TEST(ss);
+ double n;
+ ss >> n;
+ TEST(ss);
+ TEST(n == 1045.45);
+
+ if(std::use_facet<boost::locale::info>(l).country()=="US")
+ TEST(equal(ss.str(),"1,045.45",lreal));
+ }
+
+ {
+ std::cout << "- Testing as::currency national " << std::endl;
+
+ char buf[256];
+ strfmon_l(buf,256,lreal,"%n",1043.34);
+
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << as::currency;
+ ss << 1043.34;
+ TEST(ss);
+
+ TEST(equal(ss.str(),buf,lreal));
+ #ifdef DEBUG_FMT
+ std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
+ std::cout << "[" << boost::locale::conv::from_utf(buf,"UTF-8") << "]\n" ;
+ #endif
+
+ }
+
+ {
+ std::cout << "- Testing as::currency iso" << std::endl;
+ char buf[256];
+ strfmon_l(buf,256,lreal,"%i",1043.34);
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << as::currency << as::currency_iso;
+ ss << 1043.34;
+ TEST(ss);
+
+ TEST(equal(ss.str(),buf,lreal));
+ #ifdef DEBUG_FMT
+ std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
+ std::cout << "[" << boost::locale::conv::from_utf(buf,"UTF-8") << "]\n" ;
+ #endif
+ }
+
+
+ {
+ std::cout << "- Testing as::date/time" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ time_t a_date = 3600*24*(31+4); // Feb 5th
+ time_t a_time = 3600*15+60*33; // 15:33:05
+ time_t a_timesec = 13;
+ time_t a_datetime = a_date + a_time + a_timesec;
+
+ ss << as::time_zone("GMT");
+
+ ss << as::date << a_datetime << CharType('\n');
+ ss << as::time << a_datetime << CharType('\n');
+ ss << as::datetime << a_datetime << CharType('\n');
+ ss << as::time_zone("GMT+01:00");
+ ss << as::ftime(conv_to_char<CharType>("%H")) << a_datetime << CharType('\n');
+ ss << as::time_zone("GMT+00:15");
+ ss << as::ftime(conv_to_char<CharType>("%M")) << a_datetime << CharType('\n');
+
+ std::tm tm=*gmtime(&a_datetime);
+ char buf[256];
+ strftime_l(buf,sizeof(buf),"%x\n%X\n%c\n16\n48\n",&tm,lreal);
+
+ TEST(equal(ss.str(),buf,lreal));
+ #ifdef DEBUG_FMT
+ std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
+ std::cout << "[" << boost::locale::conv::from_utf(buf,"UTF-8") << "]\n" ;
+ #endif
+ }
+
+}
+
+int main()
+{
+ locale_t lreal = 0;
+ try {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select("posix");
+ boost::locale::localization_backend_manager::global(mgr);
+ boost::locale::generator gen;
+ std::string name;
+
+ {
+ std::cout << "en_US.UTF locale" << std::endl;
+ name="en_US.UTF-8";
+ if(!have_locale(name)) {
+ std::cout << "en_US.UTF-8 not supported" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name);
+ lreal=newlocale(LC_ALL_MASK,name.c_str(),0);
+ assert(lreal);
+ std::cout << "UTF-8" << std::endl;
+
+ test_by_char<char,char>(l1,lreal);
+
+ std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
+ test_by_char<wchar_t,char>(l1,lreal);
+ freelocale(lreal);
+ lreal = 0;
+ }
+ }
+ {
+ std::cout << "en_US.Latin-1 locale" << std::endl;
+ std::string name = "en_US.ISO8859-1";
+ if(!have_locale(name)) {
+ std::cout << "en_US.ISO8859-8 not supported" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name);
+ lreal=newlocale(LC_ALL_MASK,name.c_str(),0);
+ assert(lreal);
+ test_by_char<char,char>(l1,lreal);
+ std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
+ test_by_char<wchar_t,char>(l1,lreal);
+ freelocale(lreal);
+ lreal = 0;
+ }
+ }
+ {
+ std::cout << "he_IL.UTF locale" << std::endl;
+ name="he_IL.UTF-8";
+ if(!have_locale(name)) {
+ std::cout << name << " not supported" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name);
+ lreal=newlocale(LC_ALL_MASK,name.c_str(),0);
+ assert(lreal);
+ std::cout << "UTF-8" << std::endl;
+
+ test_by_char<char,char>(l1,lreal);
+
+ std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
+ test_by_char<wchar_t,char>(l1,lreal);
+ freelocale(lreal);
+ lreal = 0;
+ }
+ }
+ {
+ std::cout << "he_IL.ISO locale" << std::endl;
+ std::string name = "he_IL.ISO8859-8";
+ if(!have_locale(name)) {
+ std::cout << name <<" not supported" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name);
+ lreal=newlocale(LC_ALL_MASK,name.c_str(),0);
+ assert(lreal);
+ test_by_char<char,char>(l1,lreal);
+ std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
+ test_by_char<wchar_t,char>(l1,lreal);
+ freelocale(lreal);
+ lreal = 0;
+ }
+ }
+ {
+ std::cout << "Testing UTF-8 punct issues" << std::endl;
+ std::string name = "ru_RU.UTF-8";
+ if(!have_locale(name)) {
+ std::cout << "- No russian locale" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name);
+ std::ostringstream ss;
+ ss.imbue(l1);
+ ss << std::setprecision(10) ;
+ ss << boost::locale::as::number << 12345.45;
+ std::string v=ss.str();
+ TEST(v == "12345,45" || v == "12 345,45" || v=="12.345,45");
+ }
+ }
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ if(lreal)
+ freelocale(lreal);
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // posix
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_posix_tools.hpp b/src/boost/libs/locale/test/test_posix_tools.hpp
new file mode 100644
index 000000000..6be9c589f
--- /dev/null
+++ b/src/boost/libs/locale/test/test_posix_tools.hpp
@@ -0,0 +1,31 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_LOCLAE_TEST_LOCALE_POSIX_TOOLS_HPP
+#define BOOST_LOCLAE_TEST_LOCALE_POSIX_TOOLS_HPP
+
+#include <locale.h>
+#include <string>
+
+#if defined(__APPLE__) || defined(__FreeBSD__)
+#include <xlocale.h>
+#endif
+
+inline bool have_locale(std::string const &name)
+{
+ locale_t l=newlocale(LC_ALL_MASK,name.c_str(),0);
+ if(l) {
+ freelocale(l);
+ return true;
+ }
+ return false;
+}
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
diff --git a/src/boost/libs/locale/test/test_std_collate.cpp b/src/boost/libs/locale/test/test_std_collate.cpp
new file mode 100644
index 000000000..1f01b766a
--- /dev/null
+++ b/src/boost/libs/locale/test/test_std_collate.cpp
@@ -0,0 +1,129 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifdef BOOST_LOCALE_NO_STD_BACKEND
+#include <iostream>
+int main()
+{
+ std::cout << "STD Backend is not build... Skipping" << std::endl;
+}
+#else
+
+#include <boost/locale/config.hpp>
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/info.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <iostream>
+
+int get_sign(int x)
+{
+ if(x<0)
+ return -1;
+ else if(x==0)
+ return 0;
+ return 1;
+}
+
+template<typename CharType>
+void test_one(std::locale const &l,std::string ia,std::string ib,int diff)
+{
+ std::basic_string<CharType> a=to_correct_string<CharType>(ia,l);
+ std::basic_string<CharType> b=to_correct_string<CharType>(ib,l);
+ if(diff < 0) {
+ TEST(l(a,b));
+ TEST(!l(b,a));
+ }
+ else if(diff == 0) {
+ TEST(!l(a,b));
+ TEST(!l(b,a));
+ }
+ else {
+ TEST(!l(a,b));
+ TEST(l(b,a));
+ }
+
+ std::collate<CharType> const &col = std::use_facet<std::collate<CharType> >(l);
+
+ TEST(diff == col.compare(a.c_str(),a.c_str()+a.size(),b.c_str(),b.c_str()+b.size()));
+ TEST(diff == get_sign(col.transform(a.c_str(),a.c_str()+a.size()).compare(col.transform(b.c_str(),b.c_str()+b.size()))));
+ if(diff == 0) {
+ TEST(col.hash(a.c_str(),a.c_str()+a.size()) == col.hash(b.c_str(),b.c_str()+b.size()));
+ }
+}
+
+template<typename CharType>
+void test_char()
+{
+ boost::locale::generator gen;
+
+ std::cout << "- Testing at least C" << std::endl;
+
+ std::locale l = gen("en_US.UTF-8");
+
+ test_one<CharType>(l,"a","b",-1);
+ test_one<CharType>(l,"a","a",0);
+
+ std::string name;
+
+ #if defined(_LIBCPP_VERSION) && (defined(__APPLE__) || defined(__FreeBSD__))
+ std::cout << "- Collation is broken on this OS's standard C++ library, skipping" << std::endl;
+ #else
+ std::string names[] = { "en_US.UTF-8", "en_US.ISO8859-1" };
+ for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
+ name = get_std_name(names[i]);
+ if(!name.empty()) {
+ std::cout << "- Testing " << name << std::endl;
+ std::locale l=gen(name);
+ test_one<CharType>(l,"a","ç",-1);
+ test_one<CharType>(l,"ç","d",-1);
+ }
+ else {
+ std::cout << "- " << names[i] << " not supported, skipping" << std::endl;
+ }
+ }
+ #endif
+}
+
+
+int main()
+{
+ try {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select("std");
+ boost::locale::localization_backend_manager::global(mgr);
+
+ std::cout << "Testing char" << std::endl;
+ test_char<char>();
+ std::cout << "Testing wchar_t" << std::endl;
+ test_char<wchar_t>();
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::cout << "Testing char16_t" << std::endl;
+ test_char<char16_t>();
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::cout << "Testing char32_t" << std::endl;
+ test_char<char32_t>();
+ #endif
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // NO STD
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_std_convert.cpp b/src/boost/libs/locale/test/test_std_convert.cpp
new file mode 100644
index 000000000..6259e5547
--- /dev/null
+++ b/src/boost/libs/locale/test/test_std_convert.cpp
@@ -0,0 +1,120 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifdef BOOST_LOCALE_NO_STD_BACKEND
+#include <iostream>
+int main()
+{
+ std::cout << "STD Backend is not build... Skipping" << std::endl;
+}
+#else
+
+
+
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/info.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <iostream>
+
+template<typename CharType>
+void test_one(std::locale const &l,std::string src,std::string tgtl,std::string tgtu)
+{
+ TEST(boost::locale::to_upper(to_correct_string<CharType>(src,l),l) == to_correct_string<CharType>(tgtu,l));
+ TEST(boost::locale::to_lower(to_correct_string<CharType>(src,l),l) == to_correct_string<CharType>(tgtl,l));
+ TEST(boost::locale::fold_case(to_correct_string<CharType>(src,l),l) == to_correct_string<CharType>(tgtl,l));
+}
+
+template<typename CharType>
+void test_char()
+{
+ boost::locale::generator gen;
+
+ std::cout << "- Testing at least C" << std::endl;
+
+ std::locale l = gen("en_US.UTF-8");
+
+ test_one<CharType>(l,"Hello World i","hello world i","HELLO WORLD I");
+
+ std::string name;
+
+ name = get_std_name("en_US.UTF-8");
+ if(!name.empty()) {
+ std::cout << "- Testing " << name << std::endl;
+ std::locale l=gen(name);
+ test_one<CharType>(l,"Façade","façade","FAÇADE");
+ }
+ else {
+ std::cout << "- en_US.UTF-8 is not supported, skipping" << std::endl;
+ }
+
+ name = get_std_name("en_US.ISO8859-1");
+ if(!name.empty()) {
+ std::cout << "Testing " << name << std::endl;
+ std::locale l=gen(name);
+ test_one<CharType>(l,"Hello World","hello world","HELLO WORLD");
+ test_one<CharType>(l,"Façade","façade","FAÇADE");
+ }
+ else {
+ std::cout << "- en_US.ISO8859-1 is not supported, skipping" << std::endl;
+ }
+ std::string real_name;
+ name = get_std_name("tr_TR.UTF-8",&real_name);
+ if(!name.empty()) {
+ std::cout << "Testing " << name << std::endl;
+ if(std::use_facet<std::ctype<wchar_t> >(std::locale(real_name.c_str())).toupper(L'i')!=L'I') {
+ std::locale l=gen(name);
+ test_one<CharType>(l,"i","i","İ");
+ }
+ else {
+ std::cout << "Standard library does not support this locale's case conversion correctly" << std::endl;
+ }
+ }
+ else
+ {
+ std::cout << "- tr_TR.UTF-8 is not supported, skipping" << std::endl;
+ }
+}
+
+
+int main()
+{
+ try {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select("std");
+ boost::locale::localization_backend_manager::global(mgr);
+
+ std::cout << "Testing char" << std::endl;
+ test_char<char>();
+ std::cout << "Testing wchar_t" << std::endl;
+ test_char<wchar_t>();
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::cout << "Testing char16_t" << std::endl;
+ test_char<char16_t>();
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::cout << "Testing char32_t" << std::endl;
+ test_char<char32_t>();
+ #endif
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // no std
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_std_formatting.cpp b/src/boost/libs/locale/test/test_std_formatting.cpp
new file mode 100644
index 000000000..30cb4e1bd
--- /dev/null
+++ b/src/boost/libs/locale/test/test_std_formatting.cpp
@@ -0,0 +1,371 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+
+#ifdef BOOST_LOCALE_NO_STD_BACKEND
+#include <iostream>
+int main()
+{
+ std::cout << "STD Backend is not build... Skipping" << std::endl;
+}
+#else
+
+
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/encoding.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <iostream>
+
+//#define DEBUG_FMT
+
+#include <boost/config.hpp>
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4996)
+#endif
+
+
+template<typename C1,typename C2>
+bool equal(std::basic_string<C1> const &s1,std::basic_string<C2> const &s2)
+{
+ return boost::locale::conv::from_utf(s1,"UTF-8") == boost::locale::conv::from_utf(s2,"UTF-8");
+}
+
+template<>
+bool equal(std::string const &s1,std::string const &s2)
+{
+ return s1==s2;
+}
+
+template<typename CharType>
+std::basic_string<CharType> conv_to_char(char const *p)
+{
+ std::basic_string<CharType> r;
+ while(*p)
+ r+=CharType(*p++);
+ return r;
+}
+
+
+template<typename CharType,typename RefCharType>
+void test_by_char(std::locale const &l,std::locale const &lreal)
+{
+ typedef std::basic_stringstream<CharType> ss_type;
+ typedef std::basic_stringstream<RefCharType> ss_ref_type;
+
+ using namespace boost::locale;
+
+ {
+ std::cout << "- Testing as::posix" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << 1045.45;
+ TEST(ss);
+ double n;
+ ss >> n;
+ TEST(ss);
+ TEST(n == 1045.45);
+ TEST(ss.str()==to_correct_string<CharType>("1045.45",l));
+ #ifdef DEBUG_FMT
+ std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
+ #endif
+ }
+
+ {
+ std::cout << "- Testing as::number" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << as::number;
+ ss << 1045.45;
+ TEST(ss);
+ double n;
+ ss >> n;
+ TEST(ss);
+ TEST(n == 1045.45);
+
+ ss_ref_type ss_ref;
+ ss_ref.imbue(lreal);
+
+ ss_ref << 1045.45;
+
+ TEST(equal(ss.str(),ss_ref.str()));
+ #ifdef DEBUG_FMT
+ std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
+ std::cout << "[" << boost::locale::conv::from_utf(ss_ref.str(),"UTF-8") << "]\n" ;
+ #endif
+ }
+
+ {
+ std::cout << "- Testing as::currency national " << std::endl;
+
+ bool bad_parsing = false;
+ ss_ref_type ss_ref;
+ ss_ref.imbue(lreal);
+ ss_ref << std::showbase;
+ std::use_facet<std::money_put<RefCharType> >(lreal).put(ss_ref,false,ss_ref,RefCharType(' '),104334);
+ { // workaround MSVC library issues
+ std::ios_base::iostate err=std::ios_base::iostate();
+ typename std::money_get<RefCharType>::iter_type end;
+ long double tmp;
+ std::use_facet<std::money_get<RefCharType> >(lreal).get(ss_ref,end,false,ss_ref,err,tmp);
+ if(err & std::ios_base::failbit) {
+ std::cout << "-- Looks like standard library does not support parsing well" << std::endl;
+ bad_parsing=true;
+ }
+ }
+
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << as::currency;
+ ss << 1043.34;
+ if(!bad_parsing) {
+ TEST(ss);
+ double v1;
+ ss >> v1;
+ }
+
+
+ TEST(equal(ss.str(),ss_ref.str()));
+ #ifdef DEBUG_FMT
+ std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
+ std::cout << "[" << boost::locale::conv::from_utf(ss_ref.str(),"UTF-8") << "]\n" ;
+ #endif
+
+ }
+
+ {
+ std::cout << "- Testing as::currency iso" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << as::currency << as::currency_iso;
+ ss << 1043.34;
+ TEST(ss);
+ double v1;
+ ss >> v1;
+ TEST(ss);
+ TEST(v1==1043.34);
+
+ ss_ref_type ss_ref;
+ ss_ref.imbue(lreal);
+ ss_ref << std::showbase;
+ std::use_facet<std::money_put<RefCharType> >(lreal).put(ss_ref,true,ss_ref,RefCharType(' '),104334);
+
+ TEST(equal(ss.str(),ss_ref.str()));
+ #ifdef DEBUG_FMT
+ std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
+ std::cout << "[" << boost::locale::conv::from_utf(ss_ref.str(),"UTF-8") << "]\n" ;
+ #endif
+ }
+
+
+ {
+ std::cout << "- Testing as::date/time" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ time_t a_date = 3600*24*(31+4); // Feb 5th
+ time_t a_time = 3600*15+60*33; // 15:33:05
+ time_t a_timesec = 13;
+ time_t a_datetime = a_date + a_time + a_timesec;
+
+ ss << as::time_zone("GMT");
+
+ ss << as::date << a_datetime << CharType('\n');
+ ss << as::time << a_datetime << CharType('\n');
+ ss << as::datetime << a_datetime << CharType('\n');
+ ss << as::time_zone("GMT+01:00");
+ ss << as::ftime(conv_to_char<CharType>("%H")) << a_datetime << CharType('\n');
+ ss << as::time_zone("GMT+00:15");
+ ss << as::ftime(conv_to_char<CharType>("%M")) << a_datetime << CharType('\n');
+
+ ss_ref_type ss_ref;
+ ss_ref.imbue(lreal);
+
+ std::basic_string<RefCharType> rfmt(conv_to_char<RefCharType>("%x\n%X\n%c\n16\n48\n"));
+
+ std::tm tm=*gmtime(&a_datetime);
+
+ std::use_facet<std::time_put<RefCharType> >(lreal).put(ss_ref,ss_ref,RefCharType(' '),&tm,rfmt.c_str(),rfmt.c_str()+rfmt.size());
+
+ TEST(equal(ss.str(),ss_ref.str()));
+ #ifdef DEBUG_FMT
+ std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
+ std::cout << "[" << boost::locale::conv::from_utf(ss_ref.str(),"UTF-8") << "]\n" ;
+ #endif
+ }
+
+}
+
+int main()
+{
+ try {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select("std");
+ boost::locale::localization_backend_manager::global(mgr);
+ boost::locale::generator gen;
+
+ {
+ std::cout << "en_US.UTF locale" << std::endl;
+ std::string real_name;
+ std::string name = get_std_name("en_US.UTF-8",&real_name);
+ if(name.empty()) {
+ std::cout << "en_US.UTF-8 not supported" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name),l2(real_name.c_str());
+ std::cout << "UTF-8" << std::endl;
+ if(name==real_name)
+ test_by_char<char,char>(l1,l2);
+ else
+ test_by_char<char,wchar_t>(l1,l2);
+
+ std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
+ test_by_char<wchar_t,wchar_t>(l1,l2);
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::cout << "char16 UTF-16" << std::endl;
+ test_by_char<char16_t,char16_t>(l1,l2);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::cout << "char32 UTF-32" << std::endl;
+ test_by_char<char32_t,char32_t>(l1,l2);
+ #endif
+ }
+ }
+ {
+ std::cout << "en_US.Latin-1 locale" << std::endl;
+ std::string real_name;
+ std::string name = get_std_name("en_US.ISO8859-1",&real_name);
+ if(name.empty()) {
+ std::cout << "en_US.ISO8859-8 not supported" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name),l2(real_name.c_str());
+ test_by_char<char,char>(l1,l2);
+ std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
+ test_by_char<wchar_t,wchar_t>(l1,l2);
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::cout << "char16 UTF-16" << std::endl;
+ test_by_char<char16_t,char16_t>(l1,l2);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::cout << "char32 UTF-32" << std::endl;
+ test_by_char<char32_t,char32_t>(l1,l2);
+ #endif
+ }
+ }
+ {
+ std::cout << "he_IL.UTF locale" << std::endl;
+ std::string real_name;
+ std::string name = get_std_name("he_IL.UTF-8",&real_name);
+ if(name.empty()) {
+ std::cout << "he_IL.UTF-8 not supported" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name),l2(real_name.c_str());
+ std::cout << "UTF-8" << std::endl;
+ if(name==real_name)
+ test_by_char<char,char>(l1,l2);
+ else
+ test_by_char<char,wchar_t>(l1,l2);
+
+ std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
+ test_by_char<wchar_t,wchar_t>(l1,l2);
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::cout << "char16 UTF-16" << std::endl;
+ test_by_char<char16_t,char16_t>(l1,l2);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::cout << "char32 UTF-32" << std::endl;
+ test_by_char<char32_t,char32_t>(l1,l2);
+ #endif
+ }
+ }
+ {
+ std::cout << "he_IL.ISO8859-8 locale" << std::endl;
+ std::string real_name;
+ std::string name = get_std_name("he_IL.ISO8859-8",&real_name);
+ if(name.empty()) {
+ std::cout << "he_IL.ISO8859-8 not supported" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name),l2(real_name.c_str());
+ test_by_char<char,char>(l1,l2);
+ std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
+ test_by_char<wchar_t,wchar_t>(l1,l2);
+
+ #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ std::cout << "char16 UTF-16" << std::endl;
+ test_by_char<char16_t,char16_t>(l1,l2);
+ #endif
+ #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ std::cout << "char32 UTF-32" << std::endl;
+ test_by_char<char32_t,char32_t>(l1,l2);
+ #endif
+ }
+ }
+ {
+ std::cout << "Testing UTF-8 punct workaround" << std::endl;
+ std::string real_name;
+ std::string name = get_std_name("ru_RU.UTF-8",&real_name);
+ if(name.empty()) {
+ std::cout << "- No russian locale" << std::endl;
+ }
+ else if(name != real_name) {
+ std::cout << "- Not having UTF-8 locale, no need for workaround" << std::endl;
+ }
+ else {
+ std::locale l1=gen(name),l2(real_name.c_str());
+ bool fails = false;
+ try {
+ std::ostringstream ss;
+ ss.imbue(l2);
+ ss << 12345.45;
+ boost::locale::conv::from_utf<char>(ss.str(),"windows-1251",boost::locale::conv::stop);
+ fails = false;
+ }
+ catch(...) {
+ fails = true;
+ }
+
+ if(!fails) {
+ std::cout << "- No invalid UTF. No need to check"<<std::endl;
+ }
+ else {
+ std::ostringstream ss;
+ ss.imbue(l1);
+ ss << std::setprecision(10) ;
+ ss << boost::locale::as::number << 12345.45;
+ TEST(ss.str() == "12 345,45" || ss.str()=="12345,45");
+ }
+ }
+ }
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // no std
+
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_utf.cpp b/src/boost/libs/locale/test/test_utf.cpp
new file mode 100644
index 000000000..3476154da
--- /dev/null
+++ b/src/boost/libs/locale/test/test_utf.cpp
@@ -0,0 +1,303 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <boost/locale/utf.hpp>
+
+#include <string.h>
+
+using namespace boost::locale::utf;
+
+char *make2(unsigned v)
+{
+ static unsigned char buf[3] = {0};
+ buf[0] = 0xC0 | (v >> 6);
+ buf[1] = 0x80 | (v & 0x3F );
+ return reinterpret_cast<char*>(buf);
+}
+
+char *make3(unsigned v)
+{
+ static unsigned char buf[4] = {0};
+ buf[0] = 0xE0 | ((v >> 12) ) ;
+ buf[1] = 0x80 | ((v >> 6) & 0x3F );
+ buf[2] = 0x80 | ((v >> 0) & 0x3F );
+ return reinterpret_cast<char*>(buf);
+}
+
+char *make4(unsigned v)
+{
+ static unsigned char buf[5] = {0};
+ buf[0] = 0xF0 | ((v >> 18) ) ;
+ buf[1] = 0x80 | ((v >> 12) & 0x3F );
+ buf[2] = 0x80 | ((v >> 6) & 0x3F );
+ buf[3] = 0x80 | ((v >> 0) & 0x3F );
+ return reinterpret_cast<char*>(buf);
+}
+
+boost::uint32_t const *u32_seq(boost::uint32_t a)
+{
+ static boost::uint32_t buf[2];
+ buf[0]=a;
+ buf[1]=0;
+ return buf;
+}
+
+boost::uint16_t const *u16_seq(boost::uint16_t a)
+{
+ static boost::uint16_t buf[2];
+ buf[0]=a;
+ buf[1]=0;
+ return buf;
+}
+
+boost::uint16_t const *u16_seq(boost::uint16_t a,boost::uint16_t b)
+{
+ static boost::uint16_t buf[3];
+ buf[0]=a;
+ buf[1]=b;
+ buf[2]=0;
+ return buf;
+}
+
+template<typename CharType>
+void test_to(CharType const *s,unsigned codepoint)
+{
+ CharType const *begin = s;
+ CharType const *end = begin;
+
+ while(*end)
+ end++;
+
+ typedef utf_traits<CharType> tr;
+
+ TEST(tr::max_width == 4 / sizeof(CharType));
+
+ TEST(tr::template decode<CharType const *>(begin,end) == codepoint);
+
+ if(codepoint == incomplete || codepoint != illegal)
+ TEST(end == begin);
+
+ if(codepoint == incomplete) {
+ TEST(*s== 0 || 0 < tr::trail_length(*s));
+ TEST(tr::trail_length(*s) + 1 > end - s);
+ }
+
+ if(codepoint != incomplete && codepoint != illegal) {
+ begin=s;
+ TEST(tr::is_lead(*begin));
+ TEST(!tr::is_trail(*begin));
+ begin++;
+ while(begin!=end) {
+ TEST(tr::is_trail(*begin));
+ TEST(!tr::is_lead(*begin));
+ begin++;
+ }
+ TEST(tr::width(codepoint)==end - s);
+ TEST(tr::trail_length(*s) == tr::width(codepoint) - 1);
+ begin = s;
+ TEST(tr::decode_valid(begin) == codepoint);
+ TEST(begin == end);
+ }
+}
+
+template<typename CharType>
+void test_from(CharType const *str,unsigned codepoint)
+{
+ CharType buf[5] = {1,1,1,1,1};
+ CharType *p=buf;
+ p = utf_traits<CharType>::template encode<CharType *>(codepoint,p);
+ CharType const *end = str;
+ while(*end)
+ end++;
+ TEST(end - str == p-buf );
+ TEST(*p);
+ *p=0;
+ TEST(memcmp(str,buf,sizeof(CharType) * (end-str))==0);
+}
+
+
+int main()
+{
+ try {
+
+ std::cout << "Test UTF-8" << std::endl;
+ std::cout << "- From UTF-8" << std::endl;
+
+
+ std::cout << "-- Correct" << std::endl;
+
+ test_to("\x7f",0x7f);
+ test_to("\xc2\x80",0x80);
+ test_to("\xdf\xbf",0x7ff);
+ test_to("\xe0\xa0\x80",0x800);
+ test_to("\xef\xbf\xbf",0xffff);
+ test_to("\xf0\x90\x80\x80",0x10000);
+ test_to("\xf4\x8f\xbf\xbf",0x10ffff);
+
+ std::cout << "-- Too big" << std::endl;
+ test_to("\xf4\x9f\x80\x80",illegal); // 11 0000
+ test_to("\xfb\xbf\xbf\xbf",illegal); // 3ff ffff
+ test_to("\xf8\x90\x80\x80\x80",illegal); // 400 0000
+ test_to("\xfd\xbf\xbf\xbf\xbf\xbf",illegal); // 7fff ffff
+
+ std::cout << "-- Invalid length" << std::endl;
+
+ /// test that this actually works
+ test_to(make2(0x80),0x80);
+ test_to(make2(0x7ff),0x7ff);
+
+ test_to(make3(0x800),0x800);
+ test_to(make3(0xffff),0xffff);
+
+ test_to(make4(0x10000),0x10000);
+ test_to(make4(0x10ffff),0x10ffff);
+
+ test_to(make4(0x110000),illegal);
+ test_to(make4(0x1fffff),illegal);
+
+ test_to(make2(0),illegal);
+ test_to(make3(0),illegal);
+ test_to(make4(0),illegal);
+ test_to(make2(0x7f),illegal);
+ test_to(make3(0x7f),illegal);
+ test_to(make4(0x7f),illegal);
+
+ test_to(make3(0x80),illegal);
+ test_to(make4(0x80),illegal);
+ test_to(make3(0x7ff),illegal);
+ test_to(make4(0x7ff),illegal);
+
+ test_to(make4(0x8000),illegal);
+ test_to(make4(0xffff),illegal);
+
+ std::cout << "-- Invalid surrogate" << std::endl;
+
+ test_to(make3(0xd800),illegal);
+ test_to(make3(0xdbff),illegal);
+ test_to(make3(0xdc00),illegal);
+ test_to(make3(0xdfff),illegal);
+
+ test_to(make4(0xd800),illegal);
+ test_to(make4(0xdbff),illegal);
+ test_to(make4(0xdc00),illegal);
+ test_to(make4(0xdfff),illegal);
+
+ std::cout <<"-- Incomplete" << std::endl;
+
+ test_to("",incomplete);
+
+ test_to("\x80",illegal);
+ test_to("\xc2",incomplete);
+
+ test_to("\xdf",incomplete);
+
+ test_to("\xe0",incomplete);
+ test_to("\xe0\xa0",incomplete);
+
+ test_to("\xef\xbf",incomplete);
+ test_to("\xef",incomplete);
+
+ test_to("\xf0\x90\x80",incomplete);
+ test_to("\xf0\x90",incomplete);
+ test_to("\xf0",incomplete);
+
+ test_to("\xf4\x8f\xbf",incomplete);
+ test_to("\xf4\x8f",incomplete);
+ test_to("\xf4",incomplete);
+
+ std::cout << "- To UTF-8" << std::endl;
+
+ std::cout << "-- Test correct" << std::endl;
+
+ test_from("\x7f",0x7f);
+ test_from("\xc2\x80",0x80);
+ test_from("\xdf\xbf",0x7ff);
+ test_from("\xe0\xa0\x80",0x800);
+ test_from("\xef\xbf\xbf",0xffff);
+ test_from("\xf0\x90\x80\x80",0x10000);
+ test_from("\xf4\x8f\xbf\xbf",0x10ffff);
+
+ std::cout << "Test UTF-16" << std::endl;
+ std::cout << "- From UTF-16" << std::endl;
+
+
+ std::cout << "-- Correct" << std::endl;
+
+ test_to(u16_seq(0x10),0x10);
+ test_to(u16_seq(0xffff),0xffff);
+ test_to(u16_seq(0xD800,0xDC00),0x10000);
+ test_to(u16_seq(0xDBFF,0xDFFF),0x10FFFF);
+
+
+ std::cout << "-- Invalid surrogate" << std::endl;
+
+ test_to(u16_seq(0xDFFF),illegal);
+ test_to(u16_seq(0xDC00),illegal);
+
+ std::cout <<"-- Incomplete" << std::endl;
+
+ test_to(u16_seq(0),incomplete);
+ test_to(u16_seq(0xD800),incomplete);
+ test_to(u16_seq(0xDBFF),incomplete);
+
+ std::cout << "- To UTF-16" << std::endl;
+
+ std::cout << "-- Test correct" << std::endl;
+
+ test_to(u16_seq(0x10),0x10);
+ test_to(u16_seq(0xffff),0xffff);
+ test_to(u16_seq(0xD800,0xDC00),0x10000);
+ test_to(u16_seq(0xDBFF,0xDFFF),0x10FFFF);
+
+
+ std::cout << "Test UTF-32" << std::endl;
+ std::cout << "- From UTF-32" << std::endl;
+
+
+ std::cout << "-- Correct" << std::endl;
+
+ test_to(u32_seq(0x10),0x10);
+ test_to(u32_seq(0xffff),0xffff);
+ test_to(u32_seq(0x10000),0x10000);
+ test_to(u32_seq(0x10ffff),0x10ffff);
+
+
+
+ std::cout << "-- Invalid surrogate" << std::endl;
+
+ test_to(u32_seq(0xD800),illegal);
+ test_to(u32_seq(0xDBFF),illegal);
+ test_to(u32_seq(0xDFFF),illegal);
+ test_to(u32_seq(0xDC00),illegal);
+ test_to(u32_seq(0x110000),illegal);
+
+ std::cout <<"-- Incomplete" << std::endl;
+
+ test_to(u32_seq(0),incomplete);
+
+ std::cout << "- To UTF-32" << std::endl;
+
+ std::cout << "-- Test correct" << std::endl;
+
+ test_to(u32_seq(0x10),0x10);
+ test_to(u32_seq(0xffff),0xffff);
+ test_to(u32_seq(0x10ffff),0x10ffff);
+
+
+
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+}
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_winapi_collate.cpp b/src/boost/libs/locale/test/test_winapi_collate.cpp
new file mode 100644
index 000000000..fb12f7cac
--- /dev/null
+++ b/src/boost/libs/locale/test/test_winapi_collate.cpp
@@ -0,0 +1,133 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifdef BOOST_LOCALE_NO_WINAPI_BACKEND
+#include <iostream>
+int main()
+{
+ std::cout << "WinAPI Backend is not build... Skipping" << std::endl;
+}
+#else
+
+#include <boost/locale/collator.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+
+
+template<typename Char>
+void test_comp(std::locale l,std::basic_string<Char> left,std::basic_string<Char> right,int ilevel,int expected)
+{
+ typedef std::basic_string<Char> string_type;
+ boost::locale::collator_base::level_type level = static_cast<boost::locale::collator_base::level_type>(ilevel);
+ TEST(boost::locale::comparator<Char>(l,level)(left,right) == (expected < 0));
+ if(ilevel==4) {
+ std::collate<Char> const &coll=std::use_facet<std::collate<Char> >(l);
+ string_type lt=coll.transform(left.c_str(),left.c_str()+left.size());
+ string_type rt=coll.transform(right.c_str(),right.c_str()+right.size());
+ if(expected < 0)
+ TEST(lt<rt);
+ else if(expected == 0) {
+ TEST(lt==rt);
+ }
+ else
+ TEST(lt > rt);
+ long lh=coll.hash(left.c_str(),left.c_str()+left.size());
+ long rh=coll.hash(right.c_str(),right.c_str()+right.size());
+ if(expected == 0)
+ TEST(lh==rh);
+ else
+ TEST(lh!=rh);
+ }
+ boost::locale::collator<Char> const &coll=std::use_facet<boost::locale::collator<Char> >(l);
+ string_type lt=coll.transform(level,left.c_str(),left.c_str()+left.size());
+ TEST(lt==coll.transform(level,left));
+ string_type rt=coll.transform(level,right.c_str(),right.c_str()+right.size());
+ TEST(rt==coll.transform(level,right));
+ if(expected < 0)
+ TEST(lt<rt);
+ else if(expected == 0)
+ TEST(lt==rt);
+ else
+ TEST(lt > rt);
+ long lh=coll.hash(level,left.c_str(),left.c_str()+left.size());
+ TEST(lh==coll.hash(level,left));
+ long rh=coll.hash(level,right.c_str(),right.c_str()+right.size());
+ TEST(rh==coll.hash(level,right));
+ if(expected == 0)
+ TEST(lh==rh);
+ else
+ TEST(lh!=rh);
+
+}
+
+#define TEST_COMP(c,_l,_r) test_comp<c>(l,_l,_r,level,expected)
+
+
+void compare(std::string left,std::string right,int level,int expected)
+{
+ boost::locale::generator gen;
+ std::locale l=gen("en_US.UTF-8");
+ if(level == 4)
+ TEST(l(left,right) == (expected < 0));
+ TEST_COMP(char,left,right);
+ TEST_COMP(wchar_t,to<wchar_t>(left),to<wchar_t>(right));
+}
+
+
+void test_collate()
+{
+ int
+ primary = 0,
+ secondary = 1,
+ tertiary = 2,
+ quaternary = 3,
+ identical = 4;
+ int le = -1,gt = 1,eq = 0;
+
+
+ compare("a","A",primary,eq);
+ compare("a","A",secondary,eq);
+ compare("A","a",tertiary,gt);
+ compare("a","A",tertiary,le);
+ compare("a","A",quaternary,le);
+ compare("A","a",quaternary,gt);
+ compare("a","A",identical,le);
+ compare("A","a",identical,gt);
+ compare("a","ä",primary,eq); // a , ä
+ compare("a","ä",secondary,le); // a , ä
+ compare("ä","a",secondary,gt); // a , ä
+ compare("a","ä",quaternary,le); // a , ä
+ compare("ä","a",quaternary,gt); // a , ä
+ compare("a","ä",identical,le); // a , ä
+ compare("ä","a",identical,gt); // a , ä
+}
+
+
+
+
+int main()
+{
+ try {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select("winapi");
+ boost::locale::localization_backend_manager::global(mgr);
+
+ test_collate();
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+#endif // NO WINAPI
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_winapi_convert.cpp b/src/boost/libs/locale/test/test_winapi_convert.cpp
new file mode 100644
index 000000000..5f5584b70
--- /dev/null
+++ b/src/boost/libs/locale/test/test_winapi_convert.cpp
@@ -0,0 +1,108 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifdef BOOST_LOCALE_NO_WINAPI_BACKEND
+#include <iostream>
+int main()
+{
+ std::cout << "WinAPI Backend is not build... Skipping" << std::endl;
+}
+#else
+
+#include <boost/locale/conversion.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/info.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include <iostream>
+
+template<typename CharType>
+void test_one(std::locale const &l,std::string src,std::string tgtl,std::string tgtu)
+{
+ TEST(boost::locale::to_upper(to_correct_string<CharType>(src,l),l) == to_correct_string<CharType>(tgtu,l));
+ TEST(boost::locale::to_lower(to_correct_string<CharType>(src,l),l) == to_correct_string<CharType>(tgtl,l));
+ TEST(boost::locale::fold_case(to_correct_string<CharType>(src,l),l) == to_correct_string<CharType>(tgtl,l));
+}
+
+template<typename CharType>
+void test_char()
+{
+ boost::locale::generator gen;
+
+ std::cout << "- Testing at least C" << std::endl;
+
+
+ std::locale l = gen("en_US.UTF-8");
+
+ test_one<CharType>(l,"Hello World i","hello world i","HELLO WORLD I");
+
+ std::string name = "en_US.UTF-8";
+
+ std::cout << "- Testing " << name << std::endl;
+ l=gen(name);
+ test_one<CharType>(l,"Façade","façade","FAÇADE");
+
+
+ name = "tr_TR.UTF-8";
+ std::cout << "Testing " << name << std::endl;
+ test_one<CharType>(gen(name),"i","i","İ");
+
+}
+
+template<typename Char>
+void test_normc(std::basic_string<Char> orig,std::basic_string<Char> normal,boost::locale::norm_type type)
+{
+ std::locale l = boost::locale::generator().generate("en_US.UTF-8");
+ TEST(boost::locale::normalize(orig,type,l)==normal);
+ TEST(boost::locale::normalize(orig.c_str(),type,l)==normal);
+ TEST(boost::locale::normalize(orig.c_str(),orig.c_str()+orig.size(),type,l)==normal);
+}
+
+
+void test_norm(std::string orig,std::string normal,boost::locale::norm_type type)
+{
+ test_normc<char>(orig,normal,type);
+ test_normc<wchar_t>(to<wchar_t>(orig),to<wchar_t>(normal),type);
+}
+
+int main()
+{
+ try {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select("winapi");
+ boost::locale::localization_backend_manager::global(mgr);
+
+ std::cout << "Testing char" << std::endl;
+ test_char<char>();
+ std::cout << "Testing wchar_t" << std::endl;
+ test_char<wchar_t>();
+
+ std::cout << "Testing Unicode normalization" << std::endl;
+ test_norm("\xEF\xAC\x81","\xEF\xAC\x81",boost::locale::norm_nfd); /// ligature fi
+ test_norm("\xEF\xAC\x81","\xEF\xAC\x81",boost::locale::norm_nfc);
+ #if defined(_WIN32_NT) && _WIN32_NT >= 0x600
+ test_norm("\xEF\xAC\x81","fi",boost::locale::norm_nfkd);
+ test_norm("\xEF\xAC\x81","fi",boost::locale::norm_nfkc);
+ #endif
+ test_norm("ä","ä",boost::locale::norm_nfd); // ä to a and accent
+ test_norm("ä","ä",boost::locale::norm_nfc);
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // no winapi
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/test/test_winapi_formatting.cpp b/src/boost/libs/locale/test/test_winapi_formatting.cpp
new file mode 100644
index 000000000..a505b6f3e
--- /dev/null
+++ b/src/boost/libs/locale/test/test_winapi_formatting.cpp
@@ -0,0 +1,267 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifdef BOOST_LOCALE_NO_WINAPI_BACKEND
+#include <iostream>
+int main()
+{
+ std::cout << "WinAPI Backend is not build... Skipping" << std::endl;
+}
+#else
+
+#include <boost/locale/formatting.hpp>
+#include <boost/locale/localization_backend.hpp>
+#include <boost/locale/generator.hpp>
+#include <boost/locale/encoding.hpp>
+#include <boost/locale/info.hpp>
+#include <iomanip>
+#include "test_locale.hpp"
+#include "test_locale_tools.hpp"
+#include "../src/win32/lcid.hpp"
+#include <iostream>
+
+#include <time.h>
+#include <assert.h>
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#include <windows.h>
+
+#define DEBUG_FMT
+
+bool equal(std::string const &s1,std::wstring const &s2)
+{
+ bool res = s1 == boost::locale::conv::from_utf(s2,"UTF-8");
+ #ifdef DEBUG_FMT
+ if(!res)
+ std::cout << "[" << s1 << "]!=["<<boost::locale::conv::from_utf(s2,"UTF-8")<<"]"<<std::endl;
+ #endif
+ return res;
+}
+
+bool equal(std::wstring const &s1,std::wstring const &s2)
+{
+ bool res = s1 == s2;
+ #ifdef DEBUG_FMT
+ if(!res)
+ std::cout << "[" << boost::locale::conv::from_utf(s1,"UTF-8") << "]!=["<<boost::locale::conv::from_utf(s2,"UTF-8")<<"]"<<std::endl;
+ #endif
+ return res;
+}
+
+
+bool equal(std::string const &s1,std::string const &s2)
+{
+ bool res = s1 == s2;
+ #ifdef DEBUG_FMT
+ if(!res)
+ std::cout << "[" << s1 << "]!=["<<s2<<"]"<<std::endl;
+ #endif
+ return res;
+}
+
+bool equal(std::wstring const &s1,std::string const &s2)
+{
+ bool res = s1 == boost::locale::conv::to_utf<wchar_t>(s2,"UTF-8");
+ #ifdef DEBUG_FMT
+ if(!res)
+ std::cout << "[" << boost::locale::conv::from_utf(s1,"UTF-8") << "]!=["<<s2<<"]"<<std::endl;
+ #endif
+ return res;
+
+}
+
+template<typename CharType>
+std::basic_string<CharType> conv_to_char(char const *p)
+{
+ std::basic_string<CharType> r;
+ while(*p)
+ r+=CharType(*p++);
+ return r;
+}
+
+
+template<typename CharType>
+void test_by_char(std::locale const &l,std::string name,int lcid)
+{
+ typedef std::basic_stringstream<CharType> ss_type;
+ typedef std::basic_string<CharType> string_type;
+
+ using namespace boost::locale;
+
+ {
+ std::cout << "--- Testing as::posix" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << 1045.45;
+ TEST(ss);
+ double n;
+ ss >> n;
+ TEST(ss);
+ TEST(n == 1045.45);
+ TEST(equal(ss.str(),"1045.45"));
+ }
+
+ {
+ std::cout << "--- Testing as::number" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << as::number;
+ ss << 1045.45;
+ TEST(ss);
+ double n;
+ ss >> n;
+ TEST(ss);
+ TEST(n == 1045.45);
+
+ if(name == "ru_RU.UTF-8") {
+ if(sizeof(CharType)==1)
+ TEST(equal(ss.str(),"1 045,45")); // SP
+ else
+ TEST(equal(ss.str(),"1\xC2\xA0" "045,45")); // NBSP
+ }
+ else
+ TEST(equal(ss.str(),"1,045.45"));
+ }
+
+ {
+ std::cout << "--- Testing as::currency " << std::endl;
+
+ ss_type ss;
+ ss.imbue(l);
+
+ ss << as::currency;
+ ss << 1043.34;
+ TEST(ss);
+
+ wchar_t buf[256];
+ GetCurrencyFormatW(lcid,0,L"1043.34",0,buf,256);
+
+ TEST(equal(ss.str(),buf));
+ }
+
+ {
+ std::cout << "--- Testing as::date/time" << std::endl;
+ ss_type ss;
+ ss.imbue(l);
+
+ time_t a_date = 3600*24*(31+4); // Feb 5th
+ time_t a_time = 3600*15+60*33; // 15:33:13
+ time_t a_timesec = 13;
+ time_t a_datetime = a_date + a_time + a_timesec;
+
+ ss << as::time_zone("GMT");
+
+ ss << as::date << a_datetime << CharType('\n');
+ ss << as::time << a_datetime << CharType('\n');
+ ss << as::datetime << a_datetime << CharType('\n');
+ ss << as::time_zone("GMT+01:00");
+ ss << as::ftime(conv_to_char<CharType>("%H")) << a_datetime << CharType('\n');
+ ss << as::time_zone("GMT+00:15");
+ ss << as::ftime(conv_to_char<CharType>("%M")) << a_datetime << CharType('\n');
+
+ wchar_t time_buf[256];
+ wchar_t date_buf[256];
+
+ SYSTEMTIME st= { 1970, 2,5, 5,15,33,13,0 };
+ GetTimeFormatW(lcid,0,&st,0,time_buf,256);
+ GetDateFormatW(lcid,0,&st,0,date_buf,256);
+ TEST(equal(ss.str(),std::wstring(date_buf)+L"\n" + time_buf +L"\n" + date_buf + L" " + time_buf + L"\n16\n48\n"));
+
+ }
+
+}
+
+
+void test_date_time(std::locale l)
+{
+ std::ostringstream ss;
+ ss.imbue(l);
+
+ ss << boost::locale::as::time_zone("GMT");
+
+ time_t a_date = 3600*24*(31+4); // Feb 5th
+ time_t a_time = 3600*15+60*33; // 15:33:13
+ time_t a_timesec = 13;
+ time_t a_datetime = a_date + a_time + a_timesec;
+
+ std::string pat[] = {
+ "a", "Thu",
+ "A", "Thursday",
+ "b", "Feb",
+ "B", "February",
+ "d", "05",
+ "D", "02/05/70",
+ "e", "5",
+ "h", "Feb",
+ "H", "15",
+ "I", "03",
+ "m", "02",
+ "M", "33",
+ "n", "\n",
+ "p", "PM",
+ "r", "03:33:13 PM",
+ "R", "15:33",
+ "S", "13",
+ "t", "\t",
+ "y", "70",
+ "Y", "1970",
+ "%", "%"
+ };
+
+ for(unsigned i=0;i<sizeof(pat)/sizeof(pat[0]);i+=2) {
+ ss.str("");
+ ss << boost::locale::as::ftime("%" + pat[i]) << a_datetime;
+ TEST(equal(ss.str(),pat[i+1]));
+ }
+}
+
+int main()
+{
+ try {
+ boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
+ mgr.select("winapi");
+ boost::locale::localization_backend_manager::global(mgr);
+ boost::locale::generator gen;
+ std::string name;
+ std::string names[] = { "en_US.UTF-8", "he_IL.UTF-8", "ru_RU.UTF-8" };
+ int lcids[] = { 0x0409, 0x040D ,0x0419 };
+
+ for(unsigned i=0;i<sizeof(names)/sizeof(names[9]);i++) {
+ name = names[i];
+ std::cout << "- " << name << " locale" << std::endl;
+ if(boost::locale::impl_win::locale_to_lcid(name) == 0) {
+ std::cout << "-- not supported, skipping" << std::endl;
+ continue;
+ }
+ std::locale l1=gen(name);
+ std::cout << "-- UTF-8" << std::endl;
+ test_by_char<char>(l1,name,lcids[i]);
+ std::cout << "-- UTF-16" << std::endl;
+ test_by_char<wchar_t>(l1,name,lcids[i]);
+ }
+ std::cout << "- Testing strftime" <<std::endl;
+ test_date_time(gen("en_US.UTF-8"));
+ }
+ catch(std::exception const &e) {
+ std::cerr << "Failed " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ FINALIZE();
+
+}
+
+#endif // no winapi
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
+
+// boostinspect:noascii
diff --git a/src/boost/libs/locale/tools/cross-compile-gettext.sh b/src/boost/libs/locale/tools/cross-compile-gettext.sh
new file mode 100755
index 000000000..ce8491baa
--- /dev/null
+++ b/src/boost/libs/locale/tools/cross-compile-gettext.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+#
+# Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+
+# Small and Fast Cross Compile Script
+
+rm -r build
+cd build
+
+BUILD_TYPE=i586-mingw32msvc
+GETTEXT_VER=0.18.1.1
+ICONV_VER=1.13.1
+
+wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$ICONV_VER.tar.gz || exit 1
+wget http://ftp.gnu.org/pub/gnu/gettext/gettext-$GETTEXT_VER.tar.gz || exit 1
+
+tar -xzf libiconv-$ICONV_VER.tar.gz || exit 1
+tar -xzf gettext-$GETTEXT_VER.tar.gz || exit 1
+
+
+mkdir win32
+PACKAGE_DIR=gettext-tools-static-$GETTEXT_VER
+mkdir $PACKAGE_DIR
+
+PREFIX=`pwd`/win32
+
+cd libiconv-$ICONV_VER
+
+./configure --disable-shared --host=$BUILD_TYPE --prefix=$PREFIX || exit 1
+make -j 4 && make install || exit 1
+cp ./COPYING ../$PACKAGE_DIR/COPYING-libiconv.txt
+
+cd ../gettext-$GETTEXT_VER
+
+./configure --disable-shared --host=$BUILD_TYPE --prefix=$PREFIX --with-libiconv-prefix=$PREFIX || exit 1
+cd gettext-tools
+make -j 4 && make install || exit 1
+cd ..
+
+cp ./gettext-tools/gnulib-lib/libxml/COPYING ../$PACKAGE_DIR/COPYING-libxml.txt
+cp ./COPYING ../$PACKAGE_DIR/COPYING-gettext.txt
+
+cd ..
+
+echo http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$ICONV_VER.tar.gz > $PACKAGE_DIR/sources.txt
+echo http://ftp.gnu.org/pub/gnu/gettext/gettext-$GETTEXT_VER.tar.gz >> $PACKAGE_DIR/sources.txt
+
+cp win32/bin/*.exe $PACKAGE_DIR
+
+unix2dos $PACKAGE_DIR/*.txt
+
+zip $PACKAGE_DIR.zip $PACKAGE_DIR/*
+
+mv $PACKAGE_DIR.zip ..