Skip to content

Commit 24ac0de

Browse files
committed
Replaced "fgets" with a "get_token" function in demo/mtest_opponent.c
1 parent 1b3792b commit 24ac0de

File tree

2 files changed

+106
-52
lines changed

2 files changed

+106
-52
lines changed

demo/mtest_opponent.c

Lines changed: 87 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2059
static 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) {

doc/bn.tex

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,9 +2409,25 @@ \subsection{From ASCII}
24092409
mp_err mp_read_radix (mp_int *a, const char *str, int radix);
24102410
\end{alltt}
24112411
This will read a \texttt{NUL} terminated string in base \texttt{radix} from \texttt{str} into $a$.
2412-
It will stop reading when it reads a character it does not recognize (which happens to include the
2413-
\texttt{NUL} char\dots imagine that\dots). A single leading $-$ (ASCII \texttt{0x20}) sign can be
2414-
used to denote a negative number. The input encoding is currently restricted to ASCII only.
2412+
Valid values of \texttt{radix} are in the range $[2, 64]$.
2413+
%It will stop reading when it reads a character it does not recognize (which happens to include the
2414+
%\texttt{NUL} char\dots imagine that\dots).
2415+
2416+
It returns \texttt{MP\_VAL} for any character {\em not} in the range allowed for the given base.
2417+
The list of characters is the same as for base-64 and also in the same order.
2418+
\begin{alltt}
2419+
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/
2420+
\end{alltt}
2421+
2422+
A single leading $-$ (ASCII \texttt{0x20}) sign can be used to denote a negative number. The
2423+
plus sign $+$ (ASCII \texttt{0x2b}) is already in use (bases 63 and 64) and cannot be used
2424+
to denote positivity, no matter how good the mood of the number is.
2425+
2426+
For all bases smaller than 37 the list is case-insensitive, e.g.:~the two hexadecimal numbers
2427+
$123abc_{16} = 1194684_{10}$ and $123ABC_{16} = 1194684_{10}$ are equivalent but the two base
2428+
64 numbers $123abc_{64} = 1108232550_{10}$ and $123ABC_{64} = 1108124364_{10}$ are not.
2429+
2430+
The input encoding is currently restricted to ASCII only.
24152431

24162432
If \texttt{MP\_NO\_FILE} is not defined a function to read from a file is also available.
24172433
\index{mp\_fread}

0 commit comments

Comments
 (0)