xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/t-inp_str.c (revision d90047b5d07facf36e6c01dcc0bded8997ce9cc2)
1 /* Test mpz_inp_str.
2 
3 Copyright 2001, 2002 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>		/* for unlink */
27 #endif
28 
29 #include "gmp.h"
30 #include "gmp-impl.h"
31 #include "tests.h"
32 
33 
34 #define FILENAME  "t-inp_str.tmp"
35 
36 
37 void
38 check_data (void)
39 {
40   static const struct {
41     const char  *inp;
42     int         base;
43     const char  *want;
44     int         want_nread;
45 
46   } data[] = {
47 
48     { "0",   10, "0", 1 },
49 
50     { "abc", 10, "0", 0 },
51     { "0xf", 10, "0", 1 },
52     { "ghi", 16, "0", 0 },
53     { "100", 90, "0", 0 },
54 
55     {  "ff", 16,  "255", 2 },
56     { "-ff", 16, "-255", 3 },
57     {  "FF", 16,  "255", 2 },
58     { "-FF", 16, "-255", 3 },
59 
60     {  "z", 36, "35", 1 },
61     {  "Z", 36, "35", 1 },
62     { "1B", 59, "70", 2 },
63     {  "a", 60, "36", 1 },
64     {  "A", 61, "10", 1 },
65 
66     {  "0x0",    0,   "0", 3 },
67     {  "0X10",   0,  "16", 4 },
68     { "-0X0",    0,   "0", 4 },
69     { "-0x10",   0, "-16", 5 },
70 
71     {  "0b0",    0,  "0", 3 },
72     {  "0B10",   0,  "2", 4 },
73     { "-0B0",    0,  "0", 4 },
74     { "-0b10",   0, "-2", 5 },
75 
76     {  "00",   0,  "0", 2 },
77     {  "010",  0,  "8", 3 },
78     { "-00",   0,  "0", 3 },
79     { "-010",  0, "-8", 4 },
80 
81     {  "0x",     0,   "0", 2 },
82     {  "0",      0,   "0", 1 },
83     { " 030",   10,  "30", 4 },
84   };
85 
86   mpz_t  got, want;
87   long   ftell_nread;
88   int    i, pre, post, j, got_nread, want_nread;
89   FILE   *fp;
90 
91   mpz_init (got);
92   mpz_init (want);
93 
94   for (i = 0; i < numberof (data); i++)
95     {
96       for (pre = 0; pre <= 3; pre++)
97 	{
98 	  for (post = 0; post <= 2; post++)
99 	    {
100 	      mpz_set_str_or_abort (want, data[i].want, 0);
101 	      MPZ_CHECK_FORMAT (want);
102 
103 	      /* create the file new each time to ensure its length is what
104 		 we want */
105 	      fp = fopen (FILENAME, "w+");
106 	      ASSERT_ALWAYS (fp != NULL);
107 	      for (j = 0; j < pre; j++)
108 		putc (' ', fp);
109 	      fputs (data[i].inp, fp);
110 	      for (j = 0; j < post; j++)
111 		putc (' ', fp);
112 	      fflush (fp);
113 	      ASSERT_ALWAYS (! ferror(fp));
114 
115 	      rewind (fp);
116 	      got_nread = mpz_inp_str (got, fp, data[i].base);
117 
118 	      if (got_nread != 0)
119 		{
120 		  ftell_nread = ftell (fp);
121 		  if (got_nread != ftell_nread)
122 		    {
123 		      printf ("mpz_inp_str nread wrong\n");
124 		      printf ("  inp          \"%s\"\n", data[i].inp);
125 		      printf ("  base         %d\n", data[i].base);
126 		      printf ("  pre          %d\n", pre);
127 		      printf ("  post         %d\n", post);
128 		      printf ("  got_nread    %d\n", got_nread);
129 		      printf ("  ftell_nread  %ld\n", ftell_nread);
130 		      abort ();
131 		    }
132 		}
133 
134 	      /* if data[i].inp is a whole string to read and there's no post
135 		 whitespace then expect to have EOF */
136 	      if (post == 0 && data[i].want_nread == strlen(data[i].inp))
137 		{
138 		  int  c = getc(fp);
139 		  if (c != EOF)
140 		    {
141 		      printf ("mpz_inp_str didn't read to EOF\n");
142 		      printf ("  inp   \"%s\"\n", data[i].inp);
143 		      printf ("  base  %d\n", data[i].base);
144 		      printf ("  pre   %d\n", pre);
145 		      printf ("  post  %d\n", post);
146 		      printf ("  c     '%c' %#x\n", c, c);
147 		      abort ();
148 		    }
149 		}
150 
151 	      /* only expect "pre" included in the count when non-zero */
152 	      want_nread = data[i].want_nread;
153 	      if (want_nread != 0)
154 		want_nread += pre;
155 
156 	      if (got_nread != want_nread)
157 		{
158 		  printf ("mpz_inp_str nread wrong\n");
159 		  printf ("  inp         \"%s\"\n", data[i].inp);
160 		  printf ("  base        %d\n", data[i].base);
161 		  printf ("  pre         %d\n", pre);
162 		  printf ("  post        %d\n", post);
163 		  printf ("  got_nread   %d\n", got_nread);
164 		  printf ("  want_nread  %d\n", want_nread);
165 		  abort ();
166 		}
167 
168 	      MPZ_CHECK_FORMAT (got);
169 
170 	      if (mpz_cmp (got, want) != 0)
171 		{
172 		  printf ("mpz_inp_str wrong result\n");
173 		  printf ("  inp   \"%s\"\n", data[i].inp);
174 		  printf ("  base  %d\n", data[i].base);
175 		  mpz_trace ("  got ",  got);
176 		  mpz_trace ("  want", want);
177 		  abort ();
178 		}
179 
180 	      ASSERT_ALWAYS (fclose (fp) == 0);
181 	    }
182 	}
183     }
184 
185   mpz_clear (got);
186   mpz_clear (want);
187 }
188 
189 int
190 main (void)
191 {
192   tests_start ();
193 
194   check_data ();
195 
196   unlink (FILENAME);
197   tests_end ();
198   exit (0);
199 }
200