Skip to content

Commit 6426c46

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

File tree

2 files changed

+98
-51
lines changed

2 files changed

+98
-51
lines changed

demo/mtest_opponent.c

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

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

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)