• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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