• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //  Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3 //
4 //  Distributed under the Boost Software License, Version 1.0. (See
5 //  accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 
9 
10 #ifdef BOOST_LOCALE_NO_STD_BACKEND
11 #include <iostream>
main()12 int main()
13 {
14         std::cout << "STD Backend is not build... Skipping" << std::endl;
15 }
16 #else
17 
18 
19 #include <boost/locale/formatting.hpp>
20 #include <boost/locale/localization_backend.hpp>
21 #include <boost/locale/generator.hpp>
22 #include <boost/locale/encoding.hpp>
23 #include <iomanip>
24 #include "test_locale.hpp"
25 #include "test_locale_tools.hpp"
26 #include <iostream>
27 
28 //#define DEBUG_FMT
29 
30 #include <boost/config.hpp>
31 #ifdef BOOST_MSVC
32 #  pragma warning(disable : 4996)
33 #endif
34 
35 
36 template<typename C1,typename C2>
equal(std::basic_string<C1> const & s1,std::basic_string<C2> const & s2)37 bool equal(std::basic_string<C1> const &s1,std::basic_string<C2> const &s2)
38 {
39     return boost::locale::conv::from_utf(s1,"UTF-8") == boost::locale::conv::from_utf(s2,"UTF-8");
40 }
41 
42 template<>
equal(std::string const & s1,std::string const & s2)43 bool equal(std::string const &s1,std::string const &s2)
44 {
45     return s1==s2;
46 }
47 
48 template<typename CharType>
conv_to_char(char const * p)49 std::basic_string<CharType> conv_to_char(char const *p)
50 {
51     std::basic_string<CharType> r;
52     while(*p)
53         r+=CharType(*p++);
54     return r;
55 }
56 
57 
58 template<typename CharType,typename RefCharType>
test_by_char(std::locale const & l,std::locale const & lreal)59 void test_by_char(std::locale const &l,std::locale const &lreal)
60 {
61     typedef std::basic_stringstream<CharType> ss_type;
62     typedef std::basic_stringstream<RefCharType> ss_ref_type;
63 
64     using namespace boost::locale;
65 
66     {
67         std::cout << "- Testing as::posix" << std::endl;
68         ss_type ss;
69         ss.imbue(l);
70 
71         ss << 1045.45;
72         TEST(ss);
73         double n;
74         ss >> n;
75         TEST(ss);
76         TEST(n == 1045.45);
77         TEST(ss.str()==to_correct_string<CharType>("1045.45",l));
78         #ifdef DEBUG_FMT
79         std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
80         #endif
81     }
82 
83     {
84         std::cout << "- Testing as::number" << std::endl;
85         ss_type ss;
86         ss.imbue(l);
87 
88         ss << as::number;
89         ss << 1045.45;
90         TEST(ss);
91         double n;
92         ss >> n;
93         TEST(ss);
94         TEST(n == 1045.45);
95 
96         ss_ref_type ss_ref;
97         ss_ref.imbue(lreal);
98 
99         ss_ref << 1045.45;
100 
101         TEST(equal(ss.str(),ss_ref.str()));
102         #ifdef DEBUG_FMT
103         std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
104         std::cout << "[" << boost::locale::conv::from_utf(ss_ref.str(),"UTF-8") << "]\n" ;
105         #endif
106     }
107 
108     {
109         std::cout << "- Testing as::currency national " << std::endl;
110 
111         bool bad_parsing = false;
112         ss_ref_type ss_ref;
113         ss_ref.imbue(lreal);
114         ss_ref << std::showbase;
115         std::use_facet<std::money_put<RefCharType> >(lreal).put(ss_ref,false,ss_ref,RefCharType(' '),104334);
116         { // workaround MSVC library issues
117             std::ios_base::iostate err=std::ios_base::iostate();
118             typename std::money_get<RefCharType>::iter_type end;
119             long double tmp;
120             std::use_facet<std::money_get<RefCharType> >(lreal).get(ss_ref,end,false,ss_ref,err,tmp);
121             if(err & std::ios_base::failbit) {
122                 std::cout << "-- Looks like standard library does not support parsing well" << std::endl;
123                 bad_parsing=true;
124             }
125         }
126 
127         ss_type ss;
128         ss.imbue(l);
129 
130         ss << as::currency;
131         ss << 1043.34;
132         if(!bad_parsing) {
133             TEST(ss);
134             double v1;
135             ss >> v1;
136         }
137 
138 
139         TEST(equal(ss.str(),ss_ref.str()));
140         #ifdef DEBUG_FMT
141         std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
142         std::cout << "[" << boost::locale::conv::from_utf(ss_ref.str(),"UTF-8") << "]\n" ;
143         #endif
144 
145     }
146 
147     {
148         std::cout << "- Testing as::currency iso" << std::endl;
149         ss_type ss;
150         ss.imbue(l);
151 
152         ss << as::currency << as::currency_iso;
153         ss << 1043.34;
154         TEST(ss);
155         double v1;
156         ss >> v1;
157         TEST(ss);
158         TEST(v1==1043.34);
159 
160         ss_ref_type ss_ref;
161         ss_ref.imbue(lreal);
162         ss_ref << std::showbase;
163         std::use_facet<std::money_put<RefCharType> >(lreal).put(ss_ref,true,ss_ref,RefCharType(' '),104334);
164 
165         TEST(equal(ss.str(),ss_ref.str()));
166         #ifdef DEBUG_FMT
167         std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
168         std::cout << "[" << boost::locale::conv::from_utf(ss_ref.str(),"UTF-8") << "]\n" ;
169         #endif
170     }
171 
172 
173     {
174         std::cout << "- Testing as::date/time" << std::endl;
175         ss_type ss;
176         ss.imbue(l);
177 
178         time_t a_date = 3600*24*(31+4); // Feb 5th
179         time_t a_time = 3600*15+60*33; // 15:33:05
180         time_t a_timesec = 13;
181         time_t a_datetime = a_date + a_time + a_timesec;
182 
183         ss << as::time_zone("GMT");
184 
185         ss << as::date << a_datetime << CharType('\n');
186         ss << as::time << a_datetime << CharType('\n');
187         ss << as::datetime << a_datetime << CharType('\n');
188         ss << as::time_zone("GMT+01:00");
189         ss << as::ftime(conv_to_char<CharType>("%H")) << a_datetime << CharType('\n');
190         ss << as::time_zone("GMT+00:15");
191         ss << as::ftime(conv_to_char<CharType>("%M")) << a_datetime << CharType('\n');
192 
193         ss_ref_type ss_ref;
194         ss_ref.imbue(lreal);
195 
196         std::basic_string<RefCharType> rfmt(conv_to_char<RefCharType>("%x\n%X\n%c\n16\n48\n"));
197 
198         std::tm tm=*gmtime(&a_datetime);
199 
200         std::use_facet<std::time_put<RefCharType> >(lreal).put(ss_ref,ss_ref,RefCharType(' '),&tm,rfmt.c_str(),rfmt.c_str()+rfmt.size());
201 
202         TEST(equal(ss.str(),ss_ref.str()));
203         #ifdef DEBUG_FMT
204         std::cout << "[" << boost::locale::conv::from_utf(ss.str(),"UTF-8") << "]=\n" ;
205         std::cout << "[" << boost::locale::conv::from_utf(ss_ref.str(),"UTF-8") << "]\n" ;
206         #endif
207     }
208 
209 }
210 
main()211 int main()
212 {
213     try {
214         boost::locale::localization_backend_manager mgr = boost::locale::localization_backend_manager::global();
215         mgr.select("std");
216         boost::locale::localization_backend_manager::global(mgr);
217         boost::locale::generator gen;
218 
219         {
220             std::cout << "en_US.UTF locale" << std::endl;
221             std::string real_name;
222             std::string name = get_std_name("en_US.UTF-8",&real_name);
223             if(name.empty()) {
224                 std::cout << "en_US.UTF-8 not supported" << std::endl;
225             }
226             else {
227                 std::locale l1=gen(name),l2(real_name.c_str());
228                 std::cout << "UTF-8" << std::endl;
229                 if(name==real_name)
230                     test_by_char<char,char>(l1,l2);
231                 else
232                     test_by_char<char,wchar_t>(l1,l2);
233 
234                 std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
235                 test_by_char<wchar_t,wchar_t>(l1,l2);
236 
237                 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
238                 std::cout << "char16 UTF-16" << std::endl;
239                 test_by_char<char16_t,char16_t>(l1,l2);
240                 #endif
241                 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
242                 std::cout << "char32 UTF-32" << std::endl;
243                 test_by_char<char32_t,char32_t>(l1,l2);
244                 #endif
245             }
246         }
247         {
248             std::cout << "en_US.Latin-1 locale" << std::endl;
249             std::string real_name;
250             std::string name = get_std_name("en_US.ISO8859-1",&real_name);
251             if(name.empty()) {
252                 std::cout << "en_US.ISO8859-8 not supported" << std::endl;
253             }
254             else {
255                 std::locale l1=gen(name),l2(real_name.c_str());
256                 test_by_char<char,char>(l1,l2);
257                 std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
258                 test_by_char<wchar_t,wchar_t>(l1,l2);
259 
260                 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
261                 std::cout << "char16 UTF-16" << std::endl;
262                 test_by_char<char16_t,char16_t>(l1,l2);
263                 #endif
264                 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
265                 std::cout << "char32 UTF-32" << std::endl;
266                 test_by_char<char32_t,char32_t>(l1,l2);
267                 #endif
268             }
269         }
270         {
271             std::cout << "he_IL.UTF locale" << std::endl;
272             std::string real_name;
273             std::string name = get_std_name("he_IL.UTF-8",&real_name);
274             if(name.empty()) {
275                 std::cout << "he_IL.UTF-8 not supported" << std::endl;
276             }
277             else {
278                 std::locale l1=gen(name),l2(real_name.c_str());
279                 std::cout << "UTF-8" << std::endl;
280                 if(name==real_name)
281                     test_by_char<char,char>(l1,l2);
282                 else
283                     test_by_char<char,wchar_t>(l1,l2);
284 
285                 std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
286                 test_by_char<wchar_t,wchar_t>(l1,l2);
287 
288                 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
289                 std::cout << "char16 UTF-16" << std::endl;
290                 test_by_char<char16_t,char16_t>(l1,l2);
291                 #endif
292                 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
293                 std::cout << "char32 UTF-32" << std::endl;
294                 test_by_char<char32_t,char32_t>(l1,l2);
295                 #endif
296             }
297         }
298         {
299             std::cout << "he_IL.ISO8859-8 locale" << std::endl;
300             std::string real_name;
301             std::string name = get_std_name("he_IL.ISO8859-8",&real_name);
302             if(name.empty()) {
303                 std::cout << "he_IL.ISO8859-8 not supported" << std::endl;
304             }
305             else {
306                 std::locale l1=gen(name),l2(real_name.c_str());
307                 test_by_char<char,char>(l1,l2);
308                 std::cout << "Wide UTF-" << sizeof(wchar_t) * 8 << std::endl;
309                 test_by_char<wchar_t,wchar_t>(l1,l2);
310 
311                 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
312                 std::cout << "char16 UTF-16" << std::endl;
313                 test_by_char<char16_t,char16_t>(l1,l2);
314                 #endif
315                 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
316                 std::cout << "char32 UTF-32" << std::endl;
317                 test_by_char<char32_t,char32_t>(l1,l2);
318                 #endif
319             }
320         }
321         {
322             std::cout << "Testing UTF-8 punct workaround" << std::endl;
323             std::string real_name;
324             std::string name = get_std_name("ru_RU.UTF-8",&real_name);
325             if(name.empty()) {
326                 std::cout << "- No russian locale" << std::endl;
327             }
328             else if(name != real_name) {
329                 std::cout << "- Not having UTF-8 locale, no need for workaround" << std::endl;
330             }
331             else {
332                 std::locale l1=gen(name),l2(real_name.c_str());
333                 bool fails = false;
334                 try {
335                     std::ostringstream ss;
336                     ss.imbue(l2);
337                     ss << 12345.45;
338                     boost::locale::conv::from_utf<char>(ss.str(),"windows-1251",boost::locale::conv::stop);
339                     fails = false;
340                 }
341                 catch(...) {
342                     fails = true;
343                 }
344 
345                 if(!fails) {
346                     std::cout << "- No invalid UTF. No need to check"<<std::endl;
347                 }
348                 else {
349                     std::ostringstream ss;
350                     ss.imbue(l1);
351                     ss << std::setprecision(10) ;
352                     ss << boost::locale::as::number << 12345.45;
353                     TEST(ss.str() == "12 345,45" || ss.str()=="12345,45");
354                 }
355             }
356         }
357     }
358     catch(std::exception const &e) {
359         std::cerr << "Failed " << e.what() << std::endl;
360         return EXIT_FAILURE;
361     }
362     FINALIZE();
363 
364 }
365 
366 #endif // no std
367 
368 
369 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
370 
371 // boostinspect:noascii
372