t-locale.cc revision 1.1.1.1.8.1 1 /* Test locale support in C++ functions.
2
3 Copyright 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library test suite.
6
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
11
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 Public License for more details.
16
17 You should have received a copy of the GNU General Public License along with
18 the GNU MP Library test suite. If not, see http://www.gnu.org/licenses/. */
19
20 #include <clocale>
21 #include <iostream>
22 #include <cstdlib>
23
24 #include "gmp.h"
25 #include "gmp-impl.h"
26 #include "tests.h"
27
28 using namespace std;
29
30
31 extern "C" {
32 char point_string[2];
33 }
34
35 #if HAVE_STD__LOCALE
36 // Like std::numpunct, but with decimal_point coming from point_string[].
37 class my_numpunct : public numpunct<char> {
38 public:
39 explicit my_numpunct (size_t r = 0) : numpunct<char>(r) { }
40 protected:
41 char do_decimal_point() const { return point_string[0]; }
42 };
43 #endif
44
45 void
46 set_point (char c)
47 {
48 point_string[0] = c;
49
50 #if HAVE_STD__LOCALE
51 locale loc (locale::classic(), new my_numpunct ());
52 locale::global (loc);
53 #endif
54 }
55
56
57 void
58 check_input (void)
59 {
60 static const struct {
61 const char *str1;
62 const char *str2;
63 double want;
64 } data[] = {
65
66 { "1","", 1.0 },
67 { "1","0", 1.0 },
68 { "1","00", 1.0 },
69
70 { "","5", 0.5 },
71 { "0","5", 0.5 },
72 { "00","5", 0.5 },
73 { "00","50", 0.5 },
74
75 { "1","5", 1.5 },
76 { "1","5e1", 15.0 },
77 };
78
79 static char point[] = {
80 '.', ',', 'x', '\xFF'
81 };
82
83 mpf_t got;
84 mpf_init (got);
85
86 for (size_t i = 0; i < numberof (point); i++)
87 {
88 set_point (point[i]);
89
90 for (int neg = 0; neg <= 1; neg++)
91 {
92 for (size_t j = 0; j < numberof (data); j++)
93 {
94 string str = string(data[j].str1)+point[i]+string(data[j].str2);
95 if (neg)
96 str = "-" + str;
97
98 istringstream is (str.c_str());
99
100 mpf_set_ui (got, 123); // dummy initial value
101
102 if (! (is >> got))
103 {
104 cout << "istream mpf_t operator>> error\n";
105 cout << " point " << point[i] << "\n";
106 cout << " str \"" << str << "\"\n";
107 cout << " localeconv point \""
108 << localeconv()->decimal_point << "\"\n";
109 abort ();
110 }
111
112 double want = data[j].want;
113 if (neg)
114 want = -want;
115 if (mpf_cmp_d (got, want) != 0)
116 {
117 cout << "istream mpf_t operator>> wrong\n";
118 cout << " point " << point[i] << "\n";
119 cout << " str \"" << str << "\"\n";
120 cout << " got " << got << "\n";
121 cout << " want " << want << "\n";
122 cout << " localeconv point \""
123 << localeconv()->decimal_point << "\"\n";
124 abort ();
125 }
126 }
127 }
128 }
129
130 mpf_clear (got);
131 }
132
133 void
134 check_output (void)
135 {
136 static char point[] = {
137 '.', ',', 'x', '\xFF'
138 };
139
140 for (size_t i = 0; i < numberof (point); i++)
141 {
142 set_point (point[i]);
143 ostringstream got;
144
145 mpf_t f;
146 mpf_init (f);
147 mpf_set_d (f, 1.5);
148 got << f;
149 mpf_clear (f);
150
151 string want = string("1") + point[i] + string("5");
152
153 if (want.compare (got.str()) != 0)
154 {
155 cout << "ostream mpf_t operator<< doesn't respect locale\n";
156 cout << " point " << point[i] << "\n";
157 cout << " got \"" << got.str() << "\"\n";
158 cout << " want \"" << want << "\"\n";
159 abort ();
160 }
161 }
162 }
163
164 int
165 replacement_works (void)
166 {
167 set_point ('x');
168 mpf_t f;
169 mpf_init (f);
170 mpf_set_d (f, 1.5);
171 ostringstream s;
172 s << f;
173 mpf_clear (f);
174
175 return (s.str().compare("1x5") == 0);
176 }
177
178 int
179 main (void)
180 {
181 tests_start ();
182
183 if (replacement_works())
184 {
185 check_input ();
186 check_output ();
187 }
188 else
189 {
190 cout << "Replacing decimal point didn't work, tests skipped\n";
191 }
192
193 tests_end ();
194 return 0;
195 }
196