@@ -11,10 +11,41 @@ static void draw(const mp_int *a)
1111 ndraw (a , "" );
1212}
1313
14- #define FGETS (str , size , stream ) \
14+ /*
15+ Get tokens. It is just a very(!) simple fgets(3) that does not keep line endings.
16+
17+ Implementation follows along "man 3 fgets", some of which is quoted.
18+ */
19+ static char * s_mp_get_token (char * s , int size , FILE * stream )
20+ {
21+ char * s_bar = s ;
22+ int c ;
23+
24+ /* "fgets [...] reads in at most one less than size characters from stream" */
25+ while (-- size ) {
26+ /* "Reading stops after an EOF or a newline." We stop only for EOF here */
27+ if ((c = fgetc (stream )) == EOF ) {
28+ /* "Returns [...] NULL on error or when end of file occurs while no characters have been read" */
29+ if ((s_bar == s ) || (ferror (stream ) != 0 )) {
30+ return NULL ;
31+ }
32+ break ;
33+ }
34+ /* Ignore line-breaks but keep reading to get them out of the stream-buffer */
35+ if ((c == '\n' ) || (c == '\r' )) {
36+ continue ;
37+ }
38+ * s_bar ++ = c ;
39+ }
40+ /* "A terminating null byte ('\0') is stored after the last character in the buffer" */
41+ * s_bar = '\0' ;
42+ return s ;
43+ }
44+
45+ #define GET_TOKEN (str , size , stream ) \
1546 { \
16- char *ret = fgets( str, size, stream); \
17- if (!ret) { fprintf(stderr, "\n%d: fgets failed\n", __LINE__); goto LBL_ERR; } \
47+ char *ret = s_mp_get_token(( str), ( size), ( stream) ); \
48+ if (!ret) { fprintf(stderr, "\n%d: s_mp_get_token failed\n", __LINE__); goto LBL_ERR; } \
1849 }
1950
2051static int mtest_opponent (void )
@@ -76,17 +107,17 @@ static int mtest_opponent(void)
76107 printf ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu " ,
77108 add_n , sub_n , mul_n , div_n , sqr_n , mul2d_n , div2d_n , gcd_n , lcm_n ,
78109 expt_n , inv_n , div2_n , mul2_n , add_d_n , sub_d_n );
79- FGETS (cmd , 4095 , stdin );
110+ GET_TOKEN (cmd , 4095 , stdin );
80111 cmd [strlen (cmd ) - 1u ] = '\0' ;
81112 printf ("%-6s ]\r" , cmd );
82113 fflush (stdout );
83114 if (strcmp (cmd , "mul2d" ) == 0 ) {
84115 ++ mul2d_n ;
85- FGETS (buf , 4095 , stdin );
116+ GET_TOKEN (buf , 4095 , stdin );
86117 DO (mp_read_radix (& a , buf , 64 ));
87- FGETS (buf , 4095 , stdin );
118+ GET_TOKEN (buf , 4095 , stdin );
88119 sscanf (buf , "%u" , & rr );
89- FGETS (buf , 4095 , stdin );
120+ GET_TOKEN (buf , 4095 , stdin );
90121 DO (mp_read_radix (& b , buf , 64 ));
91122
92123 DO (mp_mul_2d (& a , (int )rr , & a ));
@@ -99,11 +130,11 @@ static int mtest_opponent(void)
99130 }
100131 } else if (strcmp (cmd , "div2d" ) == 0 ) {
101132 ++ div2d_n ;
102- FGETS (buf , 4095 , stdin );
133+ GET_TOKEN (buf , 4095 , stdin );
103134 DO (mp_read_radix (& a , buf , 64 ));
104- FGETS (buf , 4095 , stdin );
135+ GET_TOKEN (buf , 4095 , stdin );
105136 sscanf (buf , "%u" , & rr );
106- FGETS (buf , 4095 , stdin );
137+ GET_TOKEN (buf , 4095 , stdin );
107138 DO (mp_read_radix (& b , buf , 64 ));
108139
109140 DO (mp_div_2d (& a , (int )rr , & a , & e ));
@@ -119,11 +150,11 @@ static int mtest_opponent(void)
119150 }
120151 } else if (strcmp (cmd , "add" ) == 0 ) {
121152 ++ add_n ;
122- FGETS (buf , 4095 , stdin );
153+ GET_TOKEN (buf , 4095 , stdin );
123154 DO (mp_read_radix (& a , buf , 64 ));
124- FGETS (buf , 4095 , stdin );
155+ GET_TOKEN (buf , 4095 , stdin );
125156 DO (mp_read_radix (& b , buf , 64 ));
126- FGETS (buf , 4095 , stdin );
157+ GET_TOKEN (buf , 4095 , stdin );
127158 DO (mp_read_radix (& c , buf , 64 ));
128159 DO (mp_copy (& a , & d ));
129160 DO (mp_add (& d , & b , & d ));
@@ -162,11 +193,11 @@ static int mtest_opponent(void)
162193
163194 } else if (strcmp (cmd , "sub" ) == 0 ) {
164195 ++ sub_n ;
165- FGETS (buf , 4095 , stdin );
196+ GET_TOKEN (buf , 4095 , stdin );
166197 DO (mp_read_radix (& a , buf , 64 ));
167- FGETS (buf , 4095 , stdin );
198+ GET_TOKEN (buf , 4095 , stdin );
168199 DO (mp_read_radix (& b , buf , 64 ));
169- FGETS (buf , 4095 , stdin );
200+ GET_TOKEN (buf , 4095 , stdin );
170201 DO (mp_read_radix (& c , buf , 64 ));
171202 DO (mp_copy (& a , & d ));
172203 DO (mp_sub (& d , & b , & d ));
@@ -180,11 +211,11 @@ static int mtest_opponent(void)
180211 }
181212 } else if (strcmp (cmd , "mul" ) == 0 ) {
182213 ++ mul_n ;
183- FGETS (buf , 4095 , stdin );
214+ GET_TOKEN (buf , 4095 , stdin );
184215 DO (mp_read_radix (& a , buf , 64 ));
185- FGETS (buf , 4095 , stdin );
216+ GET_TOKEN (buf , 4095 , stdin );
186217 DO (mp_read_radix (& b , buf , 64 ));
187- FGETS (buf , 4095 , stdin );
218+ GET_TOKEN (buf , 4095 , stdin );
188219 DO (mp_read_radix (& c , buf , 64 ));
189220 DO (mp_copy (& a , & d ));
190221 DO (mp_mul (& d , & b , & d ));
@@ -198,13 +229,13 @@ static int mtest_opponent(void)
198229 }
199230 } else if (strcmp (cmd , "div" ) == 0 ) {
200231 ++ div_n ;
201- FGETS (buf , 4095 , stdin );
232+ GET_TOKEN (buf , 4095 , stdin );
202233 DO (mp_read_radix (& a , buf , 64 ));
203- FGETS (buf , 4095 , stdin );
234+ GET_TOKEN (buf , 4095 , stdin );
204235 DO (mp_read_radix (& b , buf , 64 ));
205- FGETS (buf , 4095 , stdin );
236+ GET_TOKEN (buf , 4095 , stdin );
206237 DO (mp_read_radix (& c , buf , 64 ));
207- FGETS (buf , 4095 , stdin );
238+ GET_TOKEN (buf , 4095 , stdin );
208239 DO (mp_read_radix (& d , buf , 64 ));
209240
210241 DO (mp_div (& a , & b , & e , & f ));
@@ -222,9 +253,9 @@ static int mtest_opponent(void)
222253
223254 } else if (strcmp (cmd , "sqr" ) == 0 ) {
224255 ++ sqr_n ;
225- FGETS (buf , 4095 , stdin );
256+ GET_TOKEN (buf , 4095 , stdin );
226257 DO (mp_read_radix (& a , buf , 64 ));
227- FGETS (buf , 4095 , stdin );
258+ GET_TOKEN (buf , 4095 , stdin );
228259 DO (mp_read_radix (& b , buf , 64 ));
229260 DO (mp_copy (& a , & c ));
230261 DO (mp_sqr (& c , & c ));
@@ -237,11 +268,11 @@ static int mtest_opponent(void)
237268 }
238269 } else if (strcmp (cmd , "gcd" ) == 0 ) {
239270 ++ gcd_n ;
240- FGETS (buf , 4095 , stdin );
271+ GET_TOKEN (buf , 4095 , stdin );
241272 DO (mp_read_radix (& a , buf , 64 ));
242- FGETS (buf , 4095 , stdin );
273+ GET_TOKEN (buf , 4095 , stdin );
243274 DO (mp_read_radix (& b , buf , 64 ));
244- FGETS (buf , 4095 , stdin );
275+ GET_TOKEN (buf , 4095 , stdin );
245276 DO (mp_read_radix (& c , buf , 64 ));
246277 DO (mp_copy (& a , & d ));
247278 DO (mp_gcd (& d , & b , & d ));
@@ -256,11 +287,11 @@ static int mtest_opponent(void)
256287 }
257288 } else if (strcmp (cmd , "lcm" ) == 0 ) {
258289 ++ lcm_n ;
259- FGETS (buf , 4095 , stdin );
290+ GET_TOKEN (buf , 4095 , stdin );
260291 DO (mp_read_radix (& a , buf , 64 ));
261- FGETS (buf , 4095 , stdin );
292+ GET_TOKEN (buf , 4095 , stdin );
262293 DO (mp_read_radix (& b , buf , 64 ));
263- FGETS (buf , 4095 , stdin );
294+ GET_TOKEN (buf , 4095 , stdin );
264295 DO (mp_read_radix (& c , buf , 64 ));
265296 DO (mp_copy (& a , & d ));
266297 DO (mp_lcm (& d , & b , & d ));
@@ -275,13 +306,13 @@ static int mtest_opponent(void)
275306 }
276307 } else if (strcmp (cmd , "expt" ) == 0 ) {
277308 ++ expt_n ;
278- FGETS (buf , 4095 , stdin );
309+ GET_TOKEN (buf , 4095 , stdin );
279310 DO (mp_read_radix (& a , buf , 64 ));
280- FGETS (buf , 4095 , stdin );
311+ GET_TOKEN (buf , 4095 , stdin );
281312 DO (mp_read_radix (& b , buf , 64 ));
282- FGETS (buf , 4095 , stdin );
313+ GET_TOKEN (buf , 4095 , stdin );
283314 DO (mp_read_radix (& c , buf , 64 ));
284- FGETS (buf , 4095 , stdin );
315+ GET_TOKEN (buf , 4095 , stdin );
285316 DO (mp_read_radix (& d , buf , 64 ));
286317 DO (mp_copy (& a , & e ));
287318 DO (mp_exptmod (& e , & b , & c , & e ));
@@ -296,11 +327,11 @@ static int mtest_opponent(void)
296327 }
297328 } else if (strcmp (cmd , "invmod" ) == 0 ) {
298329 ++ inv_n ;
299- FGETS (buf , 4095 , stdin );
330+ GET_TOKEN (buf , 4095 , stdin );
300331 DO (mp_read_radix (& a , buf , 64 ));
301- FGETS (buf , 4095 , stdin );
332+ GET_TOKEN (buf , 4095 , stdin );
302333 DO (mp_read_radix (& b , buf , 64 ));
303- FGETS (buf , 4095 , stdin );
334+ GET_TOKEN (buf , 4095 , stdin );
304335 DO (mp_read_radix (& c , buf , 64 ));
305336 DO (mp_invmod (& a , & b , & d ));
306337 DO (mp_mulmod (& d , & a , & b , & e ));
@@ -318,9 +349,9 @@ static int mtest_opponent(void)
318349
319350 } else if (strcmp (cmd , "div2" ) == 0 ) {
320351 ++ div2_n ;
321- FGETS (buf , 4095 , stdin );
352+ GET_TOKEN (buf , 4095 , stdin );
322353 DO (mp_read_radix (& a , buf , 64 ));
323- FGETS (buf , 4095 , stdin );
354+ GET_TOKEN (buf , 4095 , stdin );
324355 DO (mp_read_radix (& b , buf , 64 ));
325356 DO (mp_div_2 (& a , & c ));
326357 if (mp_cmp (& c , & b ) != MP_EQ ) {
@@ -332,9 +363,9 @@ static int mtest_opponent(void)
332363 }
333364 } else if (strcmp (cmd , "mul2" ) == 0 ) {
334365 ++ mul2_n ;
335- FGETS (buf , 4095 , stdin );
366+ GET_TOKEN (buf , 4095 , stdin );
336367 DO (mp_read_radix (& a , buf , 64 ));
337- FGETS (buf , 4095 , stdin );
368+ GET_TOKEN (buf , 4095 , stdin );
338369 DO (mp_read_radix (& b , buf , 64 ));
339370 DO (mp_mul_2 (& a , & c ));
340371 if (mp_cmp (& c , & b ) != MP_EQ ) {
@@ -346,11 +377,11 @@ static int mtest_opponent(void)
346377 }
347378 } else if (strcmp (cmd , "add_d" ) == 0 ) {
348379 ++ add_d_n ;
349- FGETS (buf , 4095 , stdin );
380+ GET_TOKEN (buf , 4095 , stdin );
350381 DO (mp_read_radix (& a , buf , 64 ));
351- FGETS (buf , 4095 , stdin );
382+ GET_TOKEN (buf , 4095 , stdin );
352383 sscanf (buf , "%d" , & ix );
353- FGETS (buf , 4095 , stdin );
384+ GET_TOKEN (buf , 4095 , stdin );
354385 DO (mp_read_radix (& b , buf , 64 ));
355386 DO (mp_add_d (& a , (mp_digit )ix , & c ));
356387 if (mp_cmp (& b , & c ) != MP_EQ ) {
@@ -363,11 +394,11 @@ static int mtest_opponent(void)
363394 }
364395 } else if (strcmp (cmd , "sub_d" ) == 0 ) {
365396 ++ sub_d_n ;
366- FGETS (buf , 4095 , stdin );
397+ GET_TOKEN (buf , 4095 , stdin );
367398 DO (mp_read_radix (& a , buf , 64 ));
368- FGETS (buf , 4095 , stdin );
399+ GET_TOKEN (buf , 4095 , stdin );
369400 sscanf (buf , "%d" , & ix );
370- FGETS (buf , 4095 , stdin );
401+ GET_TOKEN (buf , 4095 , stdin );
371402 DO (mp_read_radix (& b , buf , 64 ));
372403 DO (mp_sub_d (& a , (mp_digit )ix , & c ));
373404 if (mp_cmp (& b , & c ) != MP_EQ ) {
0 commit comments