github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-io_raw.c (about)

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