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