diff options
Diffstat (limited to 'src/boost/libs/locale/test')
36 files changed, 6100 insertions, 0 deletions
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 Binary files differnew file mode 100644 index 000000000..de43713c4 --- /dev/null +++ b/src/boost/libs/locale/test/he/LC_MESSAGES/default.mo 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 Binary files differnew file mode 100644 index 000000000..ebc9a9ca2 --- /dev/null +++ b/src/boost/libs/locale/test/he/LC_MESSAGES/fall.mo 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 Binary files differnew file mode 100644 index 000000000..54549c182 --- /dev/null +++ b/src/boost/libs/locale/test/he/LC_MESSAGES/simple.mo 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 Binary files differnew file mode 100644 index 000000000..844f9d8d1 --- /dev/null +++ b/src/boost/libs/locale/test/he_IL/LC_MESSAGES/full.mo 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 |