]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gmp/tests/mpz/t-io_raw.c
Imported gcc-4.4.3
[msp430-gcc.git] / gmp / tests / mpz / t-io_raw.c
diff --git a/gmp/tests/mpz/t-io_raw.c b/gmp/tests/mpz/t-io_raw.c
new file mode 100644 (file)
index 0000000..4fd71e4
--- /dev/null
@@ -0,0 +1,287 @@
+/* Test mpz_inp_raw and mpz_out_raw.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define FILENAME  "t-io_raw.tmp"
+
+
+/* In the fopen, "b" selects binary mode on DOS systems, meaning no
+   conversion of '\n' to and from CRLF.  It's believed systems without such
+   nonsense will simply ignore the "b", but in case that's not so a plain
+   "w+" is attempted if "w+b" fails.  */
+
+FILE *
+fopen_wplusb_or_die (const char *filename)
+{
+  FILE  *fp;
+  fp = fopen (filename, "w+b");
+  if (fp == NULL)
+    fp = fopen (filename, "w+");
+
+  if (fp == NULL)
+    {
+      printf ("Cannot create file %s\n", filename);
+      abort ();
+    }
+  return fp;
+}
+
+/* use 0x80 to check nothing bad happens with sign extension etc */
+#define BYTEVAL(i)  (((i) + 1) | 0x80)
+
+void
+check_in (void)
+{
+  int        i, j, zeros, neg, error = 0;
+  mpz_t      want, got;
+  size_t     want_ret, got_ret;
+  mp_size_t  size;
+  FILE       *fp;
+
+  mpz_init (want);
+  mpz_init (got);
+
+  for (i = 0; i < 32; i++)
+    {
+      for (zeros = 0; zeros < 8; zeros++)
+       {
+         for (neg = 0; neg <= 1; neg++)
+           {
+             want_ret = i + zeros + 4;
+
+             /* need this to get the twos complement right */
+             ASSERT_ALWAYS (sizeof (size) >= 4);
+
+             size = i + zeros;
+             if (neg)
+               size = -size;
+
+             fp = fopen_wplusb_or_die (FILENAME);
+             for (j = 3; j >= 0; j--)
+               ASSERT_ALWAYS (putc ((size >> (j*8)) & 0xFF, fp) != EOF);
+             for (j = 0; j < zeros; j++)
+               ASSERT_ALWAYS (putc ('\0', fp) != EOF);
+             for (j = 0; j < i; j++)
+               ASSERT_ALWAYS (putc (BYTEVAL (j), fp) != EOF);
+             /* and some trailing garbage */
+             ASSERT_ALWAYS (putc ('x', fp) != EOF);
+             ASSERT_ALWAYS (putc ('y', fp) != EOF);
+             ASSERT_ALWAYS (putc ('z', fp) != EOF);
+             ASSERT_ALWAYS (fflush (fp) == 0);
+             rewind (fp);
+
+             got_ret = mpz_inp_raw (got, fp);
+             ASSERT_ALWAYS (! ferror(fp));
+             ASSERT_ALWAYS (fclose (fp) == 0);
+
+             MPZ_CHECK_FORMAT (got);
+
+             if (got_ret != want_ret)
+               {
+                 printf ("check_in: return value wrong\n");
+                 error = 1;
+               }
+             if (mpz_cmp (got, want) != 0)
+               {
+                 printf ("check_in: result wrong\n");
+                 error = 1;
+               }
+             if (error)
+               {
+                 printf    ("  i=%d zeros=%d neg=%d\n", i, zeros, neg);
+                 printf    ("  got_ret  %lu\n", (unsigned long) got_ret);
+                 printf    ("  want_ret %lu\n", (unsigned long) want_ret);
+                 mpz_trace ("  got      ", got);
+                 mpz_trace ("  want     ", want);
+                 abort ();
+               }
+
+             mpz_neg (want, want);
+           }
+       }
+      mpz_mul_2exp (want, want, 8);
+      mpz_add_ui (want, want, (unsigned long) BYTEVAL (i));
+    }
+
+  mpz_clear (want);
+  mpz_clear (got);
+}
+
+
+void
+check_out (void)
+{
+  int        i, j, neg, error = 0;
+  mpz_t      z;
+  char       want[256], got[256], *p;
+  size_t     want_len, got_ret, got_read;
+  mp_size_t  size;
+  FILE       *fp;
+
+  mpz_init (z);
+
+  for (i = 0; i < 32; i++)
+    {
+      for (neg = 0; neg <= 1; neg++)
+       {
+         want_len = i + 4;
+
+         /* need this to get the twos complement right */
+         ASSERT_ALWAYS (sizeof (size) >= 4);
+
+         size = i;
+         if (neg)
+           size = -size;
+
+         p = want;
+         for (j = 3; j >= 0; j--)
+           *p++ = size >> (j*8);
+         for (j = 0; j < i; j++)
+           *p++ = BYTEVAL (j);
+         ASSERT_ALWAYS (p <= want + sizeof (want));
+
+         fp = fopen_wplusb_or_die (FILENAME);
+         got_ret = mpz_out_raw (fp, z);
+         ASSERT_ALWAYS (fflush (fp) == 0);
+         rewind (fp);
+         got_read = fread (got, 1, sizeof(got), fp);
+         ASSERT_ALWAYS (! ferror(fp));
+         ASSERT_ALWAYS (fclose (fp) == 0);
+
+         if (got_ret != want_len)
+           {
+             printf ("check_out: wrong return value\n");
+             error = 1;
+           }
+         if (got_read != want_len)
+           {
+             printf ("check_out: wrong number of bytes read back\n");
+             error = 1;
+           }
+         if (memcmp (want, got, want_len) != 0)
+           {
+             printf ("check_out: wrong data\n");
+             error = 1;
+           }
+         if (error)
+           {
+             printf    ("  i=%d neg=%d\n", i, neg);
+             mpz_trace ("  z", z);
+             printf    ("  got_ret  %lu\n", (unsigned long) got_ret);
+             printf    ("  got_read %lu\n", (unsigned long) got_read);
+             printf    ("  want_len %lu\n", (unsigned long) want_len);
+             printf    ("  want");
+             for (j = 0; j < want_len; j++)
+               printf (" %02X", (unsigned) (unsigned char) want[j]);
+             printf    ("\n");
+             printf    ("  got ");
+             for (j = 0; j < want_len; j++)
+               printf (" %02X", (unsigned) (unsigned char) got[j]);
+             printf    ("\n");
+             abort ();
+           }
+
+         mpz_neg (z, z);
+       }
+      mpz_mul_2exp (z, z, 8);
+      mpz_add_ui (z, z, (unsigned long) BYTEVAL (i));
+    }
+
+  mpz_clear (z);
+}
+
+
+void
+check_rand (void)
+{
+  gmp_randstate_ptr  rands = RANDS;
+  int        i, error = 0;
+  mpz_t      got, want;
+  size_t     inp_ret, out_ret;
+  FILE       *fp;
+
+  mpz_init (want);
+  mpz_init (got);
+
+  for (i = 0; i < 500; i++)
+    {
+      mpz_erandomb (want, rands, 10*BITS_PER_MP_LIMB);
+      mpz_negrandom (want, rands);
+
+      fp = fopen_wplusb_or_die (FILENAME);
+      out_ret = mpz_out_raw (fp, want);
+      ASSERT_ALWAYS (fflush (fp) == 0);
+      rewind (fp);
+      inp_ret = mpz_inp_raw (got, fp);
+      ASSERT_ALWAYS (fclose (fp) == 0);
+
+      MPZ_CHECK_FORMAT (got);
+
+      if (inp_ret != out_ret)
+       {
+         printf ("check_rand: different inp/out return values\n");
+         error = 1;
+       }
+      if (mpz_cmp (got, want) != 0)
+       {
+         printf ("check_rand: wrong result\n");
+         error = 1;
+       }
+      if (error)
+       {
+         printf    ("  out_ret %lu\n", (unsigned long) out_ret);
+         printf    ("  inp_ret %lu\n", (unsigned long) inp_ret);
+         mpz_trace ("  want", want);
+         mpz_trace ("  got ", got);
+         abort ();
+       }
+    }
+
+  mpz_clear (got);
+  mpz_clear (want);
+}
+
+
+int
+main (void)
+{
+  tests_start ();
+  mp_trace_base = -16;
+
+  check_in ();
+  check_out ();
+  check_rand ();
+
+  unlink (FILENAME);
+  tests_end ();
+
+  exit (0);
+}