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