Home | History | Annotate | Line # | Download | only in cxx
t-istream.cc revision 1.1.1.1.2.1
      1          1.1   mrg /* Test istream formatted input.
      2          1.1   mrg 
      3          1.1   mrg Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
      4          1.1   mrg 
      5  1.1.1.1.2.1  yamt This file is part of the GNU MP Library test suite.
      6          1.1   mrg 
      7  1.1.1.1.2.1  yamt The GNU MP Library test suite is free software; you can redistribute it
      8  1.1.1.1.2.1  yamt and/or modify it under the terms of the GNU General Public License as
      9  1.1.1.1.2.1  yamt published by the Free Software Foundation; either version 3 of the License,
     10  1.1.1.1.2.1  yamt or (at your option) any later version.
     11  1.1.1.1.2.1  yamt 
     12  1.1.1.1.2.1  yamt The GNU MP Library test suite is distributed in the hope that it will be
     13  1.1.1.1.2.1  yamt useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1.1.1.2.1  yamt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     15  1.1.1.1.2.1  yamt Public License for more details.
     16          1.1   mrg 
     17  1.1.1.1.2.1  yamt You should have received a copy of the GNU General Public License along with
     18  1.1.1.1.2.1  yamt the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
     19          1.1   mrg 
     20          1.1   mrg #include <iostream>
     21          1.1   mrg #include <cstdlib>
     22          1.1   mrg #include <cstring>
     23          1.1   mrg 
     24          1.1   mrg #include "gmp.h"
     25          1.1   mrg #include "gmp-impl.h"
     26          1.1   mrg #include "tests.h"
     27          1.1   mrg 
     28          1.1   mrg using namespace std;
     29          1.1   mrg 
     30          1.1   mrg 
     31          1.1   mrg // Under option_check_standard, the various test cases for mpz operator>>
     32          1.1   mrg // are put through the standard operator>> for long, and likewise mpf
     33          1.1   mrg // operator>> is put through double.
     34          1.1   mrg //
     35          1.1   mrg // In g++ 3.3 this results in some printouts about the final position
     36          1.1   mrg // indicated for something like ".e123".  Our mpf code stops at the "e"
     37          1.1   mrg // since there's no mantissa digits, but g++ reads the whole thing and only
     38          1.1   mrg // then decides it's bad.
     39          1.1   mrg 
     40  1.1.1.1.2.1  yamt bool option_check_standard = false;
     41          1.1   mrg 
     42          1.1   mrg 
     43          1.1   mrg // On some versions of g++ 2.96 it's been observed that putback() may leave
     44          1.1   mrg // tellg() unchanged.  We believe this is incorrect and presumably the
     45          1.1   mrg // result of a bug, since for instance it's ok in g++ 2.95 and g++ 3.3.  We
     46          1.1   mrg // detect the problem at runtime and disable affected checks.
     47          1.1   mrg 
     48  1.1.1.1.2.1  yamt bool putback_tellg_works = true;
     49          1.1   mrg 
     50          1.1   mrg void
     51          1.1   mrg check_putback_tellg (void)
     52          1.1   mrg {
     53          1.1   mrg   istringstream input ("hello");
     54          1.1   mrg   streampos  old_pos, new_pos;
     55          1.1   mrg   char  c;
     56          1.1   mrg 
     57          1.1   mrg   input.get(c);
     58          1.1   mrg   old_pos = input.tellg();
     59          1.1   mrg   input.putback(c);
     60          1.1   mrg   new_pos = input.tellg();
     61          1.1   mrg 
     62          1.1   mrg   if (old_pos == new_pos)
     63          1.1   mrg     {
     64          1.1   mrg       cout << "Warning, istringstream has a bug: putback() doesn't update tellg().\n";;
     65          1.1   mrg       cout << "Tests on tellg() will be skipped.\n";
     66  1.1.1.1.2.1  yamt       putback_tellg_works = false;
     67          1.1   mrg     }
     68          1.1   mrg }
     69          1.1   mrg 
     70          1.1   mrg 
     71          1.1   mrg #define WRONG(str)                                              \
     72          1.1   mrg   do {                                                          \
     73          1.1   mrg     cout << str ", data[" << i << "]\n";                        \
     74          1.1   mrg     cout << "  input: \"" << data[i].input << "\"\n";           \
     75          1.1   mrg     cout << "  flags: " << hex << input.flags() << dec << "\n"; \
     76          1.1   mrg   } while (0)
     77          1.1   mrg 
     78          1.1   mrg void
     79          1.1   mrg check_mpz (void)
     80          1.1   mrg {
     81          1.1   mrg   static const struct {
     82          1.1   mrg     const char     *input;
     83          1.1   mrg     int            want_pos;
     84          1.1   mrg     const char     *want;
     85          1.1   mrg     ios::fmtflags  flags;
     86          1.1   mrg 
     87          1.1   mrg   } data[] = {
     88          1.1   mrg 
     89          1.1   mrg     { "0",      -1, "0",    (ios::fmtflags) 0 },
     90          1.1   mrg     { "123",    -1, "123",  (ios::fmtflags) 0 },
     91          1.1   mrg     { "0123",   -1, "83",   (ios::fmtflags) 0 },
     92          1.1   mrg     { "0x123",  -1, "291",  (ios::fmtflags) 0 },
     93          1.1   mrg     { "-123",   -1, "-123", (ios::fmtflags) 0 },
     94          1.1   mrg     { "-0123",  -1, "-83",  (ios::fmtflags) 0 },
     95          1.1   mrg     { "-0x123", -1, "-291", (ios::fmtflags) 0 },
     96          1.1   mrg     { "+123",   -1, "123", (ios::fmtflags) 0 },
     97          1.1   mrg     { "+0123",  -1, "83",  (ios::fmtflags) 0 },
     98          1.1   mrg     { "+0x123", -1, "291", (ios::fmtflags) 0 },
     99          1.1   mrg 
    100          1.1   mrg     { "0",     -1, "0",    ios::dec },
    101          1.1   mrg     { "1f",     1, "1",    ios::dec },
    102          1.1   mrg     { "011f",   3, "11",   ios::dec },
    103          1.1   mrg     { "123",   -1, "123",  ios::dec },
    104          1.1   mrg     { "-1f",    2, "-1",   ios::dec },
    105          1.1   mrg     { "-011f",  4, "-11",  ios::dec },
    106          1.1   mrg     { "-123",  -1, "-123", ios::dec },
    107          1.1   mrg     { "+1f",    2, "1",    ios::dec },
    108          1.1   mrg     { "+011f",  4, "11",   ios::dec },
    109          1.1   mrg     { "+123",  -1, "123",  ios::dec },
    110          1.1   mrg 
    111          1.1   mrg     { "0",    -1, "0",   ios::oct },
    112          1.1   mrg     { "123",  -1, "83",  ios::oct },
    113          1.1   mrg     { "-123", -1, "-83", ios::oct },
    114          1.1   mrg     { "+123", -1, "83",  ios::oct },
    115          1.1   mrg 
    116          1.1   mrg     { "0",    -1, "0",    ios::hex },
    117          1.1   mrg     { "123",  -1, "291",  ios::hex },
    118          1.1   mrg     { "ff",   -1, "255",  ios::hex },
    119          1.1   mrg     { "FF",   -1, "255",  ios::hex },
    120          1.1   mrg     { "-123", -1, "-291", ios::hex },
    121          1.1   mrg     { "-ff",  -1, "-255", ios::hex },
    122          1.1   mrg     { "-FF",  -1, "-255", ios::hex },
    123          1.1   mrg     { "+123", -1, "291",  ios::hex },
    124          1.1   mrg     { "+ff",  -1, "255",  ios::hex },
    125          1.1   mrg     { "+FF",  -1, "255",  ios::hex },
    126          1.1   mrg     { "ab",   -1, "171",  ios::hex },
    127          1.1   mrg     { "cd",   -1, "205",  ios::hex },
    128          1.1   mrg     { "ef",   -1, "239",  ios::hex },
    129          1.1   mrg 
    130          1.1   mrg     { " 123",  0, NULL,  (ios::fmtflags) 0 },   // not without skipws
    131          1.1   mrg     { " 123", -1, "123", ios::skipws },
    132          1.1   mrg   };
    133          1.1   mrg 
    134          1.1   mrg   mpz_t      got, want;
    135  1.1.1.1.2.1  yamt   bool       got_ok, want_ok;
    136  1.1.1.1.2.1  yamt   bool       got_eof, want_eof;
    137          1.1   mrg   long       got_si, want_si;
    138          1.1   mrg   streampos  init_tellg, got_pos, want_pos;
    139          1.1   mrg 
    140          1.1   mrg   mpz_init (got);
    141          1.1   mrg   mpz_init (want);
    142          1.1   mrg 
    143          1.1   mrg   for (size_t i = 0; i < numberof (data); i++)
    144          1.1   mrg     {
    145  1.1.1.1.2.1  yamt       size_t input_length = strlen (data[i].input);
    146          1.1   mrg       want_pos = (data[i].want_pos == -1
    147  1.1.1.1.2.1  yamt                   ? input_length : data[i].want_pos);
    148  1.1.1.1.2.1  yamt       want_eof = (want_pos == streampos(input_length));
    149          1.1   mrg 
    150          1.1   mrg       want_ok = (data[i].want != NULL);
    151          1.1   mrg 
    152          1.1   mrg       if (data[i].want != NULL)
    153          1.1   mrg         mpz_set_str_or_abort (want, data[i].want, 0);
    154          1.1   mrg       else
    155          1.1   mrg         mpz_set_ui (want, 0L);
    156          1.1   mrg 
    157          1.1   mrg       if (option_check_standard && mpz_fits_slong_p (want))
    158          1.1   mrg         {
    159          1.1   mrg           istringstream  input (data[i].input);
    160          1.1   mrg           input.flags (data[i].flags);
    161          1.1   mrg           init_tellg = input.tellg();
    162          1.1   mrg           want_si = mpz_get_si (want);
    163          1.1   mrg 
    164          1.1   mrg           input >> got_si;
    165  1.1.1.1.2.1  yamt           got_ok = !input.fail();
    166  1.1.1.1.2.1  yamt           got_eof = input.eof();
    167          1.1   mrg           input.clear();
    168          1.1   mrg           got_pos = input.tellg() - init_tellg;
    169          1.1   mrg 
    170          1.1   mrg           if (got_ok != want_ok)
    171          1.1   mrg             {
    172          1.1   mrg               WRONG ("stdc++ operator>> wrong status, check_mpz");
    173          1.1   mrg               cout << "  want_ok: " << want_ok << "\n";
    174          1.1   mrg               cout << "  got_ok:  " << got_ok << "\n";
    175          1.1   mrg             }
    176          1.1   mrg           if (want_ok && got_si != want_si)
    177          1.1   mrg             {
    178          1.1   mrg               WRONG ("stdc++ operator>> wrong result, check_mpz");
    179          1.1   mrg               cout << "  got_si:  " << got_si << "\n";
    180          1.1   mrg               cout << "  want_si: " << want_si << "\n";
    181          1.1   mrg             }
    182  1.1.1.1.2.1  yamt           if (want_ok && got_eof != want_eof)
    183  1.1.1.1.2.1  yamt             {
    184  1.1.1.1.2.1  yamt               WRONG ("stdc++ operator>> wrong EOF state, check_mpz");
    185  1.1.1.1.2.1  yamt               cout << "  got_eof:  " << got_eof << "\n";
    186  1.1.1.1.2.1  yamt               cout << "  want_eof: " << want_eof << "\n";
    187  1.1.1.1.2.1  yamt             }
    188          1.1   mrg           if (putback_tellg_works && got_pos != want_pos)
    189          1.1   mrg             {
    190          1.1   mrg               WRONG ("stdc++ operator>> wrong position, check_mpz");
    191          1.1   mrg               cout << "  want_pos: " << want_pos << "\n";
    192          1.1   mrg               cout << "  got_pos:  " << got_pos << "\n";
    193          1.1   mrg             }
    194          1.1   mrg         }
    195          1.1   mrg 
    196          1.1   mrg       {
    197          1.1   mrg         istringstream  input (data[i].input);
    198          1.1   mrg         input.flags (data[i].flags);
    199          1.1   mrg         init_tellg = input.tellg();
    200          1.1   mrg 
    201          1.1   mrg         mpz_set_ui (got, 0xDEAD);
    202          1.1   mrg         input >> got;
    203  1.1.1.1.2.1  yamt         got_ok = !input.fail();
    204  1.1.1.1.2.1  yamt 	got_eof = input.eof();
    205          1.1   mrg         input.clear();
    206          1.1   mrg         got_pos = input.tellg() - init_tellg;
    207          1.1   mrg 
    208          1.1   mrg         if (got_ok != want_ok)
    209          1.1   mrg           {
    210          1.1   mrg             WRONG ("mpz operator>> wrong status");
    211          1.1   mrg             cout << "  want_ok: " << want_ok << "\n";
    212          1.1   mrg             cout << "  got_ok:  " << got_ok << "\n";
    213          1.1   mrg             abort ();
    214          1.1   mrg           }
    215          1.1   mrg         if (want_ok && mpz_cmp (got, want) != 0)
    216          1.1   mrg           {
    217          1.1   mrg             WRONG ("mpz operator>> wrong result");
    218          1.1   mrg             mpz_trace ("  got ", got);
    219          1.1   mrg             mpz_trace ("  want", want);
    220          1.1   mrg             abort ();
    221          1.1   mrg           }
    222  1.1.1.1.2.1  yamt         if (want_ok && got_eof != want_eof)
    223  1.1.1.1.2.1  yamt           {
    224  1.1.1.1.2.1  yamt             WRONG ("mpz operator>> wrong EOF state");
    225  1.1.1.1.2.1  yamt             cout << "  want_eof: " << want_eof << "\n";
    226  1.1.1.1.2.1  yamt             cout << "  got_eof:  " << got_eof << "\n";
    227  1.1.1.1.2.1  yamt             abort ();
    228  1.1.1.1.2.1  yamt           }
    229          1.1   mrg         if (putback_tellg_works && got_pos != want_pos)
    230          1.1   mrg           {
    231          1.1   mrg             WRONG ("mpz operator>> wrong position");
    232          1.1   mrg             cout << "  want_pos: " << want_pos << "\n";
    233          1.1   mrg             cout << "  got_pos:  " << got_pos << "\n";
    234          1.1   mrg             abort ();
    235          1.1   mrg           }
    236          1.1   mrg       }
    237          1.1   mrg     }
    238          1.1   mrg 
    239          1.1   mrg   mpz_clear (got);
    240          1.1   mrg   mpz_clear (want);
    241          1.1   mrg }
    242          1.1   mrg 
    243          1.1   mrg void
    244          1.1   mrg check_mpq (void)
    245          1.1   mrg {
    246          1.1   mrg   static const struct {
    247          1.1   mrg     const char     *input;
    248          1.1   mrg     int            want_pos;
    249          1.1   mrg     const char     *want;
    250          1.1   mrg     ios::fmtflags  flags;
    251          1.1   mrg 
    252          1.1   mrg   } data[] = {
    253          1.1   mrg 
    254          1.1   mrg     { "0",   -1, "0", (ios::fmtflags) 0 },
    255          1.1   mrg     { "00",  -1, "0", (ios::fmtflags) 0 },
    256          1.1   mrg     { "0x0", -1, "0", (ios::fmtflags) 0 },
    257          1.1   mrg 
    258          1.1   mrg     { "123/456",   -1, "123/456", ios::dec },
    259          1.1   mrg     { "0123/456",  -1, "123/456", ios::dec },
    260          1.1   mrg     { "123/0456",  -1, "123/456", ios::dec },
    261          1.1   mrg     { "0123/0456", -1, "123/456", ios::dec },
    262          1.1   mrg 
    263          1.1   mrg     { "123/456",   -1, "83/302", ios::oct },
    264          1.1   mrg     { "0123/456",  -1, "83/302", ios::oct },
    265          1.1   mrg     { "123/0456",  -1, "83/302", ios::oct },
    266          1.1   mrg     { "0123/0456", -1, "83/302", ios::oct },
    267          1.1   mrg 
    268          1.1   mrg     { "ab",   -1, "171",  ios::hex },
    269          1.1   mrg     { "cd",   -1, "205",  ios::hex },
    270          1.1   mrg     { "ef",   -1, "239",  ios::hex },
    271          1.1   mrg 
    272          1.1   mrg     { "0/0",     -1, "0/0", (ios::fmtflags) 0 },
    273          1.1   mrg     { "5/8",     -1, "5/8", (ios::fmtflags) 0 },
    274          1.1   mrg     { "0x5/0x8", -1, "5/8", (ios::fmtflags) 0 },
    275          1.1   mrg 
    276          1.1   mrg     { "123/456",   -1, "123/456",  (ios::fmtflags) 0 },
    277          1.1   mrg     { "123/0456",  -1, "123/302",  (ios::fmtflags) 0 },
    278          1.1   mrg     { "123/0x456", -1, "123/1110", (ios::fmtflags) 0 },
    279          1.1   mrg     { "123/0X456", -1, "123/1110", (ios::fmtflags) 0 },
    280          1.1   mrg 
    281          1.1   mrg     { "0123/123",   -1, "83/123", (ios::fmtflags) 0 },
    282          1.1   mrg     { "0123/0123",  -1, "83/83",  (ios::fmtflags) 0 },
    283          1.1   mrg     { "0123/0x123", -1, "83/291", (ios::fmtflags) 0 },
    284          1.1   mrg     { "0123/0X123", -1, "83/291", (ios::fmtflags) 0 },
    285          1.1   mrg 
    286          1.1   mrg     { "0x123/123",   -1, "291/123", (ios::fmtflags) 0 },
    287          1.1   mrg     { "0X123/0123",  -1, "291/83",  (ios::fmtflags) 0 },
    288          1.1   mrg     { "0x123/0x123", -1, "291/291", (ios::fmtflags) 0 },
    289          1.1   mrg 
    290          1.1   mrg     { " 123",  0, NULL,  (ios::fmtflags) 0 },   // not without skipws
    291          1.1   mrg     { " 123", -1, "123", ios::skipws },
    292  1.1.1.1.2.1  yamt 
    293  1.1.1.1.2.1  yamt     { "123 /456",    3, "123",  (ios::fmtflags) 0 },
    294  1.1.1.1.2.1  yamt     { "123/ 456",    4,  NULL,  (ios::fmtflags) 0 },
    295  1.1.1.1.2.1  yamt     { "123/"    ,   -1,  NULL,  (ios::fmtflags) 0 },
    296  1.1.1.1.2.1  yamt     { "123 /456",    3, "123",  ios::skipws },
    297  1.1.1.1.2.1  yamt     { "123/ 456",    4,  NULL,  ios::skipws },
    298          1.1   mrg   };
    299          1.1   mrg 
    300          1.1   mrg   mpq_t      got, want;
    301  1.1.1.1.2.1  yamt   bool       got_ok, want_ok;
    302  1.1.1.1.2.1  yamt   bool       got_eof, want_eof;
    303          1.1   mrg   long       got_si, want_si;
    304          1.1   mrg   streampos  init_tellg, got_pos, want_pos;
    305          1.1   mrg 
    306          1.1   mrg   mpq_init (got);
    307          1.1   mrg   mpq_init (want);
    308          1.1   mrg 
    309          1.1   mrg   for (size_t i = 0; i < numberof (data); i++)
    310          1.1   mrg     {
    311  1.1.1.1.2.1  yamt       size_t input_length = strlen (data[i].input);
    312          1.1   mrg       want_pos = (data[i].want_pos == -1
    313  1.1.1.1.2.1  yamt                   ? input_length : data[i].want_pos);
    314  1.1.1.1.2.1  yamt       want_eof = (want_pos == streampos(input_length));
    315          1.1   mrg 
    316          1.1   mrg       want_ok = (data[i].want != NULL);
    317          1.1   mrg 
    318          1.1   mrg       if (data[i].want != NULL)
    319          1.1   mrg         mpq_set_str_or_abort (want, data[i].want, 0);
    320          1.1   mrg       else
    321          1.1   mrg         mpq_set_ui (want, 0L, 1L);
    322          1.1   mrg 
    323          1.1   mrg       if (option_check_standard
    324          1.1   mrg           && mpz_fits_slong_p (mpq_numref(want))
    325  1.1.1.1.2.1  yamt           && mpz_cmp_ui (mpq_denref(want), 1L) == 0
    326  1.1.1.1.2.1  yamt           && strchr (data[i].input, '/') == NULL)
    327          1.1   mrg         {
    328          1.1   mrg           istringstream  input (data[i].input);
    329          1.1   mrg           input.flags (data[i].flags);
    330          1.1   mrg           init_tellg = input.tellg();
    331          1.1   mrg           want_si = mpz_get_si (mpq_numref(want));
    332          1.1   mrg 
    333          1.1   mrg           input >> got_si;
    334  1.1.1.1.2.1  yamt           got_ok = !input.fail();
    335  1.1.1.1.2.1  yamt           got_eof = input.eof();
    336          1.1   mrg           input.clear();
    337          1.1   mrg           got_pos = input.tellg() - init_tellg;
    338          1.1   mrg 
    339          1.1   mrg           if (got_ok != want_ok)
    340          1.1   mrg             {
    341          1.1   mrg               WRONG ("stdc++ operator>> wrong status, check_mpq");
    342          1.1   mrg               cout << "  want_ok: " << want_ok << "\n";
    343          1.1   mrg               cout << "  got_ok:  " << got_ok << "\n";
    344          1.1   mrg             }
    345          1.1   mrg           if (want_ok && want_si != got_si)
    346          1.1   mrg             {
    347          1.1   mrg               WRONG ("stdc++ operator>> wrong result, check_mpq");
    348          1.1   mrg               cout << "  got_si:  " << got_si << "\n";
    349          1.1   mrg               cout << "  want_si: " << want_si << "\n";
    350          1.1   mrg             }
    351  1.1.1.1.2.1  yamt           if (want_ok && got_eof != want_eof)
    352  1.1.1.1.2.1  yamt             {
    353  1.1.1.1.2.1  yamt               WRONG ("stdc++ operator>> wrong EOF state, check_mpq");
    354  1.1.1.1.2.1  yamt               cout << "  got_eof:  " << got_eof << "\n";
    355  1.1.1.1.2.1  yamt               cout << "  want_eof: " << want_eof << "\n";
    356  1.1.1.1.2.1  yamt             }
    357          1.1   mrg           if (putback_tellg_works && got_pos != want_pos)
    358          1.1   mrg             {
    359          1.1   mrg               WRONG ("stdc++ operator>> wrong position, check_mpq");
    360          1.1   mrg               cout << "  want_pos: " << want_pos << "\n";
    361          1.1   mrg               cout << "  got_pos:  " << got_pos << "\n";
    362          1.1   mrg             }
    363          1.1   mrg         }
    364          1.1   mrg 
    365          1.1   mrg       {
    366          1.1   mrg         istringstream  input (data[i].input);
    367          1.1   mrg         input.flags (data[i].flags);
    368          1.1   mrg         init_tellg = input.tellg();
    369          1.1   mrg         mpq_set_si (got, 0xDEAD, 0xBEEF);
    370          1.1   mrg 
    371          1.1   mrg         input >> got;
    372  1.1.1.1.2.1  yamt         got_ok = !input.fail();
    373  1.1.1.1.2.1  yamt 	got_eof = input.eof();
    374          1.1   mrg         input.clear();
    375          1.1   mrg         got_pos = input.tellg() - init_tellg;
    376          1.1   mrg 
    377          1.1   mrg         if (got_ok != want_ok)
    378          1.1   mrg           {
    379          1.1   mrg             WRONG ("mpq operator>> wrong status");
    380          1.1   mrg             cout << "  want_ok: " << want_ok << "\n";
    381          1.1   mrg             cout << "  got_ok:  " << got_ok << "\n";
    382          1.1   mrg             abort ();
    383          1.1   mrg           }
    384          1.1   mrg         // don't use mpq_equal, since we allow non-normalized values to be
    385          1.1   mrg         // read, which can trigger ASSERTs in mpq_equal
    386          1.1   mrg         if (want_ok && (mpz_cmp (mpq_numref (got), mpq_numref(want)) != 0
    387          1.1   mrg                         || mpz_cmp (mpq_denref (got), mpq_denref(want)) != 0))
    388          1.1   mrg           {
    389          1.1   mrg             WRONG ("mpq operator>> wrong result");
    390          1.1   mrg             mpq_trace ("  got ", got);
    391          1.1   mrg             mpq_trace ("  want", want);
    392          1.1   mrg             abort ();
    393          1.1   mrg           }
    394  1.1.1.1.2.1  yamt         if (want_ok && got_eof != want_eof)
    395  1.1.1.1.2.1  yamt           {
    396  1.1.1.1.2.1  yamt             WRONG ("mpq operator>> wrong EOF state");
    397  1.1.1.1.2.1  yamt             cout << "  want_eof: " << want_eof << "\n";
    398  1.1.1.1.2.1  yamt             cout << "  got_eof:  " << got_eof << "\n";
    399  1.1.1.1.2.1  yamt             abort ();
    400  1.1.1.1.2.1  yamt           }
    401          1.1   mrg         if (putback_tellg_works && got_pos != want_pos)
    402          1.1   mrg           {
    403          1.1   mrg             WRONG ("mpq operator>> wrong position");
    404          1.1   mrg             cout << "  want_pos: " << want_pos << "\n";
    405          1.1   mrg             cout << "  got_pos:  " << got_pos << "\n";
    406          1.1   mrg             abort ();
    407          1.1   mrg           }
    408          1.1   mrg       }
    409          1.1   mrg     }
    410          1.1   mrg 
    411          1.1   mrg   mpq_clear (got);
    412          1.1   mrg   mpq_clear (want);
    413          1.1   mrg }
    414          1.1   mrg 
    415          1.1   mrg 
    416          1.1   mrg void
    417          1.1   mrg check_mpf (void)
    418          1.1   mrg {
    419          1.1   mrg   static const struct {
    420          1.1   mrg     const char     *input;
    421          1.1   mrg     int            want_pos;
    422          1.1   mrg     const char     *want;
    423          1.1   mrg     ios::fmtflags  flags;
    424          1.1   mrg 
    425          1.1   mrg   } data[] = {
    426          1.1   mrg 
    427          1.1   mrg     { "0",      -1, "0", (ios::fmtflags) 0 },
    428          1.1   mrg     { "+0",     -1, "0", (ios::fmtflags) 0 },
    429          1.1   mrg     { "-0",     -1, "0", (ios::fmtflags) 0 },
    430          1.1   mrg     { "0.0",    -1, "0", (ios::fmtflags) 0 },
    431          1.1   mrg     { "0.",     -1, "0", (ios::fmtflags) 0 },
    432          1.1   mrg     { ".0",     -1, "0", (ios::fmtflags) 0 },
    433          1.1   mrg     { "+.0",    -1, "0", (ios::fmtflags) 0 },
    434          1.1   mrg     { "-.0",    -1, "0", (ios::fmtflags) 0 },
    435          1.1   mrg     { "+0.00",  -1, "0", (ios::fmtflags) 0 },
    436          1.1   mrg     { "-0.000", -1, "0", (ios::fmtflags) 0 },
    437          1.1   mrg     { "+0.00",  -1, "0", (ios::fmtflags) 0 },
    438          1.1   mrg     { "-0.000", -1, "0", (ios::fmtflags) 0 },
    439          1.1   mrg     { "0.0e0",  -1, "0", (ios::fmtflags) 0 },
    440          1.1   mrg     { "0.e0",   -1, "0", (ios::fmtflags) 0 },
    441          1.1   mrg     { ".0e0",   -1, "0", (ios::fmtflags) 0 },
    442          1.1   mrg     { "0.0e-0", -1, "0", (ios::fmtflags) 0 },
    443          1.1   mrg     { "0.e-0",  -1, "0", (ios::fmtflags) 0 },
    444          1.1   mrg     { ".0e-0",  -1, "0", (ios::fmtflags) 0 },
    445          1.1   mrg     { "0.0e+0", -1, "0", (ios::fmtflags) 0 },
    446          1.1   mrg     { "0.e+0",  -1, "0", (ios::fmtflags) 0 },
    447          1.1   mrg     { ".0e+0",  -1, "0", (ios::fmtflags) 0 },
    448          1.1   mrg 
    449          1.1   mrg     { "1",  -1,  "1", (ios::fmtflags) 0 },
    450          1.1   mrg     { "+1", -1,  "1", (ios::fmtflags) 0 },
    451          1.1   mrg     { "-1", -1, "-1", (ios::fmtflags) 0 },
    452          1.1   mrg 
    453          1.1   mrg     { " 0",  0,  NULL, (ios::fmtflags) 0 },  // not without skipws
    454          1.1   mrg     { " 0",  -1, "0", ios::skipws },
    455          1.1   mrg     { " +0", -1, "0", ios::skipws },
    456          1.1   mrg     { " -0", -1, "0", ios::skipws },
    457          1.1   mrg 
    458          1.1   mrg     { "+-123", 1, NULL, (ios::fmtflags) 0 },
    459          1.1   mrg     { "-+123", 1, NULL, (ios::fmtflags) 0 },
    460          1.1   mrg     { "1e+-123", 3, NULL, (ios::fmtflags) 0 },
    461          1.1   mrg     { "1e-+123", 3, NULL, (ios::fmtflags) 0 },
    462          1.1   mrg 
    463          1.1   mrg     { "e123",   0, NULL, (ios::fmtflags) 0 }, // at least one mantissa digit
    464          1.1   mrg     { ".e123",  1, NULL, (ios::fmtflags) 0 },
    465          1.1   mrg     { "+.e123", 2, NULL, (ios::fmtflags) 0 },
    466          1.1   mrg     { "-.e123", 2, NULL, (ios::fmtflags) 0 },
    467          1.1   mrg 
    468          1.1   mrg     { "123e",   4, NULL, (ios::fmtflags) 0 }, // at least one exponent digit
    469          1.1   mrg     { "123e-",  5, NULL, (ios::fmtflags) 0 },
    470          1.1   mrg     { "123e+",  5, NULL, (ios::fmtflags) 0 },
    471          1.1   mrg   };
    472          1.1   mrg 
    473          1.1   mrg   mpf_t      got, want;
    474  1.1.1.1.2.1  yamt   bool       got_ok, want_ok;
    475  1.1.1.1.2.1  yamt   bool       got_eof, want_eof;
    476          1.1   mrg   double     got_d, want_d;
    477          1.1   mrg   streampos  init_tellg, got_pos, want_pos;
    478          1.1   mrg 
    479          1.1   mrg   mpf_init (got);
    480          1.1   mrg   mpf_init (want);
    481          1.1   mrg 
    482          1.1   mrg   for (size_t i = 0; i < numberof (data); i++)
    483          1.1   mrg     {
    484  1.1.1.1.2.1  yamt       size_t input_length = strlen (data[i].input);
    485          1.1   mrg       want_pos = (data[i].want_pos == -1
    486  1.1.1.1.2.1  yamt                   ? input_length : data[i].want_pos);
    487  1.1.1.1.2.1  yamt       want_eof = (want_pos == streampos(input_length));
    488          1.1   mrg 
    489          1.1   mrg       want_ok = (data[i].want != NULL);
    490          1.1   mrg 
    491          1.1   mrg       if (data[i].want != NULL)
    492          1.1   mrg         mpf_set_str_or_abort (want, data[i].want, 0);
    493          1.1   mrg       else
    494          1.1   mrg         mpf_set_ui (want, 0L);
    495          1.1   mrg 
    496          1.1   mrg       want_d = mpf_get_d (want);
    497          1.1   mrg       if (option_check_standard && mpf_cmp_d (want, want_d) == 0)
    498          1.1   mrg         {
    499          1.1   mrg           istringstream  input (data[i].input);
    500          1.1   mrg           input.flags (data[i].flags);
    501          1.1   mrg           init_tellg = input.tellg();
    502          1.1   mrg 
    503          1.1   mrg           input >> got_d;
    504  1.1.1.1.2.1  yamt           got_ok = !input.fail();
    505  1.1.1.1.2.1  yamt           got_eof = input.eof();
    506          1.1   mrg           input.clear();
    507          1.1   mrg           got_pos = input.tellg() - init_tellg;
    508          1.1   mrg 
    509          1.1   mrg           if (got_ok != want_ok)
    510          1.1   mrg             {
    511          1.1   mrg               WRONG ("stdc++ operator>> wrong status, check_mpf");
    512          1.1   mrg               cout << "  want_ok: " << want_ok << "\n";
    513          1.1   mrg               cout << "  got_ok:  " << got_ok << "\n";
    514          1.1   mrg             }
    515          1.1   mrg           if (want_ok && want_d != got_d)
    516          1.1   mrg             {
    517          1.1   mrg               WRONG ("stdc++ operator>> wrong result, check_mpf");
    518          1.1   mrg               cout << "  got:   " << got_d << "\n";
    519          1.1   mrg               cout << "  want:  " << want_d << "\n";
    520          1.1   mrg             }
    521  1.1.1.1.2.1  yamt           if (want_ok && got_eof != want_eof)
    522  1.1.1.1.2.1  yamt             {
    523  1.1.1.1.2.1  yamt               WRONG ("stdc++ operator>> wrong EOF state, check_mpf");
    524  1.1.1.1.2.1  yamt               cout << "  got_eof:  " << got_eof << "\n";
    525  1.1.1.1.2.1  yamt               cout << "  want_eof: " << want_eof << "\n";
    526  1.1.1.1.2.1  yamt             }
    527          1.1   mrg           if (putback_tellg_works && got_pos != want_pos)
    528          1.1   mrg             {
    529          1.1   mrg               WRONG ("stdc++ operator>> wrong position, check_mpf");
    530          1.1   mrg               cout << "  want_pos: " << want_pos << "\n";
    531          1.1   mrg               cout << "  got_pos:  " << got_pos << "\n";
    532          1.1   mrg             }
    533          1.1   mrg         }
    534          1.1   mrg 
    535          1.1   mrg       {
    536          1.1   mrg         istringstream  input (data[i].input);
    537          1.1   mrg         input.flags (data[i].flags);
    538          1.1   mrg         init_tellg = input.tellg();
    539          1.1   mrg 
    540          1.1   mrg         mpf_set_ui (got, 0xDEAD);
    541          1.1   mrg         input >> got;
    542  1.1.1.1.2.1  yamt         got_ok = !input.fail();
    543  1.1.1.1.2.1  yamt 	got_eof = input.eof();
    544          1.1   mrg         input.clear();
    545          1.1   mrg         got_pos = input.tellg() - init_tellg;
    546          1.1   mrg 
    547          1.1   mrg         if (got_ok != want_ok)
    548          1.1   mrg           {
    549          1.1   mrg             WRONG ("mpf operator>> wrong status");
    550          1.1   mrg             cout << "  want_ok: " << want_ok << "\n";
    551          1.1   mrg             cout << "  got_ok:  " << got_ok << "\n";
    552          1.1   mrg             abort ();
    553          1.1   mrg           }
    554          1.1   mrg         if (want_ok && mpf_cmp (got, want) != 0)
    555          1.1   mrg           {
    556          1.1   mrg             WRONG ("mpf operator>> wrong result");
    557          1.1   mrg             mpf_trace ("  got ", got);
    558          1.1   mrg             mpf_trace ("  want", want);
    559          1.1   mrg             abort ();
    560          1.1   mrg           }
    561  1.1.1.1.2.1  yamt         if (want_ok && got_eof != want_eof)
    562  1.1.1.1.2.1  yamt           {
    563  1.1.1.1.2.1  yamt             WRONG ("mpf operator>> wrong EOF state");
    564  1.1.1.1.2.1  yamt             cout << "  want_eof: " << want_eof << "\n";
    565  1.1.1.1.2.1  yamt             cout << "  got_eof:  " << got_eof << "\n";
    566  1.1.1.1.2.1  yamt             abort ();
    567  1.1.1.1.2.1  yamt           }
    568          1.1   mrg         if (putback_tellg_works && got_pos != want_pos)
    569          1.1   mrg           {
    570          1.1   mrg             WRONG ("mpf operator>> wrong position");
    571          1.1   mrg             cout << "  want_pos: " << want_pos << "\n";
    572          1.1   mrg             cout << "  got_pos:  " << got_pos << "\n";
    573          1.1   mrg             abort ();
    574          1.1   mrg           }
    575          1.1   mrg       }
    576          1.1   mrg     }
    577          1.1   mrg 
    578          1.1   mrg   mpf_clear (got);
    579          1.1   mrg   mpf_clear (want);
    580          1.1   mrg }
    581          1.1   mrg 
    582          1.1   mrg 
    583          1.1   mrg 
    584          1.1   mrg int
    585          1.1   mrg main (int argc, char *argv[])
    586          1.1   mrg {
    587          1.1   mrg   if (argc > 1 && strcmp (argv[1], "-s") == 0)
    588  1.1.1.1.2.1  yamt     option_check_standard = true;
    589          1.1   mrg 
    590          1.1   mrg   tests_start ();
    591          1.1   mrg 
    592          1.1   mrg   check_putback_tellg ();
    593          1.1   mrg   check_mpz ();
    594          1.1   mrg   check_mpq ();
    595          1.1   mrg   check_mpf ();
    596          1.1   mrg 
    597          1.1   mrg   tests_end ();
    598          1.1   mrg   return 0;
    599          1.1   mrg }
    600