@@ -11,10 +11,49 @@ static void draw(const mp_int *a)
11
11
ndraw (a , "" );
12
12
}
13
13
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 ) \
15
54
{ \
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; } \
18
57
}
19
58
20
59
static int mtest_opponent (void )
@@ -76,17 +115,16 @@ static int mtest_opponent(void)
76
115
printf ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu " ,
77
116
add_n , sub_n , mul_n , div_n , sqr_n , mul2d_n , div2d_n , gcd_n , lcm_n ,
78
117
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 );
81
119
printf ("%-6s ]\r" , cmd );
82
120
fflush (stdout );
83
121
if (strcmp (cmd , "mul2d" ) == 0 ) {
84
122
++ mul2d_n ;
85
- FGETS (buf , 4095 , stdin );
123
+ GET_TOKEN (buf , 4095 , stdin );
86
124
DO (mp_read_radix (& a , buf , 64 ));
87
- FGETS (buf , 4095 , stdin );
125
+ GET_TOKEN (buf , 4095 , stdin );
88
126
sscanf (buf , "%u" , & rr );
89
- FGETS (buf , 4095 , stdin );
127
+ GET_TOKEN (buf , 4095 , stdin );
90
128
DO (mp_read_radix (& b , buf , 64 ));
91
129
92
130
DO (mp_mul_2d (& a , (int )rr , & a ));
@@ -99,11 +137,11 @@ static int mtest_opponent(void)
99
137
}
100
138
} else if (strcmp (cmd , "div2d" ) == 0 ) {
101
139
++ div2d_n ;
102
- FGETS (buf , 4095 , stdin );
140
+ GET_TOKEN (buf , 4095 , stdin );
103
141
DO (mp_read_radix (& a , buf , 64 ));
104
- FGETS (buf , 4095 , stdin );
142
+ GET_TOKEN (buf , 4095 , stdin );
105
143
sscanf (buf , "%u" , & rr );
106
- FGETS (buf , 4095 , stdin );
144
+ GET_TOKEN (buf , 4095 , stdin );
107
145
DO (mp_read_radix (& b , buf , 64 ));
108
146
109
147
DO (mp_div_2d (& a , (int )rr , & a , & e ));
@@ -119,11 +157,11 @@ static int mtest_opponent(void)
119
157
}
120
158
} else if (strcmp (cmd , "add" ) == 0 ) {
121
159
++ add_n ;
122
- FGETS (buf , 4095 , stdin );
160
+ GET_TOKEN (buf , 4095 , stdin );
123
161
DO (mp_read_radix (& a , buf , 64 ));
124
- FGETS (buf , 4095 , stdin );
162
+ GET_TOKEN (buf , 4095 , stdin );
125
163
DO (mp_read_radix (& b , buf , 64 ));
126
- FGETS (buf , 4095 , stdin );
164
+ GET_TOKEN (buf , 4095 , stdin );
127
165
DO (mp_read_radix (& c , buf , 64 ));
128
166
DO (mp_copy (& a , & d ));
129
167
DO (mp_add (& d , & b , & d ));
@@ -162,11 +200,11 @@ static int mtest_opponent(void)
162
200
163
201
} else if (strcmp (cmd , "sub" ) == 0 ) {
164
202
++ sub_n ;
165
- FGETS (buf , 4095 , stdin );
203
+ GET_TOKEN (buf , 4095 , stdin );
166
204
DO (mp_read_radix (& a , buf , 64 ));
167
- FGETS (buf , 4095 , stdin );
205
+ GET_TOKEN (buf , 4095 , stdin );
168
206
DO (mp_read_radix (& b , buf , 64 ));
169
- FGETS (buf , 4095 , stdin );
207
+ GET_TOKEN (buf , 4095 , stdin );
170
208
DO (mp_read_radix (& c , buf , 64 ));
171
209
DO (mp_copy (& a , & d ));
172
210
DO (mp_sub (& d , & b , & d ));
@@ -180,11 +218,11 @@ static int mtest_opponent(void)
180
218
}
181
219
} else if (strcmp (cmd , "mul" ) == 0 ) {
182
220
++ mul_n ;
183
- FGETS (buf , 4095 , stdin );
221
+ GET_TOKEN (buf , 4095 , stdin );
184
222
DO (mp_read_radix (& a , buf , 64 ));
185
- FGETS (buf , 4095 , stdin );
223
+ GET_TOKEN (buf , 4095 , stdin );
186
224
DO (mp_read_radix (& b , buf , 64 ));
187
- FGETS (buf , 4095 , stdin );
225
+ GET_TOKEN (buf , 4095 , stdin );
188
226
DO (mp_read_radix (& c , buf , 64 ));
189
227
DO (mp_copy (& a , & d ));
190
228
DO (mp_mul (& d , & b , & d ));
@@ -198,13 +236,13 @@ static int mtest_opponent(void)
198
236
}
199
237
} else if (strcmp (cmd , "div" ) == 0 ) {
200
238
++ div_n ;
201
- FGETS (buf , 4095 , stdin );
239
+ GET_TOKEN (buf , 4095 , stdin );
202
240
DO (mp_read_radix (& a , buf , 64 ));
203
- FGETS (buf , 4095 , stdin );
241
+ GET_TOKEN (buf , 4095 , stdin );
204
242
DO (mp_read_radix (& b , buf , 64 ));
205
- FGETS (buf , 4095 , stdin );
243
+ GET_TOKEN (buf , 4095 , stdin );
206
244
DO (mp_read_radix (& c , buf , 64 ));
207
- FGETS (buf , 4095 , stdin );
245
+ GET_TOKEN (buf , 4095 , stdin );
208
246
DO (mp_read_radix (& d , buf , 64 ));
209
247
210
248
DO (mp_div (& a , & b , & e , & f ));
@@ -222,9 +260,9 @@ static int mtest_opponent(void)
222
260
223
261
} else if (strcmp (cmd , "sqr" ) == 0 ) {
224
262
++ sqr_n ;
225
- FGETS (buf , 4095 , stdin );
263
+ GET_TOKEN (buf , 4095 , stdin );
226
264
DO (mp_read_radix (& a , buf , 64 ));
227
- FGETS (buf , 4095 , stdin );
265
+ GET_TOKEN (buf , 4095 , stdin );
228
266
DO (mp_read_radix (& b , buf , 64 ));
229
267
DO (mp_copy (& a , & c ));
230
268
DO (mp_sqr (& c , & c ));
@@ -237,11 +275,11 @@ static int mtest_opponent(void)
237
275
}
238
276
} else if (strcmp (cmd , "gcd" ) == 0 ) {
239
277
++ gcd_n ;
240
- FGETS (buf , 4095 , stdin );
278
+ GET_TOKEN (buf , 4095 , stdin );
241
279
DO (mp_read_radix (& a , buf , 64 ));
242
- FGETS (buf , 4095 , stdin );
280
+ GET_TOKEN (buf , 4095 , stdin );
243
281
DO (mp_read_radix (& b , buf , 64 ));
244
- FGETS (buf , 4095 , stdin );
282
+ GET_TOKEN (buf , 4095 , stdin );
245
283
DO (mp_read_radix (& c , buf , 64 ));
246
284
DO (mp_copy (& a , & d ));
247
285
DO (mp_gcd (& d , & b , & d ));
@@ -256,11 +294,11 @@ static int mtest_opponent(void)
256
294
}
257
295
} else if (strcmp (cmd , "lcm" ) == 0 ) {
258
296
++ lcm_n ;
259
- FGETS (buf , 4095 , stdin );
297
+ GET_TOKEN (buf , 4095 , stdin );
260
298
DO (mp_read_radix (& a , buf , 64 ));
261
- FGETS (buf , 4095 , stdin );
299
+ GET_TOKEN (buf , 4095 , stdin );
262
300
DO (mp_read_radix (& b , buf , 64 ));
263
- FGETS (buf , 4095 , stdin );
301
+ GET_TOKEN (buf , 4095 , stdin );
264
302
DO (mp_read_radix (& c , buf , 64 ));
265
303
DO (mp_copy (& a , & d ));
266
304
DO (mp_lcm (& d , & b , & d ));
@@ -275,13 +313,13 @@ static int mtest_opponent(void)
275
313
}
276
314
} else if (strcmp (cmd , "expt" ) == 0 ) {
277
315
++ expt_n ;
278
- FGETS (buf , 4095 , stdin );
316
+ GET_TOKEN (buf , 4095 , stdin );
279
317
DO (mp_read_radix (& a , buf , 64 ));
280
- FGETS (buf , 4095 , stdin );
318
+ GET_TOKEN (buf , 4095 , stdin );
281
319
DO (mp_read_radix (& b , buf , 64 ));
282
- FGETS (buf , 4095 , stdin );
320
+ GET_TOKEN (buf , 4095 , stdin );
283
321
DO (mp_read_radix (& c , buf , 64 ));
284
- FGETS (buf , 4095 , stdin );
322
+ GET_TOKEN (buf , 4095 , stdin );
285
323
DO (mp_read_radix (& d , buf , 64 ));
286
324
DO (mp_copy (& a , & e ));
287
325
DO (mp_exptmod (& e , & b , & c , & e ));
@@ -296,11 +334,11 @@ static int mtest_opponent(void)
296
334
}
297
335
} else if (strcmp (cmd , "invmod" ) == 0 ) {
298
336
++ inv_n ;
299
- FGETS (buf , 4095 , stdin );
337
+ GET_TOKEN (buf , 4095 , stdin );
300
338
DO (mp_read_radix (& a , buf , 64 ));
301
- FGETS (buf , 4095 , stdin );
339
+ GET_TOKEN (buf , 4095 , stdin );
302
340
DO (mp_read_radix (& b , buf , 64 ));
303
- FGETS (buf , 4095 , stdin );
341
+ GET_TOKEN (buf , 4095 , stdin );
304
342
DO (mp_read_radix (& c , buf , 64 ));
305
343
DO (mp_invmod (& a , & b , & d ));
306
344
DO (mp_mulmod (& d , & a , & b , & e ));
@@ -318,9 +356,9 @@ static int mtest_opponent(void)
318
356
319
357
} else if (strcmp (cmd , "div2" ) == 0 ) {
320
358
++ div2_n ;
321
- FGETS (buf , 4095 , stdin );
359
+ GET_TOKEN (buf , 4095 , stdin );
322
360
DO (mp_read_radix (& a , buf , 64 ));
323
- FGETS (buf , 4095 , stdin );
361
+ GET_TOKEN (buf , 4095 , stdin );
324
362
DO (mp_read_radix (& b , buf , 64 ));
325
363
DO (mp_div_2 (& a , & c ));
326
364
if (mp_cmp (& c , & b ) != MP_EQ ) {
@@ -332,9 +370,9 @@ static int mtest_opponent(void)
332
370
}
333
371
} else if (strcmp (cmd , "mul2" ) == 0 ) {
334
372
++ mul2_n ;
335
- FGETS (buf , 4095 , stdin );
373
+ GET_TOKEN (buf , 4095 , stdin );
336
374
DO (mp_read_radix (& a , buf , 64 ));
337
- FGETS (buf , 4095 , stdin );
375
+ GET_TOKEN (buf , 4095 , stdin );
338
376
DO (mp_read_radix (& b , buf , 64 ));
339
377
DO (mp_mul_2 (& a , & c ));
340
378
if (mp_cmp (& c , & b ) != MP_EQ ) {
@@ -346,11 +384,11 @@ static int mtest_opponent(void)
346
384
}
347
385
} else if (strcmp (cmd , "add_d" ) == 0 ) {
348
386
++ add_d_n ;
349
- FGETS (buf , 4095 , stdin );
387
+ GET_TOKEN (buf , 4095 , stdin );
350
388
DO (mp_read_radix (& a , buf , 64 ));
351
- FGETS (buf , 4095 , stdin );
389
+ GET_TOKEN (buf , 4095 , stdin );
352
390
sscanf (buf , "%d" , & ix );
353
- FGETS (buf , 4095 , stdin );
391
+ GET_TOKEN (buf , 4095 , stdin );
354
392
DO (mp_read_radix (& b , buf , 64 ));
355
393
DO (mp_add_d (& a , (mp_digit )ix , & c ));
356
394
if (mp_cmp (& b , & c ) != MP_EQ ) {
@@ -363,11 +401,11 @@ static int mtest_opponent(void)
363
401
}
364
402
} else if (strcmp (cmd , "sub_d" ) == 0 ) {
365
403
++ sub_d_n ;
366
- FGETS (buf , 4095 , stdin );
404
+ GET_TOKEN (buf , 4095 , stdin );
367
405
DO (mp_read_radix (& a , buf , 64 ));
368
- FGETS (buf , 4095 , stdin );
406
+ GET_TOKEN (buf , 4095 , stdin );
369
407
sscanf (buf , "%d" , & ix );
370
- FGETS (buf , 4095 , stdin );
408
+ GET_TOKEN (buf , 4095 , stdin );
371
409
DO (mp_read_radix (& b , buf , 64 ));
372
410
DO (mp_sub_d (& a , (mp_digit )ix , & c ));
373
411
if (mp_cmp (& b , & c ) != MP_EQ ) {
0 commit comments