github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/cxx/t-locale.cc (about) 1 /* Test locale support in C++ functions. 2 3 Copyright 2001-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 https://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 << GMP_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 << GMP_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 }