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