1 #include "locale_test.h"
2
3 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
4 # include <locale>
5 # include <sstream>
6 # include <memory>
7 # include <stdexcept>
8
9 # if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
10 using namespace std;
11 # endif
12
13 static const char* tested_locales[] = {
14 // name,
15 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
16 "fr_FR",
17 "ru_RU.koi8r",
18 "en_GB",
19 "en_US",
20 # endif
21 "",
22 "C"
23 };
24
_time_put_get(const locale & loc)25 void LocaleTest::_time_put_get( const locale& loc )
26 {
27 {
28 typedef time_put<char, ostreambuf_iterator<char, char_traits<char> > > time_put_facet;
29 CPPUNIT_ASSERT( has_facet<time_put_facet>(loc) );
30 const time_put_facet& tmp = use_facet<time_put_facet>(loc);
31
32 struct tm xmas = { 0, 0, 12, 25, 11, 93 };
33 ostringstream ostr;
34 ostr.imbue(loc);
35 string format = "%B %d %Y";
36
37 time_put_facet::iter_type ret = tmp.put(ostr, ostr, ' ', &xmas, format.data(), format.data() + format.size());
38 CPPUNIT_ASSERT( !ret.failed() );
39
40 /*
41 * In other words, user conformation is required for reliable parsing
42 * of user-entered dates and times, but machine-generated formats can be
43 * parsed reliably. This allows parsers to be aggressive about interpreting
44 * user variations on standard format.
45 *
46 * ISO/IEC 14882, 22.2.5.1
47 */
48 typedef time_get<char, istreambuf_iterator<char, char_traits<char> > > time_get_facet;
49 CPPUNIT_ASSERT( has_facet<time_get_facet>(loc) );
50 const time_get_facet& tmg = use_facet<time_get_facet>(loc);
51 basic_ios<char> io(0);
52 io.imbue(loc);
53
54 istringstream istr( ostr.str() );
55 istreambuf_iterator<char, char_traits<char> > i( istr );
56 istreambuf_iterator<char, char_traits<char> > e;
57 ios_base::iostate err = ios_base::goodbit;
58 struct tm other = { 15, 20, 9, 14, 7, 105 };
59
60 i = tmg.get_monthname( i, e, io, err, &other );
61 CPPUNIT_ASSERT( err == ios_base::goodbit );
62 CPPUNIT_ASSERT( other.tm_mon == xmas.tm_mon );
63
64 ++i; ++i; ++i; ++i; // skip day of month and spaces around it
65 i = tmg.get_year( i, e, io, err, &other );
66
67 CPPUNIT_ASSERT( err == ios_base::eofbit );
68 CPPUNIT_ASSERT( other.tm_year == xmas.tm_year );
69
70 ostringstream ostrX;
71 ostrX.imbue(loc);
72 format = "%x %X";
73
74 ret = tmp.put(ostrX, ostrX, ' ', &xmas, format.data(), format.data() + format.size());
75 CPPUNIT_ASSERT( !ret.failed() );
76
77 istringstream istrX( ostrX.str() );
78 istreambuf_iterator<char, char_traits<char> > j( istrX );
79
80 err = ios_base::goodbit;
81
82 struct tm yet_more = { 15, 20, 9, 14, 7, 105 };
83
84 j = tmg.get_date( j, e, io, err, &yet_more );
85
86 CPPUNIT_ASSERT( err == ios_base::goodbit );
87
88 CPPUNIT_ASSERT( yet_more.tm_sec != xmas.tm_sec );
89 CPPUNIT_ASSERT( yet_more.tm_min != xmas.tm_min );
90 CPPUNIT_ASSERT( yet_more.tm_hour != xmas.tm_hour );
91 CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday );
92 CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon );
93 CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year );
94
95 ++j; // skip space
96
97 j = tmg.get_time( j, e, io, err, &yet_more );
98
99 CPPUNIT_ASSERT( err == ios_base::eofbit || err == ios_base::goodbit );
100
101 CPPUNIT_ASSERT( yet_more.tm_sec == xmas.tm_sec );
102 CPPUNIT_ASSERT( yet_more.tm_min == xmas.tm_min );
103 CPPUNIT_ASSERT( yet_more.tm_hour == xmas.tm_hour );
104 CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday );
105 CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon );
106 CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year );
107 }
108 # if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
109 {
110 typedef time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > time_put_facet;
111 CPPUNIT_ASSERT( has_facet<time_put_facet>(loc) );
112 const time_put_facet& tmp = use_facet<time_put_facet>(loc);
113
114 struct tm xmas = { 0, 0, 12, 25, 11, 93 };
115 wostringstream ostr;
116 ostr.imbue(loc);
117 wstring format = L"%B %d %Y";
118
119 time_put_facet::iter_type ret = tmp.put(ostr, ostr, ' ', &xmas, format.data(), format.data() + format.size());
120 CPPUNIT_ASSERT( !ret.failed() );
121
122 /*
123 * In other words, user conformation is required for reliable parsing
124 * of user-entered dates and times, but machine-generated formats can be
125 * parsed reliably. This allows parsers to be aggressive about interpreting
126 * user variations on standard format.
127 *
128 * ISO/IEC 14882, 22.2.5.1
129 */
130 typedef time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > > time_get_facet;
131 CPPUNIT_ASSERT( has_facet<time_get_facet>(loc) );
132 const time_get_facet& tmg = use_facet<time_get_facet>(loc);
133 // Intentional instantiation with char to show a bug in a previous STLport version.
134 basic_ios<char> io(0);
135 io.imbue(loc);
136
137 wistringstream istr( ostr.str() );
138 istreambuf_iterator<wchar_t, char_traits<wchar_t> > i( istr );
139 istreambuf_iterator<wchar_t, char_traits<wchar_t> > e;
140 ios_base::iostate err = ios_base::goodbit;
141 struct tm other = { 15, 20, 9, 14, 7, 105 };
142
143 i = tmg.get_monthname( i, e, io, err, &other );
144 CPPUNIT_ASSERT( err == ios_base::goodbit );
145 CPPUNIT_ASSERT( other.tm_mon == xmas.tm_mon );
146
147 ++i; ++i; ++i; ++i; // skip day of month and spaces around it
148 i = tmg.get_year( i, e, io, err, &other );
149
150 CPPUNIT_ASSERT( err == ios_base::eofbit );
151 CPPUNIT_ASSERT( other.tm_year == xmas.tm_year );
152
153 wostringstream ostrX;
154 ostrX.imbue(loc);
155 format = L"%x %X";
156
157 ret = tmp.put(ostrX, ostrX, ' ', &xmas, format.data(), format.data() + format.size());
158 CPPUNIT_ASSERT( !ret.failed() );
159
160 wistringstream istrX( ostrX.str() );
161 istreambuf_iterator<wchar_t, char_traits<wchar_t> > j( istrX );
162
163 err = ios_base::goodbit;
164
165 struct tm yet_more = { 15, 20, 9, 14, 7, 105 };
166
167 j = tmg.get_date( j, e, io, err, &yet_more );
168
169 CPPUNIT_ASSERT( err == ios_base::goodbit );
170
171 CPPUNIT_ASSERT( yet_more.tm_sec != xmas.tm_sec );
172 CPPUNIT_ASSERT( yet_more.tm_min != xmas.tm_min );
173 CPPUNIT_ASSERT( yet_more.tm_hour != xmas.tm_hour );
174 CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday );
175 CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon );
176 CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year );
177
178 ++j; // skip space
179
180 j = tmg.get_time( j, e, io, err, &yet_more );
181
182 CPPUNIT_ASSERT( err == ios_base::eofbit || err == ios_base::goodbit );
183
184 CPPUNIT_ASSERT( yet_more.tm_sec == xmas.tm_sec );
185 CPPUNIT_ASSERT( yet_more.tm_min == xmas.tm_min );
186 CPPUNIT_ASSERT( yet_more.tm_hour == xmas.tm_hour );
187 CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday );
188 CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon );
189 CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year );
190 }
191 # endif
192 }
193
194 typedef void (LocaleTest::*_Test) (const locale&);
test_supported_locale(LocaleTest & inst,_Test __test)195 static void test_supported_locale(LocaleTest& inst, _Test __test) {
196 size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]);
197 for (size_t i = 0; i < n; ++i) {
198 locale loc;
199 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
200 try
201 # endif
202 {
203 locale tmp(tested_locales[i]);
204 loc = tmp;
205 }
206 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
207 catch (runtime_error const&) {
208 //This locale is not supported.
209 continue;
210 }
211 # endif
212 CPPUNIT_MESSAGE( loc.name().c_str() );
213 (inst.*__test)(loc);
214
215 {
216 locale tmp(locale::classic(), tested_locales[i], locale::time);
217 loc = tmp;
218 }
219 (inst.*__test)(loc);
220
221 {
222 typedef time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > > time_put_facet;
223 locale tmp0(locale::classic(), new time_put_facet(tested_locales[i]));
224 typedef time_get_byname<char, istreambuf_iterator<char, char_traits<char> > > time_get_facet;
225 locale tmp1(tmp0, new time_get_facet(tested_locales[i]));
226 loc = tmp1;
227 }
228 (inst.*__test)(loc);
229 }
230 }
231
time_put_get()232 void LocaleTest::time_put_get()
233 { test_supported_locale(*this, &LocaleTest::_time_put_get); }
234
time_by_name()235 void LocaleTest::time_by_name()
236 {
237 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
238 /*
239 * Check of the 22.1.1.2.7 standard point. Construction of a locale
240 * instance from a null pointer or an unknown name should result in
241 * a runtime_error exception.
242 */
243 # if defined (STLPORT) || !defined (_MSC_VER) || (_MSC_VER > 1400)
244 try {
245 locale loc(locale::classic(), new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >(static_cast<char const*>(0)));
246 CPPUNIT_FAIL;
247 }
248 catch (runtime_error const&) {
249 }
250 catch (...) {
251 CPPUNIT_FAIL;
252 }
253 # endif
254
255 try {
256 locale loc(locale::classic(), new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >("yasli_language"));
257 CPPUNIT_FAIL;
258 }
259 catch (runtime_error const&) {
260 }
261 catch (...) {
262 CPPUNIT_FAIL;
263 }
264
265 try {
266 string veryLongFacetName("LC_TIME=");
267 veryLongFacetName.append(512, '?');
268 locale loc(locale::classic(), new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >(veryLongFacetName.c_str()));
269 CPPUNIT_FAIL;
270 }
271 catch (runtime_error const& /* e */) {
272 //CPPUNIT_MESSAGE( e.what() );
273 }
274 catch (...) {
275 CPPUNIT_FAIL;
276 }
277
278 try {
279 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >(static_cast<char const*>(0)));
280 CPPUNIT_FAIL;
281 }
282 catch (runtime_error const&) {
283 }
284 catch (...) {
285 CPPUNIT_FAIL;
286 }
287
288 try {
289 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >("yasli_language"));
290 CPPUNIT_FAIL;
291 }
292 catch (runtime_error const&) {
293 }
294 catch (...) {
295 CPPUNIT_FAIL;
296 }
297
298 try {
299 string veryLongFacetName("LC_TIME=");
300 veryLongFacetName.append(512, '?');
301 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >(veryLongFacetName.c_str()));
302 CPPUNIT_FAIL;
303 }
304 catch (runtime_error const& /* e */) {
305 //CPPUNIT_MESSAGE( e.what() );
306 }
307 catch (...) {
308 CPPUNIT_FAIL;
309 }
310
311 try {
312 locale loc(locale::classic(), "C", locale::time);
313 }
314 catch (runtime_error const& /* e */) {
315 /* CPPUNIT_MESSAGE( e.what() ); */
316 CPPUNIT_FAIL;
317 }
318 catch (...) {
319 CPPUNIT_FAIL;
320 }
321
322 try {
323 // On platform without real localization support we should rely on the "C" facet.
324 locale loc(locale::classic(), "", locale::time);
325 }
326 catch (runtime_error const& /* e */) {
327 /* CPPUNIT_MESSAGE( e.what() ); */
328 CPPUNIT_FAIL;
329 }
330 catch (...) {
331 CPPUNIT_FAIL;
332 }
333
334 try {
335 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >("C"));
336 }
337 catch (runtime_error const& /* e */) {
338 /* CPPUNIT_MESSAGE( e.what() ); */
339 CPPUNIT_FAIL;
340 }
341 catch (...) {
342 CPPUNIT_FAIL;
343 }
344
345 try {
346 // On platform without real localization support we should rely on the "C" locale facet.
347 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >(""));
348 }
349 catch (runtime_error const& /* e */) {
350 /* CPPUNIT_MESSAGE( e.what() ); */
351 CPPUNIT_FAIL;
352 }
353 catch (...) {
354 CPPUNIT_FAIL;
355 }
356
357 # if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
358 try {
359 locale loc(locale::classic(), new time_put_byname<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(static_cast<char const*>(0)));
360 CPPUNIT_FAIL;
361 }
362 catch (runtime_error const&) {
363 }
364 catch (...) {
365 CPPUNIT_FAIL;
366 }
367
368 try {
369 locale loc(locale::classic(), new time_put_byname<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >("yasli_language"));
370 CPPUNIT_FAIL;
371 }
372 catch (runtime_error const&) {
373 }
374 catch (...) {
375 CPPUNIT_FAIL;
376 }
377
378 try {
379 locale loc(locale::classic(), new time_get_byname<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(static_cast<char const*>(0)));
380 CPPUNIT_FAIL;
381 }
382 catch (runtime_error const&) {
383 }
384 catch (...) {
385 CPPUNIT_FAIL;
386 }
387
388 try {
389 locale loc(locale::classic(), new time_get_byname<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >("yasli_language"));
390 CPPUNIT_FAIL;
391 }
392 catch (runtime_error const&) {
393 }
394 catch (...) {
395 CPPUNIT_FAIL;
396 }
397
398 # endif
399 # endif
400 }
401
402 #endif
403