@@ -11,10 +11,49 @@ 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+ bool eol_hit = false;
24+
25+ /* "fgets [...] reads in at most one less than size characters from stream" */
26+ while (-- size ) {
27+ /* "Reading stops after an EOF or a newline." We stop only for EOF here */
28+ if ((c = fgetc (stream )) == EOF ) {
29+ /* "Returns [...] NULL on error or when end of file occurs while no characters have been read" */
30+ if ((s_bar == s ) || (ferror (stream ) != 0 )) {
31+ return NULL ;
32+ }
33+ break ;
34+ }
35+ /* Ignore line-breaks but keep reading to get them out of the stream-buffer */
36+ if ((c == '\n' ) || (c == '\r' )) {
37+ eol_hit = true;
38+ continue ;
39+ }
40+ /* Stop reading after linebreak */
41+ if (eol_hit ) {
42+ /* We already read the character after the linebreak, put it back */
43+ ungetc (c , stream );
44+ break ;
45+ }
46+ * s_bar ++ = c ;
47+ }
48+ /* "A terminating null byte ('\0') is stored after the last character in the buffer" */
49+ * s_bar = '\0' ;
50+ return s ;
51+ }
52+
53+ #define GET_TOKEN (str , size , stream ) \
1554 { \
16- char *ret = fgets( str, size, stream); \
17- if (!ret) { fprintf(stderr, "\n%d: fgets failed\n", __LINE__); goto LBL_ERR; } \
55+ char *ret = s_mp_get_token(( str), ( size), ( stream) ); \
56+ if (!ret) { fprintf(stderr, "\n%d: s_mp_get_token failed\n", __LINE__); goto LBL_ERR; } \
1857 }
1958
2059static int mtest_opponent (void )
@@ -76,17 +115,16 @@ static int mtest_opponent(void)
76115 printf ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu " ,
77116 add_n , sub_n , mul_n , div_n , sqr_n , mul2d_n , div2d_n , gcd_n , lcm_n ,
78117 expt_n , inv_n , div2_n , mul2_n , add_d_n , sub_d_n );
79- FGETS (cmd , 4095 , stdin );
80- cmd [strlen (cmd ) - 1u ] = '\0' ;
118+ GET_TOKEN (cmd , 4095 , stdin );
81119 printf ("%-6s ]\r" , cmd );
82120 fflush (stdout );
83121 if (strcmp (cmd , "mul2d" ) == 0 ) {
84122 ++ mul2d_n ;
85- FGETS (buf , 4095 , stdin );
123+ GET_TOKEN (buf , 4095 , stdin );
86124 DO (mp_read_radix (& a , buf , 64 ));
87- FGETS (buf , 4095 , stdin );
125+ GET_TOKEN (buf , 4095 , stdin );
88126 sscanf (buf , "%u" , & rr );
89- FGETS (buf , 4095 , stdin );
127+ GET_TOKEN (buf , 4095 , stdin );
90128 DO (mp_read_radix (& b , buf , 64 ));
91129
92130 DO (mp_mul_2d (& a , (int )rr , & a ));
@@ -99,11 +137,11 @@ static int mtest_opponent(void)
99137 }
100138 } else if (strcmp (cmd , "div2d" ) == 0 ) {
101139 ++ div2d_n ;
102- FGETS (buf , 4095 , stdin );
140+ GET_TOKEN (buf , 4095 , stdin );
103141 DO (mp_read_radix (& a , buf , 64 ));
104- FGETS (buf , 4095 , stdin );
142+ GET_TOKEN (buf , 4095 , stdin );
105143 sscanf (buf , "%u" , & rr );
106- FGETS (buf , 4095 , stdin );
144+ GET_TOKEN (buf , 4095 , stdin );
107145 DO (mp_read_radix (& b , buf , 64 ));
108146
109147 DO (mp_div_2d (& a , (int )rr , & a , & e ));
@@ -119,11 +157,11 @@ static int mtest_opponent(void)
119157 }
120158 } else if (strcmp (cmd , "add" ) == 0 ) {
121159 ++ add_n ;
122- FGETS (buf , 4095 , stdin );
160+ GET_TOKEN (buf , 4095 , stdin );
123161 DO (mp_read_radix (& a , buf , 64 ));
124- FGETS (buf , 4095 , stdin );
162+ GET_TOKEN (buf , 4095 , stdin );
125163 DO (mp_read_radix (& b , buf , 64 ));
126- FGETS (buf , 4095 , stdin );
164+ GET_TOKEN (buf , 4095 , stdin );
127165 DO (mp_read_radix (& c , buf , 64 ));
128166 DO (mp_copy (& a , & d ));
129167 DO (mp_add (& d , & b , & d ));
@@ -162,11 +200,11 @@ static int mtest_opponent(void)
162200
163201 } else if (strcmp (cmd , "sub" ) == 0 ) {
164202 ++ sub_n ;
165- FGETS (buf , 4095 , stdin );
203+ GET_TOKEN (buf , 4095 , stdin );
166204 DO (mp_read_radix (& a , buf , 64 ));
167- FGETS (buf , 4095 , stdin );
205+ GET_TOKEN (buf , 4095 , stdin );
168206 DO (mp_read_radix (& b , buf , 64 ));
169- FGETS (buf , 4095 , stdin );
207+ GET_TOKEN (buf , 4095 , stdin );
170208 DO (mp_read_radix (& c , buf , 64 ));
171209 DO (mp_copy (& a , & d ));
172210 DO (mp_sub (& d , & b , & d ));
@@ -180,11 +218,11 @@ static int mtest_opponent(void)
180218 }
181219 } else if (strcmp (cmd , "mul" ) == 0 ) {
182220 ++ mul_n ;
183- FGETS (buf , 4095 , stdin );
221+ GET_TOKEN (buf , 4095 , stdin );
184222 DO (mp_read_radix (& a , buf , 64 ));
185- FGETS (buf , 4095 , stdin );
223+ GET_TOKEN (buf , 4095 , stdin );
186224 DO (mp_read_radix (& b , buf , 64 ));
187- FGETS (buf , 4095 , stdin );
225+ GET_TOKEN (buf , 4095 , stdin );
188226 DO (mp_read_radix (& c , buf , 64 ));
189227 DO (mp_copy (& a , & d ));
190228 DO (mp_mul (& d , & b , & d ));
@@ -198,13 +236,13 @@ static int mtest_opponent(void)
198236 }
199237 } else if (strcmp (cmd , "div" ) == 0 ) {
200238 ++ div_n ;
201- FGETS (buf , 4095 , stdin );
239+ GET_TOKEN (buf , 4095 , stdin );
202240 DO (mp_read_radix (& a , buf , 64 ));
203- FGETS (buf , 4095 , stdin );
241+ GET_TOKEN (buf , 4095 , stdin );
204242 DO (mp_read_radix (& b , buf , 64 ));
205- FGETS (buf , 4095 , stdin );
243+ GET_TOKEN (buf , 4095 , stdin );
206244 DO (mp_read_radix (& c , buf , 64 ));
207- FGETS (buf , 4095 , stdin );
245+ GET_TOKEN (buf , 4095 , stdin );
208246 DO (mp_read_radix (& d , buf , 64 ));
209247
210248 DO (mp_div (& a , & b , & e , & f ));
@@ -222,9 +260,9 @@ static int mtest_opponent(void)
222260
223261 } else if (strcmp (cmd , "sqr" ) == 0 ) {
224262 ++ sqr_n ;
225- FGETS (buf , 4095 , stdin );
263+ GET_TOKEN (buf , 4095 , stdin );
226264 DO (mp_read_radix (& a , buf , 64 ));
227- FGETS (buf , 4095 , stdin );
265+ GET_TOKEN (buf , 4095 , stdin );
228266 DO (mp_read_radix (& b , buf , 64 ));
229267 DO (mp_copy (& a , & c ));
230268 DO (mp_sqr (& c , & c ));
@@ -237,11 +275,11 @@ static int mtest_opponent(void)
237275 }
238276 } else if (strcmp (cmd , "gcd" ) == 0 ) {
239277 ++ gcd_n ;
240- FGETS (buf , 4095 , stdin );
278+ GET_TOKEN (buf , 4095 , stdin );
241279 DO (mp_read_radix (& a , buf , 64 ));
242- FGETS (buf , 4095 , stdin );
280+ GET_TOKEN (buf , 4095 , stdin );
243281 DO (mp_read_radix (& b , buf , 64 ));
244- FGETS (buf , 4095 , stdin );
282+ GET_TOKEN (buf , 4095 , stdin );
245283 DO (mp_read_radix (& c , buf , 64 ));
246284 DO (mp_copy (& a , & d ));
247285 DO (mp_gcd (& d , & b , & d ));
@@ -256,11 +294,11 @@ static int mtest_opponent(void)
256294 }
257295 } else if (strcmp (cmd , "lcm" ) == 0 ) {
258296 ++ lcm_n ;
259- FGETS (buf , 4095 , stdin );
297+ GET_TOKEN (buf , 4095 , stdin );
260298 DO (mp_read_radix (& a , buf , 64 ));
261- FGETS (buf , 4095 , stdin );
299+ GET_TOKEN (buf , 4095 , stdin );
262300 DO (mp_read_radix (& b , buf , 64 ));
263- FGETS (buf , 4095 , stdin );
301+ GET_TOKEN (buf , 4095 , stdin );
264302 DO (mp_read_radix (& c , buf , 64 ));
265303 DO (mp_copy (& a , & d ));
266304 DO (mp_lcm (& d , & b , & d ));
@@ -275,13 +313,13 @@ static int mtest_opponent(void)
275313 }
276314 } else if (strcmp (cmd , "expt" ) == 0 ) {
277315 ++ expt_n ;
278- FGETS (buf , 4095 , stdin );
316+ GET_TOKEN (buf , 4095 , stdin );
279317 DO (mp_read_radix (& a , buf , 64 ));
280- FGETS (buf , 4095 , stdin );
318+ GET_TOKEN (buf , 4095 , stdin );
281319 DO (mp_read_radix (& b , buf , 64 ));
282- FGETS (buf , 4095 , stdin );
320+ GET_TOKEN (buf , 4095 , stdin );
283321 DO (mp_read_radix (& c , buf , 64 ));
284- FGETS (buf , 4095 , stdin );
322+ GET_TOKEN (buf , 4095 , stdin );
285323 DO (mp_read_radix (& d , buf , 64 ));
286324 DO (mp_copy (& a , & e ));
287325 DO (mp_exptmod (& e , & b , & c , & e ));
@@ -296,11 +334,11 @@ static int mtest_opponent(void)
296334 }
297335 } else if (strcmp (cmd , "invmod" ) == 0 ) {
298336 ++ inv_n ;
299- FGETS (buf , 4095 , stdin );
337+ GET_TOKEN (buf , 4095 , stdin );
300338 DO (mp_read_radix (& a , buf , 64 ));
301- FGETS (buf , 4095 , stdin );
339+ GET_TOKEN (buf , 4095 , stdin );
302340 DO (mp_read_radix (& b , buf , 64 ));
303- FGETS (buf , 4095 , stdin );
341+ GET_TOKEN (buf , 4095 , stdin );
304342 DO (mp_read_radix (& c , buf , 64 ));
305343 DO (mp_invmod (& a , & b , & d ));
306344 DO (mp_mulmod (& d , & a , & b , & e ));
@@ -318,9 +356,9 @@ static int mtest_opponent(void)
318356
319357 } else if (strcmp (cmd , "div2" ) == 0 ) {
320358 ++ div2_n ;
321- FGETS (buf , 4095 , stdin );
359+ GET_TOKEN (buf , 4095 , stdin );
322360 DO (mp_read_radix (& a , buf , 64 ));
323- FGETS (buf , 4095 , stdin );
361+ GET_TOKEN (buf , 4095 , stdin );
324362 DO (mp_read_radix (& b , buf , 64 ));
325363 DO (mp_div_2 (& a , & c ));
326364 if (mp_cmp (& c , & b ) != MP_EQ ) {
@@ -332,9 +370,9 @@ static int mtest_opponent(void)
332370 }
333371 } else if (strcmp (cmd , "mul2" ) == 0 ) {
334372 ++ mul2_n ;
335- FGETS (buf , 4095 , stdin );
373+ GET_TOKEN (buf , 4095 , stdin );
336374 DO (mp_read_radix (& a , buf , 64 ));
337- FGETS (buf , 4095 , stdin );
375+ GET_TOKEN (buf , 4095 , stdin );
338376 DO (mp_read_radix (& b , buf , 64 ));
339377 DO (mp_mul_2 (& a , & c ));
340378 if (mp_cmp (& c , & b ) != MP_EQ ) {
@@ -346,11 +384,11 @@ static int mtest_opponent(void)
346384 }
347385 } else if (strcmp (cmd , "add_d" ) == 0 ) {
348386 ++ add_d_n ;
349- FGETS (buf , 4095 , stdin );
387+ GET_TOKEN (buf , 4095 , stdin );
350388 DO (mp_read_radix (& a , buf , 64 ));
351- FGETS (buf , 4095 , stdin );
389+ GET_TOKEN (buf , 4095 , stdin );
352390 sscanf (buf , "%d" , & ix );
353- FGETS (buf , 4095 , stdin );
391+ GET_TOKEN (buf , 4095 , stdin );
354392 DO (mp_read_radix (& b , buf , 64 ));
355393 DO (mp_add_d (& a , (mp_digit )ix , & c ));
356394 if (mp_cmp (& b , & c ) != MP_EQ ) {
@@ -363,11 +401,11 @@ static int mtest_opponent(void)
363401 }
364402 } else if (strcmp (cmd , "sub_d" ) == 0 ) {
365403 ++ sub_d_n ;
366- FGETS (buf , 4095 , stdin );
404+ GET_TOKEN (buf , 4095 , stdin );
367405 DO (mp_read_radix (& a , buf , 64 ));
368- FGETS (buf , 4095 , stdin );
406+ GET_TOKEN (buf , 4095 , stdin );
369407 sscanf (buf , "%d" , & ix );
370- FGETS (buf , 4095 , stdin );
408+ GET_TOKEN (buf , 4095 , stdin );
371409 DO (mp_read_radix (& b , buf , 64 ));
372410 DO (mp_sub_d (& a , (mp_digit )ix , & c ));
373411 if (mp_cmp (& b , & c ) != MP_EQ ) {
0 commit comments