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