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