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

     1  /*
     2  
     3  Copyright 2012-2014, 2016 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 <assert.h>
    21  #include <limits.h>
    22  #include <stdlib.h>
    23  #include <stdio.h>
    24  #include <string.h>
    25  
    26  #include "testutils.h"
    27  
    28  #define MAXBITS 400
    29  #define COUNT 2000
    30  
    31  #define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
    32  #define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
    33  
    34  static void
    35  test_small (void)
    36  {
    37    struct {
    38      const char *input;
    39      const char *decimal;
    40    } data[] = {
    41      { "183407", "183407" },
    42      { " 763959", "763959 " },
    43      { "9 81999", "981999" },
    44      { "10\t7398 ", "107398" },
    45      { "-9585 44", "-00958544" },
    46      { "-0", "0000" },
    47      { " -000  ", "0" },
    48      { "0704436", "231710" },
    49      /* Check the case of large number of leading zeros. */
    50      { "0000000000000000000000000", "0000000000000000000000000" },
    51      { "000000000000000000000000704436", "000000000000000000000000231710" },
    52      { " 02503517", "689999" },
    53      { "0 1312143", "365667" },
    54      { "-03 274062", "-882738" },
    55      { "012\t242", "005282" },
    56      { "0b11010111110010001111", "883855" },
    57      { " 0b11001010010100001", "103585" },
    58      { "-0b101010110011101111", "-175343" },
    59      { "0b 1111111011011100110", "521958" },
    60      { "0b1 1111110111001000011", "1044035" },
    61      { " 0x53dfc", "343548" },
    62      { "0xfA019", "1024025" },
    63      { "0x 642d1", "410321" },
    64      { "0x5 8067", "360551" },
    65      { "-0xd6Be6", "-879590" },
    66      { "\t0B1110000100000000011", "460803" },
    67      { "0B\t1111110010010100101", "517285" },
    68      { "0B1\t010111101101110100", "359284" },
    69      { "-0B101\t1001101111111001", "-367609" },
    70      { "0B10001001010111110000", "562672" },
    71      { "0Xe4B7e", "936830" },
    72      { "0X1E4bf", "124095" },
    73      { "-0Xfdb90", "-1039248" },
    74      { "0X7fc47", "523335" },
    75      { "0X8167c", "530044" },
    76      /* Some invalid inputs */
    77      { "", NULL },
    78      { "0x", NULL },
    79      { "0b", NULL },
    80      { "0z", NULL },
    81      { "-", NULL },
    82      { "-0x ", NULL },
    83      { "0|1", NULL },
    84      { "4+4", NULL },
    85      { "0ab", NULL },
    86      { "10x0", NULL },
    87      { "0xxab", NULL },
    88      { "ab", NULL },
    89      { "0%#", NULL },
    90      { "$foo", NULL },
    91      { NULL, NULL }
    92    };
    93    unsigned i;
    94    mpz_t a, b;
    95    mpz_init (b);
    96  
    97    for (i = 0; data[i].input; i++)
    98      {
    99        int res = mpz_init_set_str (a, data[i].input, 0);
   100        if (data[i].decimal)
   101  	{
   102  	  if (res != 0)
   103  	    {
   104  	      fprintf (stderr, "mpz_set_str returned -1, input: %s\n",
   105  		       data[i].input);
   106  	      abort ();
   107  	    }
   108  	  if (mpz_set_str (b, data[i].decimal, 10) != 0)
   109  	    {
   110  	      fprintf (stderr, "mpz_set_str returned -1, decimal input: %s\n",
   111  		       data[i].input);
   112  	      abort ();
   113  	    }
   114  	  if (mpz_cmp (a, b) != 0)
   115  	    {
   116  	      fprintf (stderr, "mpz_set_str failed for input: %s\n",
   117  		       data[i].input);
   118  
   119  	      dump ("got", a);
   120  	      dump ("ref", b);
   121  	      abort ();
   122  	    }
   123  	}
   124        else if (res != -1)
   125  	{
   126  	  fprintf (stderr, "mpz_set_str returned %d, invalid input: %s\n",
   127  		   res, data[i].input);
   128  	  abort ();
   129  	}
   130        mpz_clear (a);
   131      }
   132  
   133    mpz_clear (b);
   134  }
   135  
   136  void
   137  testmain (int argc, char **argv)
   138  {
   139    unsigned i;
   140    char *ap;
   141    char *bp;
   142    char *rp;
   143    size_t bn, rn, arn;
   144  
   145    mpz_t a, b;
   146  
   147    FILE *tmp;
   148  
   149    test_small ();
   150  
   151    mpz_init (a);
   152    mpz_init (b);
   153  
   154    tmp = tmpfile ();
   155    if (!tmp)
   156      fprintf (stderr,
   157  	     "Failed to create temporary file. Skipping mpz_out_str tests.\n");
   158  
   159    for (i = 0; i < COUNT; i++)
   160      {
   161        int base;
   162        for (base = 0; base <= 36; base += 1 + (base == 0))
   163  	{
   164  	  hex_random_str_op (MAXBITS, i&1 ? base: -base, &ap, &rp);
   165  	  if (mpz_set_str (a, ap, 16) != 0)
   166  	    {
   167  	      fprintf (stderr, "mpz_set_str failed on input %s\n", ap);
   168  	      abort ();
   169  	    }
   170  
   171  	  rn = strlen (rp);
   172  	  arn = rn - (rp[0] == '-');
   173  
   174  	  bn = mpz_sizeinbase (a, base ? base : 10);
   175  	  if (bn < arn || bn > (arn + 1))
   176  	    {
   177  	      fprintf (stderr, "mpz_sizeinbase failed:\n");
   178  	      dump ("a", a);
   179  	      fprintf (stderr, "r = %s\n", rp);
   180  	      fprintf (stderr, "  base %d, correct size %u, got %u\n",
   181  		       base, (unsigned) arn, (unsigned)bn);
   182  	      abort ();
   183  	    }
   184  	  bp = mpz_get_str (NULL, i&1 ? base: -base, a);
   185  	  if (strcmp (bp, rp))
   186  	    {
   187  	      fprintf (stderr, "mpz_get_str failed:\n");
   188  	      dump ("a", a);
   189  	      fprintf (stderr, "b = %s\n", bp);
   190  	      fprintf (stderr, "  base = %d\n", base);
   191  	      fprintf (stderr, "r = %s\n", rp);
   192  	      abort ();
   193  	    }
   194  
   195  	  /* Just a few tests with file i/o. */
   196  	  if (tmp && i < 20)
   197  	    {
   198  	      size_t tn;
   199  	      rewind (tmp);
   200  	      tn = mpz_out_str (tmp, i&1 ? base: -base, a);
   201  	      if (tn != rn)
   202  		{
   203  		  fprintf (stderr, "mpz_out_str, bad return value:\n");
   204  		  dump ("a", a);
   205  		  fprintf (stderr, "r = %s\n", rp);
   206  		  fprintf (stderr, "  base %d, correct size %u, got %u\n",
   207  			   base, (unsigned) rn, (unsigned)tn);
   208  		  abort ();
   209  		}
   210  	      rewind (tmp);
   211  	      memset (bp, 0, rn);
   212  	      tn = fread (bp, 1, rn, tmp);
   213  	      if (tn != rn)
   214  		{
   215  		  fprintf (stderr,
   216  			   "fread failed, expected %lu bytes, got only %lu.\n",
   217  			   (unsigned long) rn, (unsigned long) tn);
   218  		  abort ();
   219  		}
   220  
   221  	      if (memcmp (bp, rp, rn) != 0)
   222  		{
   223  		  fprintf (stderr, "mpz_out_str failed:\n");
   224  		  dump ("a", a);
   225  		  fprintf (stderr, "b = %s\n", bp);
   226  		  fprintf (stderr, "  base = %d\n", base);
   227  		  fprintf (stderr, "r = %s\n", rp);
   228  		  abort ();
   229  		}
   230  	    }
   231  
   232  	  mpz_set_str (b, rp, base);
   233  
   234  	  if (mpz_cmp (a, b))
   235  	    {
   236  	      fprintf (stderr, "mpz_set_str failed:\n");
   237  	      fprintf (stderr, "r = %s\n", rp);
   238  	      fprintf (stderr, "  base = %d\n", base);
   239  	      fprintf (stderr, "r = %s\n", ap);
   240  	      fprintf (stderr, "  base = 16\n");
   241  	      dump ("b", b);
   242  	      dump ("r", a);
   243  	      abort ();
   244  	    }
   245  
   246  	  /* Test mpn interface */
   247  	  if (base && mpz_sgn (a))
   248  	    {
   249  	      size_t i;
   250  	      const char *absr;
   251  	      mp_limb_t t[MAXLIMBS];
   252  	      mp_size_t tn = mpz_size (a);
   253  
   254  	      assert (tn <= MAXLIMBS);
   255  	      mpn_copyi (t, a->_mp_d, tn);
   256  
   257  	      bn = mpn_get_str ((unsigned char *) bp, base, t, tn);
   258  	      if (bn != arn)
   259  		{
   260  		  fprintf (stderr, "mpn_get_str failed:\n");
   261  		  fprintf (stderr, "returned length: %lu (bad)\n", (unsigned long) bn);
   262  		  fprintf (stderr, "expected: %lu\n", (unsigned long) arn);
   263  		  fprintf (stderr, "  base = %d\n", base);
   264  		  fprintf (stderr, "r = %s\n", ap);
   265  		  fprintf (stderr, "  base = 16\n");
   266  		  dump ("b", b);
   267  		  dump ("r", a);
   268  		  abort ();
   269  		}
   270  	      absr = rp + (rp[0] == '-');
   271  
   272  	      for (i = 0; i < bn; i++)
   273  		{
   274  		  unsigned char digit = absr[i];
   275  		  unsigned value;
   276  		  if (digit >= '0' && digit <= '9')
   277  		    value = digit - '0';
   278  		  else if (digit >= 'a' && digit <= 'z')
   279  		    value = digit - 'a' + 10;
   280  		  else if (digit >= 'A' && digit <= 'Z')
   281  		    value = digit - 'A' + 10;
   282  		  else
   283  		    {
   284  		      fprintf (stderr, "Internal error in test.\n");
   285  		      abort();
   286  		    }
   287  		  if (bp[i] != value)
   288  		    {
   289  		      fprintf (stderr, "mpn_get_str failed:\n");
   290  		      fprintf (stderr, "digit %lu: %d (bad)\n", (unsigned long) i, bp[i]);
   291  		      fprintf (stderr, "expected: %d\n", value);
   292  		      fprintf (stderr, "  base = %d\n", base);
   293  		      fprintf (stderr, "r = %s\n", ap);
   294  		      fprintf (stderr, "  base = 16\n");
   295  		      dump ("b", b);
   296  		      dump ("r", a);
   297  		      abort ();
   298  		    }
   299  		}
   300  	      tn = mpn_set_str (t, (unsigned char *) bp, bn, base);
   301  	      if (tn != mpz_size (a) || mpn_cmp (t, a->_mp_d, tn))
   302  		{
   303  		  fprintf (stderr, "mpn_set_str failed:\n");
   304  		  fprintf (stderr, "r = %s\n", rp);
   305  		  fprintf (stderr, "  base = %d\n", base);
   306  		  fprintf (stderr, "r = %s\n", ap);
   307  		  fprintf (stderr, "  base = 16\n");
   308  		  dump ("r", a);
   309  		  abort ();
   310  		}
   311  	    }
   312  	  free (ap);
   313  	  free (rp);
   314  	  testfree (bp);
   315  	}
   316      }
   317    mpz_clear (a);
   318    mpz_clear (b);
   319  }