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 //
_num_put_get(const locale & loc,const ref_locale * prl)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*);
test_supported_locale(LocaleTest & inst,_Test __test)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 
num_put_get()166 void LocaleTest::num_put_get()
167 { test_supported_locale(*this, &LocaleTest::_num_put_get); }
168 
numpunct_by_name()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