Home | History | Annotate | Line # | Download | only in tests
      1 /* tio_str-- Test file for mpc_inp_str and mpc_out_str.
      2 
      3 Copyright (C) 2009, 2011, 2013, 2014 INRIA
      4 
      5 This file is part of GNU MPC.
      6 
      7 GNU MPC is free software; you can redistribute it and/or modify it under
      8 the terms of the GNU Lesser General Public License as published by the
      9 Free Software Foundation; either version 3 of the License, or (at your
     10 option) any later version.
     11 
     12 GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
     13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
     15 more details.
     16 
     17 You should have received a copy of the GNU Lesser General Public License
     18 along with this program. If not, see http://www.gnu.org/licenses/ .
     19 */
     20 
     21 #include "mpc-tests.h"
     22 
     23 #ifdef HAVE_UNISTD_H
     24 #ifndef _POSIX_C_SOURCE
     25 #define _POSIX_C_SOURCE 1 /* apparently needed on Darwin */
     26 #endif
     27 #include <unistd.h> /* for dup, dup2, STDIN_FILENO and STDOUT_FILENO */
     28 #else
     29 #define STDIN_FILENO 0
     30 #define STDOUT_FILENO 1
     31 #endif
     32 
     33 extern unsigned long line_number;
     34 /* character appearing next in the file, may be EOF */
     35 extern int nextchar;
     36 extern const char *mpc_rnd_mode[];
     37 
     38 static void
     39 check_file (const char* file_name)
     40 {
     41   FILE *fp;
     42 
     43   int tmp;
     44   int base;
     45   int inex_re;
     46   int inex_im;
     47   mpc_t expected, got;
     48   mpc_rnd_t rnd = MPC_RNDNN;
     49   int inex = 0, expected_inex;
     50   size_t expected_size, size;
     51   known_signs_t ks = {1, 1};
     52 
     53   fp = open_data_file (file_name);
     54 
     55   mpc_init2 (expected, 53);
     56   mpc_init2 (got, 53);
     57 
     58   /* read data file */
     59   line_number = 1;
     60   nextchar = getc (fp);
     61   skip_whitespace_comments (fp);
     62 
     63   while (nextchar != EOF)
     64     {
     65       /* 1. read a line of data: expected result, base, rounding mode */
     66       read_ternary (fp, &inex_re);
     67       read_ternary (fp, &inex_im);
     68       read_mpc (fp, expected, &ks);
     69       if (inex_re == TERNARY_ERROR || inex_im == TERNARY_ERROR)
     70          expected_inex = -1;
     71       else
     72          expected_inex = MPC_INEX (inex_re, inex_im);
     73       read_int (fp, &tmp, "size");
     74       expected_size = (size_t)tmp;
     75       read_int (fp, &base, "base");
     76       read_mpc_rounding_mode (fp, &rnd);
     77 
     78       /* 2. read string at the same precision as the expected result */
     79       while (nextchar != '"')
     80         nextchar = getc (fp);
     81       mpfr_set_prec (mpc_realref (got), MPC_PREC_RE (expected));
     82       mpfr_set_prec (mpc_imagref (got), MPC_PREC_IM (expected));
     83       inex = mpc_inp_str (got, fp, &size, base, rnd);
     84 
     85       /* 3. compare this result with the expected one */
     86       if (inex != expected_inex || !same_mpc_value (got, expected, ks)
     87           || size != expected_size)
     88         {
     89           printf ("mpc_inp_str failed (line %lu) with rounding mode %s\n",
     90                   line_number, mpc_rnd_mode[rnd]);
     91           if (inex != expected_inex)
     92             printf("     got inexact value: %d\nexpected inexact value: %d\n",
     93                    inex, expected_inex);
     94           if (size !=  expected_size)
     95             printf ("     got size: %lu\nexpected size: %lu\n     ",
     96                     (unsigned long int) size, (unsigned long int) expected_size);
     97           printf ("    ");
     98           MPC_OUT (got);
     99           MPC_OUT (expected);
    100 
    101           exit (1);
    102         }
    103 
    104       while ((nextchar = getc (fp)) != '"');
    105       nextchar = getc (fp);
    106 
    107       skip_whitespace_comments (fp);
    108     }
    109 
    110   mpc_clear (expected);
    111   mpc_clear (got);
    112   close_data_file (fp);
    113 }
    114 
    115 static void
    116 check_io_str (mpc_ptr read_number, mpc_ptr expected)
    117 {
    118   char tmp_file[] = "mpc_test";
    119   FILE *fp;
    120   size_t sz;
    121 
    122   if (!(fp = fopen (tmp_file, "w")))
    123     {
    124       printf ("Error: Could not open file %s in write mode\n", tmp_file);
    125       exit (1);
    126     }
    127 
    128   mpc_out_str (fp, 10, 0, expected, MPC_RNDNN);
    129   fclose (fp);
    130 
    131   if (!(fp = fopen (tmp_file, "r")))
    132     {
    133       printf ("Error: Could not open file %s in read mode\n", tmp_file);
    134       exit (1);
    135     };
    136   if (mpc_inp_str (read_number, fp, &sz, 10, MPC_RNDNN) == -1)
    137     {
    138       printf ("Error: mpc_inp_str cannot correctly re-read number "
    139               "in file %s\n", tmp_file);
    140 
    141       exit (1);
    142     }
    143   fclose (fp);
    144 
    145   /* mpc_cmp set erange flag when an operand is a NaN */
    146   mpfr_clear_flags ();
    147   if (mpc_cmp (read_number, expected) != 0 || mpfr_erangeflag_p())
    148     {
    149       printf ("Error: inp_str o out_str <> Id\n");
    150       MPC_OUT (read_number);
    151       MPC_OUT (expected);
    152 
    153       exit (1);
    154     }
    155 }
    156 
    157 #ifndef MPC_NO_STREAM_REDIRECTION
    158 /* test out_str with stream=NULL */
    159 static void
    160 check_stdout (mpc_ptr read_number, mpc_ptr expected)
    161 {
    162   char tmp_file[] = "mpc_test";
    163   int fd;
    164   size_t sz;
    165 
    166   fflush (stdout);
    167   fd = dup (STDOUT_FILENO);
    168   if (freopen (tmp_file, "w", stdout) == NULL)
    169   {
    170      printf ("mpc_inp_str cannot redirect stdout\n");
    171      exit (1);
    172   }
    173   mpc_out_str (NULL, 2, 0, expected, MPC_RNDNN);
    174   fflush (stdout);
    175   dup2 (fd, STDOUT_FILENO);
    176   close (fd);
    177   clearerr (stdout);
    178 
    179   fflush (stdin);
    180   fd = dup (STDIN_FILENO);
    181   if (freopen (tmp_file, "r", stdin) == NULL)
    182   {
    183      printf ("mpc_inp_str cannot redirect stdout\n");
    184      exit (1);
    185   }
    186   if (mpc_inp_str (read_number, NULL, &sz, 2, MPC_RNDNN) == -1)
    187     {
    188       printf ("mpc_inp_str cannot correctly re-read number "
    189               "in file %s\n", tmp_file);
    190       exit (1);
    191     }
    192   mpfr_clear_flags (); /* mpc_cmp set erange flag when an operand is
    193                           a NaN */
    194   if (mpc_cmp (read_number, expected) != 0 || mpfr_erangeflag_p())
    195     {
    196       printf ("mpc_inp_str did not read the number which was written by "
    197               "mpc_out_str\n");
    198       MPC_OUT (read_number);
    199       MPC_OUT (expected);
    200       exit (1);
    201     }
    202   fflush (stdin);
    203   dup2 (fd, STDIN_FILENO);
    204   close (fd);
    205   clearerr (stdin);
    206 }
    207 #endif /* MPC_NO_STREAM_REDIRECTION */
    208 
    209 int
    210 main (void)
    211 {
    212   mpc_t z, x;
    213   mpfr_prec_t prec;
    214 
    215   test_start ();
    216 
    217   mpc_init2 (z, 1000);
    218   mpc_init2 (x, 1000);
    219 
    220   check_file ("inp_str.dat");
    221 
    222   for (prec = 2; prec <= 1000; prec+=7)
    223     {
    224       mpc_set_prec (z, prec);
    225       mpc_set_prec (x, prec);
    226 
    227       mpc_set_si_si (x, 1, 1, MPC_RNDNN);
    228       check_io_str (z, x);
    229 
    230       mpc_set_si_si (x, -1, 1, MPC_RNDNN);
    231       check_io_str (z, x);
    232 
    233       mpfr_set_inf (mpc_realref(x), -1);
    234       mpfr_set_inf (mpc_imagref(x), +1);
    235       check_io_str (z, x);
    236 
    237       test_default_random (x,  -1024, 1024, 128, 25);
    238       check_io_str (z, x);
    239     }
    240 
    241 #ifndef MPC_NO_STREAM_REDIRECTION
    242   mpc_set_si_si (x, 1, -4, MPC_RNDNN);
    243   mpc_div_ui (x, x, 3, MPC_RNDDU);
    244 
    245   check_stdout(z, x);
    246 #endif
    247 
    248   mpc_clear (z);
    249   mpc_clear (x);
    250 
    251   test_end ();
    252 
    253   return 0;
    254 }
    255