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 <stdexcept>
      7 
      8 #  include "complete_digits.h"
      9 
     10 #  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
     11 using namespace std;
     12 #  endif
     13 
     14 struct ref_locale {
     15   const char *name;
     16   const char *decimal_point;
     17   const char *thousands_sep;
     18 };
     19 
     20 static const ref_locale tested_locales[] = {
     21 //{  name,         decimal_point, thousands_sepy_thousands_sep},
     22 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
     23   { "fr_FR",       ",",           "\xa0"},
     24   { "ru_RU.koi8r", ",",           "."},
     25   { "en_GB",       ".",           ","},
     26   { "en_US",       ".",           ","},
     27 #  endif
     28   { "C",           ".",           ","},
     29 };
     30 
     31 //
     32 // tests implementation
     33 //
     34 void LocaleTest::_num_put_get( const locale& loc, const ref_locale* prl ) {
     35   const ref_locale& rl = *prl;
     36   CPPUNIT_ASSERT( has_facet<numpunct<char> >(loc) );
     37   numpunct<char> const& npct = use_facet<numpunct<char> >(loc);
     38   CPPUNIT_ASSERT( npct.decimal_point() == *rl.decimal_point );
     39 
     40   float val = 1234.56f;
     41   ostringstream fostr;
     42   fostr.imbue(loc);
     43   fostr << val;
     44 
     45   string ref = "1";
     46   if (!npct.grouping().empty()) {
     47     ref += npct.thousands_sep();
     48   }
     49   ref += "234";
     50   ref += npct.decimal_point();
     51   ref += "56";
     52   //cout << "In " << loc.name() << " 1234.56 is written: " << fostr.str() << endl;
     53   CPPUNIT_ASSERT( fostr.str() == ref );
     54 
     55   val = 12345678.9f;
     56   ref = "1";
     57   ref += npct.decimal_point();
     58   ref += "23457e+";
     59   string digits = "7";
     60   complete_digits(digits);
     61   ref += digits;
     62   fostr.str("");
     63   fostr << val;
     64   CPPUNIT_ASSERT( fostr.str() == ref );
     65 
     66   val = 1000000000.0f;
     67   fostr.str("");
     68   fostr << val;
     69   digits = "9";
     70   complete_digits(digits);
     71   CPPUNIT_ASSERT( fostr.str() == string("1e+") + digits );
     72 
     73   val = 1234.0f;
     74   ref = "1";
     75   if (!npct.grouping().empty()) {
     76     ref += npct.thousands_sep();
     77   }
     78   ref += "234";
     79   fostr.str("");
     80   fostr << val;
     81   CPPUNIT_ASSERT( fostr.str() == ref );
     82 
     83   val = 10000001.0f;
     84   fostr.str("");
     85   fostr << val;
     86   digits = "7";
     87   complete_digits(digits);
     88   CPPUNIT_ASSERT( fostr.str() == string("1e+") + digits );
     89 
     90   if (npct.grouping().size() == 1 && npct.grouping()[0] == 3) {
     91     int ival = 1234567890;
     92     fostr.str("");
     93     fostr << ival;
     94     ref = "1";
     95     ref += npct.thousands_sep();
     96     ref += "234";
     97     ref += npct.thousands_sep();
     98     ref += "567";
     99     ref += npct.thousands_sep();
    100     ref += "890";
    101     CPPUNIT_ASSERT( fostr.str() == ref );
    102   }
    103 
    104 #if defined (__BORLANDC__)
    105   num_put<char> const& nput = use_facet<num_put<char> >(loc);
    106   typedef numeric_limits<double> limd;
    107   fostr.setf(ios_base::uppercase | ios_base::showpos);
    108 
    109   if (limd::has_infinity) {
    110     double infinity = limd::infinity();
    111     fostr.str("");
    112     nput.put(fostr, fostr, ' ', infinity);
    113     CPPUNIT_ASSERT( fostr.str() == string("+Inf") );
    114   }
    115 
    116   if (limd::has_quiet_NaN) {
    117     /* Ignore FPU exceptions */
    118     unsigned int _float_control_word = _control87(0, 0);
    119     _control87(EM_INVALID|EM_INEXACT, MCW_EM);
    120     double qnan = limd::quiet_NaN();
    121     /* Reset floating point control word */
    122     _clear87();
    123     _control87(_float_control_word, MCW_EM);
    124     fostr.str("");
    125     nput.put(fostr, fostr, ' ', qnan);
    126     CPPUNIT_ASSERT( fostr.str() == string("+NaN") );
    127   }
    128 #endif
    129 }
    130 
    131 typedef void (LocaleTest::*_Test) (const locale&, const ref_locale*);
    132 static void test_supported_locale(LocaleTest& inst, _Test __test) {
    133   size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]);
    134   for (size_t i = 0; i < n; ++i) {
    135     locale loc;
    136 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    137     try
    138 #  endif
    139     {
    140       locale tmp(tested_locales[i].name);
    141       loc = tmp;
    142     }
    143 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    144     catch (runtime_error const&) {
    145       //This locale is not supported.
    146       continue;
    147     }
    148 #  endif
    149     CPPUNIT_MESSAGE( loc.name().c_str() );
    150     (inst.*__test)(loc, tested_locales + i);
    151 
    152     {
    153       locale tmp(locale::classic(), tested_locales[i].name, locale::numeric);
    154       loc = tmp;
    155     }
    156     (inst.*__test)(loc, tested_locales + i);
    157 
    158     {
    159       locale tmp(locale::classic(), new numpunct_byname<char>(tested_locales[i].name));
    160       loc = tmp;
    161     }
    162     (inst.*__test)(loc, tested_locales + i);
    163   }
    164 }
    165 
    166 void LocaleTest::num_put_get()
    167 { test_supported_locale(*this, &LocaleTest::_num_put_get); }
    168 
    169 void LocaleTest::numpunct_by_name()
    170 {
    171   /*
    172    * Check of the 22.1.1.2.7 standard point. Construction of a locale
    173    * instance from a null pointer or an unknown name should result in
    174    * a runtime_error exception.
    175    */
    176 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    177 #    if defined (STLPORT) || !defined (__GNUC__)
    178   try {
    179     locale loc(locale::classic(), new numpunct_byname<char>(static_cast<char const*>(0)));
    180     CPPUNIT_FAIL;
    181   }
    182   catch (runtime_error const& /* e */) {
    183     //CPPUNIT_MESSAGE( e.what() );
    184   }
    185   catch (...) {
    186     CPPUNIT_FAIL;
    187   }
    188 #    endif
    189 
    190   try {
    191     locale loc(locale::classic(), new numpunct_byname<char>("yasli_language"));
    192     CPPUNIT_FAIL;
    193   }
    194   catch (runtime_error const& /* e */) {
    195     //CPPUNIT_MESSAGE( e.what() );
    196   }
    197   catch (...) {
    198     CPPUNIT_FAIL;
    199   }
    200 
    201   try {
    202     string veryLongFacetName("LC_NUMERIC=");
    203     veryLongFacetName.append(512, '?');
    204     locale loc(locale::classic(), new numpunct_byname<char>(veryLongFacetName.c_str()));
    205     CPPUNIT_FAIL;
    206   }
    207   catch (runtime_error const& /* e */) {
    208     //CPPUNIT_MESSAGE( e.what() );
    209   }
    210   catch (...) {
    211     CPPUNIT_FAIL;
    212   }
    213 
    214   try {
    215     locale loc(locale::classic(), "C", locale::numeric);
    216   }
    217   catch (runtime_error const& e) {
    218     CPPUNIT_MESSAGE( e.what() );
    219     CPPUNIT_FAIL;
    220   }
    221   catch (...) {
    222     CPPUNIT_FAIL;
    223   }
    224 
    225   try {
    226     // On platform without real localization support we should rely on the "C" facet.
    227     locale loc(locale::classic(), "", locale::numeric);
    228   }
    229   catch (runtime_error const& e) {
    230     CPPUNIT_MESSAGE( e.what() );
    231     CPPUNIT_FAIL;
    232   }
    233   catch (...) {
    234     CPPUNIT_FAIL;
    235   }
    236 
    237   try {
    238     locale loc(locale::classic(), new numpunct_byname<char>("C"));
    239     numpunct<char> const& cfacet_byname = use_facet<numpunct<char> >(loc);
    240     numpunct<char> const& cfacet = use_facet<numpunct<char> >(locale::classic());
    241 
    242     CPPUNIT_CHECK( cfacet_byname.decimal_point() == cfacet.decimal_point() );
    243     CPPUNIT_CHECK( cfacet_byname.grouping() == cfacet.grouping() );
    244     if (!cfacet.grouping().empty())
    245       CPPUNIT_CHECK( cfacet_byname.thousands_sep() == cfacet.thousands_sep() );
    246 #    if !defined (STLPORT) || !defined (__GLIBC__)
    247     CPPUNIT_CHECK( cfacet_byname.truename() == cfacet.truename() );
    248     CPPUNIT_CHECK( cfacet_byname.falsename() == cfacet.falsename() );
    249 #    endif
    250   }
    251   catch (runtime_error const& /* e */) {
    252     //CPPUNIT_MESSAGE( e.what() );
    253     CPPUNIT_FAIL;
    254   }
    255   catch (...) {
    256     CPPUNIT_FAIL;
    257   }
    258 
    259   try {
    260     // On platform without real localization support we should rely on the "C" locale facet.
    261     locale loc(locale::classic(), new numpunct_byname<char>(""));
    262   }
    263   catch (runtime_error const& e) {
    264     CPPUNIT_MESSAGE( e.what() );
    265     CPPUNIT_FAIL;
    266   }
    267   catch (...) {
    268     CPPUNIT_FAIL;
    269   }
    270 
    271 #    if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
    272 #      if defined (STLPORT) || !defined (__GNUC__)
    273   try {
    274     locale loc(locale::classic(), new numpunct_byname<wchar_t>(static_cast<char const*>(0)));
    275     CPPUNIT_FAIL;
    276   }
    277   catch (runtime_error const&) {
    278   }
    279   catch (...) {
    280     CPPUNIT_FAIL;
    281   }
    282 #      endif
    283 
    284   try {
    285     locale loc(locale::classic(), new numpunct_byname<wchar_t>("yasli_language"));
    286     CPPUNIT_FAIL;
    287   }
    288   catch (runtime_error const&) {
    289   }
    290   catch (...) {
    291     CPPUNIT_FAIL;
    292   }
    293 #    endif
    294 #  endif
    295 }
    296 
    297 #endif
    298