Blame tests/cxx/t-locale.cc

Packit 5c3484
/* Test locale support in C++ functions.
Packit 5c3484
Packit 5c3484
Copyright 2001-2003, 2007 Free Software Foundation, Inc.
Packit 5c3484
Packit 5c3484
This file is part of the GNU MP Library test suite.
Packit 5c3484
Packit 5c3484
The GNU MP Library test suite is free software; you can redistribute it
Packit 5c3484
and/or modify it under the terms of the GNU General Public License as
Packit 5c3484
published by the Free Software Foundation; either version 3 of the License,
Packit 5c3484
or (at your option) any later version.
Packit 5c3484
Packit 5c3484
The GNU MP Library test suite is distributed in the hope that it will be
Packit 5c3484
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5c3484
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 5c3484
Public License for more details.
Packit 5c3484
Packit 5c3484
You should have received a copy of the GNU General Public License along with
Packit 5c3484
the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
Packit 5c3484
Packit 5c3484
#include <clocale>
Packit 5c3484
#include <iostream>
Packit 5c3484
#include <cstdlib>
Packit 5c3484
Packit 5c3484
#include "gmp.h"
Packit 5c3484
#include "gmp-impl.h"
Packit 5c3484
#include "tests.h"
Packit 5c3484
Packit 5c3484
using namespace std;
Packit 5c3484
Packit 5c3484
Packit 5c3484
extern "C" {
Packit 5c3484
  char point_string[2];
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
#if HAVE_STD__LOCALE
Packit 5c3484
// Like std::numpunct, but with decimal_point coming from point_string[].
Packit 5c3484
class my_numpunct : public numpunct<char> {
Packit 5c3484
 public:
Packit 5c3484
  explicit my_numpunct (size_t r = 0) : numpunct<char>(r) { }
Packit 5c3484
 protected:
Packit 5c3484
  char do_decimal_point() const { return point_string[0]; }
Packit 5c3484
};
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
set_point (char c)
Packit 5c3484
{
Packit 5c3484
  point_string[0] = c;
Packit 5c3484
Packit 5c3484
#if HAVE_STD__LOCALE
Packit 5c3484
  locale loc (locale::classic(), new my_numpunct ());
Packit 5c3484
  locale::global (loc);
Packit 5c3484
#endif
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
check_input (void)
Packit 5c3484
{
Packit 5c3484
  static const struct {
Packit 5c3484
    const char  *str1;
Packit 5c3484
    const char  *str2;
Packit 5c3484
    double      want;
Packit 5c3484
  } data[] = {
Packit 5c3484
Packit 5c3484
    { "1","",   1.0 },
Packit 5c3484
    { "1","0",  1.0 },
Packit 5c3484
    { "1","00", 1.0 },
Packit 5c3484
Packit 5c3484
    { "","5",    0.5 },
Packit 5c3484
    { "0","5",   0.5 },
Packit 5c3484
    { "00","5",  0.5 },
Packit 5c3484
    { "00","50", 0.5 },
Packit 5c3484
Packit 5c3484
    { "1","5",    1.5 },
Packit 5c3484
    { "1","5e1", 15.0 },
Packit 5c3484
  };
Packit 5c3484
Packit 5c3484
  static char point[] = {
Packit 5c3484
    '.', ',', 'x', '\xFF'
Packit 5c3484
  };
Packit 5c3484
Packit 5c3484
  mpf_t  got;
Packit 5c3484
  mpf_init (got);
Packit 5c3484
Packit 5c3484
  for (size_t i = 0; i < numberof (point); i++)
Packit 5c3484
    {
Packit 5c3484
      set_point (point[i]);
Packit 5c3484
Packit 5c3484
      for (int neg = 0; neg <= 1; neg++)
Packit 5c3484
        {
Packit 5c3484
          for (size_t j = 0; j < numberof (data); j++)
Packit 5c3484
            {
Packit 5c3484
              string str = string(data[j].str1)+point[i]+string(data[j].str2);
Packit 5c3484
              if (neg)
Packit 5c3484
                str = "-" + str;
Packit 5c3484
Packit 5c3484
              istringstream is (str.c_str());
Packit 5c3484
Packit 5c3484
              mpf_set_ui (got, 123);   // dummy initial value
Packit 5c3484
Packit 5c3484
              if (! (is >> got))
Packit 5c3484
                {
Packit 5c3484
                  cout << "istream mpf_t operator>> error\n";
Packit 5c3484
                  cout << "  point " << point[i] << "\n";
Packit 5c3484
                  cout << "  str   \"" << str << "\"\n";
Packit 5c3484
                  cout << "  localeconv point \""
Packit 5c3484
                       << GMP_DECIMAL_POINT << "\"\n";
Packit 5c3484
                  abort ();
Packit 5c3484
                }
Packit 5c3484
Packit 5c3484
              double want = data[j].want;
Packit 5c3484
              if (neg)
Packit 5c3484
                want = -want;
Packit 5c3484
              if (mpf_cmp_d (got, want) != 0)
Packit 5c3484
                {
Packit 5c3484
                  cout << "istream mpf_t operator>> wrong\n";
Packit 5c3484
                  cout << "  point " << point[i] << "\n";
Packit 5c3484
                  cout << "  str   \"" << str << "\"\n";
Packit 5c3484
                  cout << "  got   " << got << "\n";
Packit 5c3484
                  cout << "  want  " << want << "\n";
Packit 5c3484
                  cout << "  localeconv point \""
Packit 5c3484
                       << GMP_DECIMAL_POINT << "\"\n";
Packit 5c3484
                  abort ();
Packit 5c3484
                }
Packit 5c3484
            }
Packit 5c3484
        }
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  mpf_clear (got);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
check_output (void)
Packit 5c3484
{
Packit 5c3484
  static char point[] = {
Packit 5c3484
    '.', ',', 'x', '\xFF'
Packit 5c3484
  };
Packit 5c3484
Packit 5c3484
  for (size_t i = 0; i < numberof (point); i++)
Packit 5c3484
    {
Packit 5c3484
      set_point (point[i]);
Packit 5c3484
      ostringstream  got;
Packit 5c3484
Packit 5c3484
      mpf_t  f;
Packit 5c3484
      mpf_init (f);
Packit 5c3484
      mpf_set_d (f, 1.5);
Packit 5c3484
      got << f;
Packit 5c3484
      mpf_clear (f);
Packit 5c3484
Packit 5c3484
      string  want = string("1") + point[i] + string("5");
Packit 5c3484
Packit 5c3484
      if (want.compare (got.str()) != 0)
Packit 5c3484
        {
Packit 5c3484
          cout << "ostream mpf_t operator<< doesn't respect locale\n";
Packit 5c3484
          cout << "  point " << point[i] << "\n";
Packit 5c3484
          cout << "  got   \"" << got.str() << "\"\n";
Packit 5c3484
          cout << "  want  \"" << want      << "\"\n";
Packit 5c3484
          abort ();
Packit 5c3484
        }
Packit 5c3484
    }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
replacement_works (void)
Packit 5c3484
{
Packit 5c3484
  set_point ('x');
Packit 5c3484
  mpf_t  f;
Packit 5c3484
  mpf_init (f);
Packit 5c3484
  mpf_set_d (f, 1.5);
Packit 5c3484
  ostringstream s;
Packit 5c3484
  s << f;
Packit 5c3484
  mpf_clear (f);
Packit 5c3484
Packit 5c3484
  return (s.str().compare("1x5") == 0);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
main (void)
Packit 5c3484
{
Packit 5c3484
  tests_start ();
Packit 5c3484
Packit 5c3484
  if (replacement_works())
Packit 5c3484
    {
Packit 5c3484
      check_input ();
Packit 5c3484
      check_output ();
Packit 5c3484
    }
Packit 5c3484
  else
Packit 5c3484
    {
Packit 5c3484
      cout << "Replacing decimal point didn't work, tests skipped\n";
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  tests_end ();
Packit 5c3484
  return 0;
Packit 5c3484
}