Home | History | Annotate | Download | only in unit
      1 #include "locale_test.h"
      2 
      3 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
      4 #  include <sstream>
      5 #  include <locale>
      6 #  include <stdexcept>
      7 
      8 #  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
      9 using namespace std;
     10 #  endif
     11 
     12 static const char* tested_locales[] = {
     13 //name,
     14 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
     15   "fr_FR",
     16   "ru_RU.koi8r",
     17   "en_GB",
     18   "en_US",
     19 #  endif
     20   "",
     21   "C"
     22 };
     23 
     24 CPPUNIT_TEST_SUITE_REGISTRATION(LocaleTest);
     25 
     26 //
     27 // tests implementation
     28 //
     29 typedef void (LocaleTest::*_Test) (const locale&);
     30 static void test_supported_locale(LocaleTest &inst, _Test __test) {
     31   size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]);
     32   for (size_t i = 0; i < n; ++i) {
     33     locale loc;
     34 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
     35     try {
     36 #  endif
     37       locale tmp(tested_locales[i]);
     38       loc = tmp;
     39 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
     40     }
     41     catch (runtime_error const&) {
     42       //This locale is not supported.
     43       continue;
     44     }
     45 #  endif
     46     CPPUNIT_MESSAGE( loc.name().c_str() );
     47     (inst.*__test)(loc);
     48   }
     49 }
     50 
     51 void LocaleTest::locale_by_name() {
     52 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
     53   /*
     54    * Check of the 22.1.1.2.7 standard point. Construction of a locale
     55    * instance from a null pointer or an unknown name should result in
     56    * a runtime_error exception.
     57    */
     58   try {
     59     locale loc(static_cast<char const*>(0));
     60     CPPUNIT_FAIL;
     61   }
     62   catch (runtime_error const&) {
     63   }
     64   catch (...) {
     65     CPPUNIT_FAIL;
     66   }
     67 
     68   try {
     69     locale loc("yasli_language");
     70     CPPUNIT_FAIL;
     71   }
     72   catch (runtime_error const& /* e */) {
     73     //CPPUNIT_MESSAGE( e.what() );
     74   }
     75   catch (...) {
     76     CPPUNIT_FAIL;
     77   }
     78 
     79   try {
     80     string very_large_locale_name(1024, '?');
     81     locale loc(very_large_locale_name.c_str());
     82     CPPUNIT_FAIL;
     83   }
     84   catch (runtime_error const& /* e */) {
     85     //CPPUNIT_MESSAGE( e.what() );
     86   }
     87   catch (...) {
     88     CPPUNIT_FAIL;
     89   }
     90 
     91 #if defined (STLPORT) || !defined (_MSC_VER) || (_MSC_VER > 1400)
     92   try {
     93     string very_large_locale_name("LC_CTYPE=");
     94     very_large_locale_name.append(1024, '?');
     95     locale loc(very_large_locale_name.c_str());
     96     CPPUNIT_FAIL;
     97   }
     98   catch (runtime_error const& /* e */) {
     99     //CPPUNIT_MESSAGE( e.what() );
    100   }
    101   catch (...) {
    102     CPPUNIT_FAIL;
    103   }
    104 
    105   try {
    106     string very_large_locale_name("LC_ALL=");
    107     very_large_locale_name.append(1024, '?');
    108     locale loc(very_large_locale_name.c_str());
    109     CPPUNIT_FAIL;
    110   }
    111   catch (runtime_error const& /* e */) {
    112     //CPPUNIT_MESSAGE( e.what() );
    113   }
    114   catch (...) {
    115     CPPUNIT_FAIL;
    116   }
    117 #endif
    118 
    119   try {
    120     locale loc("C");
    121   }
    122   catch (runtime_error const& /* e */) {
    123     /* CPPUNIT_MESSAGE( e.what() ); */
    124     CPPUNIT_FAIL;
    125   }
    126   catch (...) {
    127     CPPUNIT_FAIL;
    128   }
    129 
    130   try {
    131     // On platform without real localization support we should rely on the "C" locale facet.
    132     locale loc("");
    133   }
    134   catch (runtime_error const& /* e */) {
    135     /* CPPUNIT_MESSAGE( e.what() ); */
    136     CPPUNIT_FAIL;
    137   }
    138   catch (...) {
    139     CPPUNIT_FAIL;
    140   }
    141 
    142 #  endif
    143 }
    144 
    145 void LocaleTest::loc_has_facet() {
    146   locale loc("C");
    147   typedef numpunct<char> implemented_facet;
    148   CPPUNIT_ASSERT( has_facet<implemented_facet>(loc) );
    149   /*
    150   typedef num_put<char, back_insert_iterator<string> > not_implemented_facet;
    151   CPPUNIT_ASSERT( !has_facet<not_implemented_facet>(loc) );
    152   */
    153 }
    154 
    155 void LocaleTest::locale_init_problem() {
    156 #  if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
    157   test_supported_locale(*this, &LocaleTest::_locale_init_problem);
    158 #  endif
    159 }
    160 
    161 /*
    162  * Creation of a locale instance imply initialization of some STLport internal
    163  * static objects first. We use a static instance of locale to check that this
    164  * initialization is done correctly.
    165  */
    166 static locale global_loc;
    167 static locale other_loc("");
    168 
    169 #  if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
    170 void LocaleTest::_locale_init_problem( const locale& loc)
    171 {
    172 #    if !defined (__APPLE__) && !defined (__FreeBSD__) || \
    173         !defined(__GNUC__) || ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__> 3)))
    174   typedef codecvt<char,char,mbstate_t> my_facet;
    175 #    else
    176 // std::mbstate_t required for gcc 3.3.2 on FreeBSD...
    177 // I am not sure what key here---FreeBSD or 3.3.2...
    178 //      - ptr 2005-04-04
    179   typedef codecvt<char,char,std::mbstate_t> my_facet;
    180 #    endif
    181 
    182   locale loc_ref(global_loc);
    183   {
    184     locale gloc( loc_ref, new my_facet() );
    185     CPPUNIT_ASSERT( has_facet<my_facet>( gloc ) );
    186     //The following code is just here to try to confuse the reference counting underlying mecanism:
    187     locale::global( locale::classic() );
    188     locale::global( gloc );
    189   }
    190 
    191 #      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    192   try {
    193 #      endif
    194     ostringstream os("test") ;
    195     locale loc2( loc, new my_facet() );
    196     CPPUNIT_ASSERT( has_facet<my_facet>( loc2 ) );
    197     os.imbue( loc2 );
    198 #      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    199   }
    200   catch ( runtime_error& ) {
    201     CPPUNIT_FAIL;
    202   }
    203   catch ( ... ) {
    204    CPPUNIT_FAIL;
    205   }
    206 #      endif
    207 
    208 #      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    209   try {
    210 #      endif
    211     ostringstream os2("test2");
    212 #      if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    213   }
    214   catch ( runtime_error& ) {
    215     CPPUNIT_FAIL;
    216   }
    217   catch ( ... ) {
    218     CPPUNIT_FAIL;
    219   }
    220 #  endif
    221 }
    222 #endif
    223 
    224 void LocaleTest::default_locale()
    225 {
    226   locale loc( "" );
    227 }
    228 
    229 class dummy_facet : public locale::facet {
    230 public:
    231   static locale::id id;
    232 };
    233 
    234 locale::id dummy_facet::id;
    235 
    236 void LocaleTest::combine()
    237 {
    238 #  if (!defined (STLPORT) || \
    239        (defined (_STLP_USE_EXCEPTIONS) && !defined (_STLP_NO_MEMBER_TEMPLATES) && !defined (_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS)))
    240   {
    241     try {
    242       locale loc("");
    243       if (!has_facet<messages<char> >(loc)) {
    244         loc.combine<messages<char> >(loc);
    245         CPPUNIT_FAIL;
    246       }
    247     }
    248     catch (const runtime_error & /* e */) {
    249       /* CPPUNIT_MESSAGE( e.what() ); */
    250     }
    251 
    252     try {
    253       locale loc;
    254       if (!has_facet<dummy_facet>(loc)) {
    255         loc.combine<dummy_facet>(loc);
    256         CPPUNIT_FAIL;
    257       }
    258     }
    259     catch (const runtime_error & /* e */) {
    260       /* CPPUNIT_MESSAGE( e.what() ); */
    261     }
    262   }
    263 
    264   locale loc1(locale::classic()), loc2;
    265   size_t loc1_index = 0;
    266   for (size_t i = 0; _get_ref_monetary(i) != 0; ++i) {
    267     try {
    268       {
    269         locale loc(_get_ref_monetary_name(_get_ref_monetary(i)));
    270         if (loc1 == locale::classic())
    271         {
    272           loc1 = loc;
    273           loc1_index = i;
    274           continue;
    275         }
    276         else
    277         {
    278           loc2 = loc;
    279         }
    280       }
    281 
    282       //We can start the test
    283       ostringstream ostr;
    284       ostr << "combining '" << loc2.name() << "' money facets with '" << loc1.name() << "'";
    285       CPPUNIT_MESSAGE( ostr.str().c_str() );
    286 
    287       //We are going to combine money facets as all formats are different.
    288       {
    289         //We check that resulting locale has correctly acquire loc2 facets.
    290         locale loc = loc1.combine<moneypunct<char, true> >(loc2);
    291         loc = loc.combine<moneypunct<char, false> >(loc2);
    292         loc = loc.combine<money_put<char> >(loc2);
    293         loc = loc.combine<money_get<char> >(loc2);
    294 
    295         //Check loc has the correct facets:
    296         _money_put_get2(loc2, loc, _get_ref_monetary(i));
    297 
    298         //Check loc1 has not been impacted:
    299         _money_put_get2(loc1, loc1, _get_ref_monetary(loc1_index));
    300 
    301         //Check loc2 has not been impacted:
    302         _money_put_get2(loc2, loc2, _get_ref_monetary(i));
    303       }
    304       {
    305         //We check that resulting locale has not wrongly acquire loc1 facets that hasn't been combine:
    306         locale loc = loc2.combine<numpunct<char> >(loc1);
    307         loc = loc.combine<time_put<char> >(loc1);
    308         loc = loc.combine<time_get<char> >(loc1);
    309 
    310         //Check loc has the correct facets:
    311         _money_put_get2(loc2, loc, _get_ref_monetary(i));
    312 
    313         //Check loc1 has not been impacted:
    314         _money_put_get2(loc1, loc1, _get_ref_monetary(loc1_index));
    315 
    316         //Check loc2 has not been impacted:
    317         _money_put_get2(loc2, loc2, _get_ref_monetary(i));
    318       }
    319 
    320       {
    321         // Check auto combination do not result in weird reference counting behavior
    322         // (might generate a crash).
    323         loc1.combine<numpunct<char> >(loc1);
    324       }
    325 
    326       loc1 = loc2;
    327       loc1_index = i;
    328     }
    329     catch (runtime_error const&) {
    330       //This locale is not supported.
    331       continue;
    332     }
    333   }
    334 #  endif
    335 }
    336 
    337 #endif
    338