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  }