Home | History | Annotate | Download | only in unit
      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 
     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&);
    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 
    232 void LocaleTest::time_put_get()
    233 { test_supported_locale(*this, &LocaleTest::_time_put_get); }
    234 
    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