Home | History | Annotate | Line # | Download | only in mpz
      1      1.1  mrg /* Test mpz_inp_raw and mpz_out_raw.
      2      1.1  mrg 
      3      1.1  mrg Copyright 2001 Free Software Foundation, Inc.
      4      1.1  mrg 
      5  1.1.1.2  mrg This file is part of the GNU MP Library test suite.
      6      1.1  mrg 
      7  1.1.1.2  mrg The GNU MP Library test suite is free software; you can redistribute it
      8  1.1.1.2  mrg and/or modify it under the terms of the GNU General Public License as
      9  1.1.1.2  mrg published by the Free Software Foundation; either version 3 of the License,
     10  1.1.1.2  mrg or (at your option) any later version.
     11  1.1.1.2  mrg 
     12  1.1.1.2  mrg The GNU MP Library test suite is distributed in the hope that it will be
     13  1.1.1.2  mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1.1.2  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     15  1.1.1.2  mrg Public License for more details.
     16      1.1  mrg 
     17  1.1.1.2  mrg You should have received a copy of the GNU General Public License along with
     18  1.1.1.3  mrg the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
     19      1.1  mrg 
     20      1.1  mrg #include "config.h"
     21      1.1  mrg 
     22      1.1  mrg #include <stdio.h>
     23      1.1  mrg #include <stdlib.h>
     24      1.1  mrg #include <string.h>
     25      1.1  mrg #if HAVE_UNISTD_H
     26      1.1  mrg #include <unistd.h>
     27      1.1  mrg #endif
     28      1.1  mrg 
     29      1.1  mrg #include "gmp-impl.h"
     30      1.1  mrg #include "tests.h"
     31      1.1  mrg 
     32      1.1  mrg #define FILENAME  "t-io_raw.tmp"
     33      1.1  mrg 
     34      1.1  mrg 
     35      1.1  mrg /* In the fopen, "b" selects binary mode on DOS systems, meaning no
     36      1.1  mrg    conversion of '\n' to and from CRLF.  It's believed systems without such
     37      1.1  mrg    nonsense will simply ignore the "b", but in case that's not so a plain
     38      1.1  mrg    "w+" is attempted if "w+b" fails.  */
     39      1.1  mrg 
     40      1.1  mrg FILE *
     41      1.1  mrg fopen_wplusb_or_die (const char *filename)
     42      1.1  mrg {
     43      1.1  mrg   FILE  *fp;
     44      1.1  mrg   fp = fopen (filename, "w+b");
     45      1.1  mrg   if (fp == NULL)
     46      1.1  mrg     fp = fopen (filename, "w+");
     47      1.1  mrg 
     48      1.1  mrg   if (fp == NULL)
     49      1.1  mrg     {
     50      1.1  mrg       printf ("Cannot create file %s\n", filename);
     51      1.1  mrg       abort ();
     52      1.1  mrg     }
     53      1.1  mrg   return fp;
     54      1.1  mrg }
     55      1.1  mrg 
     56      1.1  mrg /* use 0x80 to check nothing bad happens with sign extension etc */
     57      1.1  mrg #define BYTEVAL(i)  (((i) + 1) | 0x80)
     58      1.1  mrg 
     59      1.1  mrg void
     60      1.1  mrg check_in (void)
     61      1.1  mrg {
     62      1.1  mrg   int        i, j, zeros, neg, error = 0;
     63      1.1  mrg   mpz_t      want, got;
     64      1.1  mrg   size_t     want_ret, got_ret;
     65      1.1  mrg   mp_size_t  size;
     66      1.1  mrg   FILE       *fp;
     67      1.1  mrg 
     68      1.1  mrg   mpz_init (want);
     69      1.1  mrg   mpz_init (got);
     70      1.1  mrg 
     71      1.1  mrg   for (i = 0; i < 32; i++)
     72      1.1  mrg     {
     73      1.1  mrg       for (zeros = 0; zeros < 8; zeros++)
     74      1.1  mrg 	{
     75      1.1  mrg 	  for (neg = 0; neg <= 1; neg++)
     76      1.1  mrg 	    {
     77      1.1  mrg 	      want_ret = i + zeros + 4;
     78      1.1  mrg 
     79      1.1  mrg 	      /* need this to get the twos complement right */
     80      1.1  mrg 	      ASSERT_ALWAYS (sizeof (size) >= 4);
     81      1.1  mrg 
     82      1.1  mrg 	      size = i + zeros;
     83      1.1  mrg 	      if (neg)
     84      1.1  mrg 		size = -size;
     85      1.1  mrg 
     86      1.1  mrg 	      fp = fopen_wplusb_or_die (FILENAME);
     87      1.1  mrg 	      for (j = 3; j >= 0; j--)
     88      1.1  mrg 		ASSERT_ALWAYS (putc ((size >> (j*8)) & 0xFF, fp) != EOF);
     89      1.1  mrg 	      for (j = 0; j < zeros; j++)
     90      1.1  mrg 		ASSERT_ALWAYS (putc ('\0', fp) != EOF);
     91      1.1  mrg 	      for (j = 0; j < i; j++)
     92      1.1  mrg 		ASSERT_ALWAYS (putc (BYTEVAL (j), fp) != EOF);
     93      1.1  mrg 	      /* and some trailing garbage */
     94      1.1  mrg 	      ASSERT_ALWAYS (putc ('x', fp) != EOF);
     95      1.1  mrg 	      ASSERT_ALWAYS (putc ('y', fp) != EOF);
     96      1.1  mrg 	      ASSERT_ALWAYS (putc ('z', fp) != EOF);
     97      1.1  mrg 	      ASSERT_ALWAYS (fflush (fp) == 0);
     98      1.1  mrg 	      rewind (fp);
     99      1.1  mrg 
    100      1.1  mrg 	      got_ret = mpz_inp_raw (got, fp);
    101      1.1  mrg 	      ASSERT_ALWAYS (! ferror(fp));
    102      1.1  mrg 	      ASSERT_ALWAYS (fclose (fp) == 0);
    103      1.1  mrg 
    104      1.1  mrg 	      MPZ_CHECK_FORMAT (got);
    105      1.1  mrg 
    106      1.1  mrg 	      if (got_ret != want_ret)
    107      1.1  mrg 		{
    108      1.1  mrg 		  printf ("check_in: return value wrong\n");
    109      1.1  mrg 		  error = 1;
    110      1.1  mrg 		}
    111      1.1  mrg 	      if (mpz_cmp (got, want) != 0)
    112      1.1  mrg 		{
    113      1.1  mrg 		  printf ("check_in: result wrong\n");
    114      1.1  mrg 		  error = 1;
    115      1.1  mrg 		}
    116      1.1  mrg 	      if (error)
    117      1.1  mrg 		{
    118      1.1  mrg 		  printf    ("  i=%d zeros=%d neg=%d\n", i, zeros, neg);
    119      1.1  mrg 		  printf    ("  got_ret  %lu\n", (unsigned long) got_ret);
    120      1.1  mrg 		  printf    ("  want_ret %lu\n", (unsigned long) want_ret);
    121      1.1  mrg 		  mpz_trace ("  got      ", got);
    122      1.1  mrg 		  mpz_trace ("  want     ", want);
    123      1.1  mrg 		  abort ();
    124      1.1  mrg 		}
    125      1.1  mrg 
    126      1.1  mrg 	      mpz_neg (want, want);
    127      1.1  mrg 	    }
    128      1.1  mrg 	}
    129      1.1  mrg       mpz_mul_2exp (want, want, 8);
    130      1.1  mrg       mpz_add_ui (want, want, (unsigned long) BYTEVAL (i));
    131      1.1  mrg     }
    132      1.1  mrg 
    133      1.1  mrg   mpz_clear (want);
    134      1.1  mrg   mpz_clear (got);
    135      1.1  mrg }
    136      1.1  mrg 
    137      1.1  mrg 
    138      1.1  mrg void
    139      1.1  mrg check_out (void)
    140      1.1  mrg {
    141      1.1  mrg   int        i, j, neg, error = 0;
    142      1.1  mrg   mpz_t      z;
    143      1.1  mrg   char       want[256], got[256], *p;
    144      1.1  mrg   size_t     want_len, got_ret, got_read;
    145      1.1  mrg   mp_size_t  size;
    146      1.1  mrg   FILE       *fp;
    147      1.1  mrg 
    148      1.1  mrg   mpz_init (z);
    149      1.1  mrg 
    150      1.1  mrg   for (i = 0; i < 32; i++)
    151      1.1  mrg     {
    152      1.1  mrg       for (neg = 0; neg <= 1; neg++)
    153      1.1  mrg 	{
    154      1.1  mrg 	  want_len = i + 4;
    155      1.1  mrg 
    156      1.1  mrg 	  /* need this to get the twos complement right */
    157      1.1  mrg 	  ASSERT_ALWAYS (sizeof (size) >= 4);
    158      1.1  mrg 
    159      1.1  mrg 	  size = i;
    160      1.1  mrg 	  if (neg)
    161      1.1  mrg 	    size = -size;
    162      1.1  mrg 
    163      1.1  mrg 	  p = want;
    164      1.1  mrg 	  for (j = 3; j >= 0; j--)
    165      1.1  mrg 	    *p++ = size >> (j*8);
    166      1.1  mrg 	  for (j = 0; j < i; j++)
    167      1.1  mrg 	    *p++ = BYTEVAL (j);
    168      1.1  mrg 	  ASSERT_ALWAYS (p <= want + sizeof (want));
    169      1.1  mrg 
    170      1.1  mrg 	  fp = fopen_wplusb_or_die (FILENAME);
    171      1.1  mrg 	  got_ret = mpz_out_raw (fp, z);
    172      1.1  mrg 	  ASSERT_ALWAYS (fflush (fp) == 0);
    173      1.1  mrg 	  rewind (fp);
    174      1.1  mrg 	  got_read = fread (got, 1, sizeof(got), fp);
    175      1.1  mrg 	  ASSERT_ALWAYS (! ferror(fp));
    176      1.1  mrg 	  ASSERT_ALWAYS (fclose (fp) == 0);
    177      1.1  mrg 
    178      1.1  mrg 	  if (got_ret != want_len)
    179      1.1  mrg 	    {
    180      1.1  mrg 	      printf ("check_out: wrong return value\n");
    181      1.1  mrg 	      error = 1;
    182      1.1  mrg 	    }
    183      1.1  mrg 	  if (got_read != want_len)
    184      1.1  mrg 	    {
    185      1.1  mrg 	      printf ("check_out: wrong number of bytes read back\n");
    186      1.1  mrg 	      error = 1;
    187      1.1  mrg 	    }
    188      1.1  mrg 	  if (memcmp (want, got, want_len) != 0)
    189      1.1  mrg 	    {
    190      1.1  mrg 	      printf ("check_out: wrong data\n");
    191      1.1  mrg 	      error = 1;
    192      1.1  mrg 	    }
    193      1.1  mrg 	  if (error)
    194      1.1  mrg 	    {
    195      1.1  mrg 	      printf    ("  i=%d neg=%d\n", i, neg);
    196      1.1  mrg 	      mpz_trace ("  z", z);
    197      1.1  mrg 	      printf    ("  got_ret  %lu\n", (unsigned long) got_ret);
    198      1.1  mrg 	      printf    ("  got_read %lu\n", (unsigned long) got_read);
    199      1.1  mrg 	      printf    ("  want_len %lu\n", (unsigned long) want_len);
    200      1.1  mrg 	      printf    ("  want");
    201      1.1  mrg 	      for (j = 0; j < want_len; j++)
    202      1.1  mrg 		printf (" %02X", (unsigned) (unsigned char) want[j]);
    203      1.1  mrg 	      printf    ("\n");
    204      1.1  mrg 	      printf    ("  got ");
    205      1.1  mrg 	      for (j = 0; j < want_len; j++)
    206      1.1  mrg 		printf (" %02X", (unsigned) (unsigned char) got[j]);
    207      1.1  mrg 	      printf    ("\n");
    208      1.1  mrg 	      abort ();
    209      1.1  mrg 	    }
    210      1.1  mrg 
    211      1.1  mrg 	  mpz_neg (z, z);
    212      1.1  mrg 	}
    213      1.1  mrg       mpz_mul_2exp (z, z, 8);
    214      1.1  mrg       mpz_add_ui (z, z, (unsigned long) BYTEVAL (i));
    215      1.1  mrg     }
    216      1.1  mrg 
    217      1.1  mrg   mpz_clear (z);
    218      1.1  mrg }
    219      1.1  mrg 
    220      1.1  mrg 
    221      1.1  mrg void
    222      1.1  mrg check_rand (void)
    223      1.1  mrg {
    224      1.1  mrg   gmp_randstate_ptr  rands = RANDS;
    225      1.1  mrg   int        i, error = 0;
    226      1.1  mrg   mpz_t      got, want;
    227      1.1  mrg   size_t     inp_ret, out_ret;
    228      1.1  mrg   FILE       *fp;
    229      1.1  mrg 
    230      1.1  mrg   mpz_init (want);
    231      1.1  mrg   mpz_init (got);
    232      1.1  mrg 
    233      1.1  mrg   for (i = 0; i < 500; i++)
    234      1.1  mrg     {
    235      1.1  mrg       mpz_erandomb (want, rands, 10*GMP_LIMB_BITS);
    236      1.1  mrg       mpz_negrandom (want, rands);
    237      1.1  mrg 
    238      1.1  mrg       fp = fopen_wplusb_or_die (FILENAME);
    239      1.1  mrg       out_ret = mpz_out_raw (fp, want);
    240      1.1  mrg       ASSERT_ALWAYS (fflush (fp) == 0);
    241      1.1  mrg       rewind (fp);
    242      1.1  mrg       inp_ret = mpz_inp_raw (got, fp);
    243      1.1  mrg       ASSERT_ALWAYS (fclose (fp) == 0);
    244      1.1  mrg 
    245      1.1  mrg       MPZ_CHECK_FORMAT (got);
    246      1.1  mrg 
    247      1.1  mrg       if (inp_ret != out_ret)
    248      1.1  mrg 	{
    249      1.1  mrg 	  printf ("check_rand: different inp/out return values\n");
    250      1.1  mrg 	  error = 1;
    251      1.1  mrg 	}
    252      1.1  mrg       if (mpz_cmp (got, want) != 0)
    253      1.1  mrg 	{
    254      1.1  mrg 	  printf ("check_rand: wrong result\n");
    255      1.1  mrg 	  error = 1;
    256      1.1  mrg 	}
    257      1.1  mrg       if (error)
    258      1.1  mrg 	{
    259      1.1  mrg 	  printf    ("  out_ret %lu\n", (unsigned long) out_ret);
    260      1.1  mrg 	  printf    ("  inp_ret %lu\n", (unsigned long) inp_ret);
    261      1.1  mrg 	  mpz_trace ("  want", want);
    262      1.1  mrg 	  mpz_trace ("  got ", got);
    263      1.1  mrg 	  abort ();
    264      1.1  mrg 	}
    265      1.1  mrg     }
    266      1.1  mrg 
    267      1.1  mrg   mpz_clear (got);
    268      1.1  mrg   mpz_clear (want);
    269      1.1  mrg }
    270      1.1  mrg 
    271      1.1  mrg 
    272      1.1  mrg int
    273      1.1  mrg main (void)
    274      1.1  mrg {
    275      1.1  mrg   tests_start ();
    276      1.1  mrg   mp_trace_base = -16;
    277      1.1  mrg 
    278      1.1  mrg   check_in ();
    279      1.1  mrg   check_out ();
    280      1.1  mrg   check_rand ();
    281      1.1  mrg 
    282      1.1  mrg   unlink (FILENAME);
    283      1.1  mrg   tests_end ();
    284      1.1  mrg 
    285      1.1  mrg   exit (0);
    286      1.1  mrg }
    287