Skip to content

Commit 6edd7e1

Browse files
committed
printing mp_digit
1 parent fe3bd2d commit 6edd7e1

File tree

3 files changed

+240
-7
lines changed

3 files changed

+240
-7
lines changed

demo/test.c

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,28 @@ static int test_mp_printf_extension(void)
373373
"Right aligned AAA 0 BBB\n",
374374
"Left aligned AAA 0 BBB\n",
375375
"hex with right align AAA 0x0 BBB\n",
376-
"hex with left align AAA 0x0 BBB\n"
376+
"hex with left align AAA 0x0 BBB\n",
377+
"Right aligned AAA 10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n",
378+
"Left aligned AAA 10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n",
379+
"Right aligned AAA +10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n",
380+
"Left aligned AAA +10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n",
381+
"Right aligned AAA 10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n",
382+
"Left aligned AAA 10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n",
383+
"Right aligned AAA JTpzuD8E+6OxDD6VWf/T BBB\n",
384+
"Left aligned AAA JTpzuD8E+6OxDD6VWf/T BBB\n",
385+
"Right aligned AAA +JTpzuD8E+6OxDD6VWf/T BBB\n",
386+
"Left aligned AAA +JTpzuD8E+6OxDD6VWf/T BBB\n",
387+
"Right aligned AAA JTpzuD8E+6OxDD6VWf/T BBB\n",
388+
"Left aligned AAA JTpzuD8E+6OxDD6VWf/T BBB\n",
389+
"Right aligned AAA 0@JTpzuD8E+6OxDD6VWf/T BBB\n",
390+
"Left aligned AAA 0@JTpzuD8E+6OxDD6VWf/T BBB\n",
391+
"Right aligned AAA +0@JTpzuD8E+6OxDD6VWf/T BBB\n",
392+
"Left aligned AAA +0@JTpzuD8E+6OxDD6VWf/T BBB\n",
393+
"Right aligned AAA 0@JTpzuD8E+6OxDD6VWf/T BBB\n",
394+
"Left aligned AAA 0@JTpzuD8E+6OxDD6VWf/T BBB\n"
377395
};
378396

379-
const char *print_strings[41] = {
397+
const char *print_strings[58] = {
380398
"Right aligned AAA %50N BBB\n",
381399
"Left aligned AAA %-50N BBB\n",
382400
"Right aligned AAA %+50N BBB\n",
@@ -424,6 +442,25 @@ static int test_mp_printf_extension(void)
424442
"Left aligned AAA %-50N BBB\n",
425443
"hex with right align AAA %#50kN BBB\n",
426444
"hex with left align AAA %#-50kN BBB\n",
445+
/* at idx == 40 mp_exch(&p,&q); */
446+
"Right aligned AAA %50bN BBB\n",
447+
"Left aligned AAA %-50bN BBB\n",
448+
"Right aligned AAA %+50bN BBB\n",
449+
"Left aligned AAA %+-50bN BBB\n",
450+
"Right aligned AAA %' '50bN BBB\n",
451+
"Left aligned AAA %' '-50bN BBB\n",
452+
"Right aligned AAA %50@N BBB\n",
453+
"Left aligned AAA %-50@N BBB\n",
454+
"Right aligned AAA %+50@N BBB\n",
455+
"Left aligned AAA %+-50@N BBB\n",
456+
"Right aligned AAA %' '50@N BBB\n",
457+
"Left aligned AAA %' '-50@N BBB\n",
458+
"Right aligned AAA %#50@N BBB\n",
459+
"Left aligned AAA %#-50@N BBB\n",
460+
"Right aligned AAA %#+50@N BBB\n",
461+
"Left aligned AAA %#+-50@N BBB\n",
462+
"Right aligned AAA %#' '50@N BBB\n",
463+
"Left aligned AAA %#' '-50@N BBB\n"
427464
};
428465

429466
mp_int p, q;
@@ -442,13 +479,16 @@ static int test_mp_printf_extension(void)
442479

443480
DO(mp_printf_extension());
444481

445-
for (idx = 0; idx < 40; idx++) {
482+
for (idx = 0; idx < 52; idx++) {
446483
if (idx == 18) {
447484
mp_exch(&p,&q);
448485
}
449486
if (idx == 36) {
450487
mp_zero(&p);
451488
}
489+
if (idx == 40) {
490+
mp_exch(&p,&q);
491+
}
452492
characters_printed = fprintf(test_file, print_strings[idx], &p);
453493
slen = strlen(test_strings[idx]);
454494
if ((characters_printed - (int)slen) != 0) {

mp_printf_extension.c

Lines changed: 193 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,53 @@ static int mp_octmod = 0;
1616
static int mp_binmod = 0;
1717
static int mp_basmod = 0;
1818

19+
static void s_mp_str_reverse(char *s, int len)
20+
{
21+
int x = 0, y = len - 1;
22+
char t;
23+
24+
while (x < y) {
25+
t = s[x];
26+
s[x] = s[y];
27+
s[y] = t;
28+
x++;
29+
y--;
30+
}
31+
}
32+
static const char s_mp_base64[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
33+
/* TODO: formatting. Precision and thousands separators (latter needs locale environment, so prob. not) */
34+
static int s_mp_print_mp_digit_binary(mp_digit number, mp_digit base, bool prefix, char *buffer)
35+
{
36+
mp_digit cp, digit;
37+
int i = 0;
38+
39+
cp = number;
40+
while (cp != 0) {
41+
digit = cp % base;
42+
cp /= base;
43+
buffer[i++] = s_mp_base64[digit];
44+
}
45+
if (prefix && (base != 10)) {
46+
switch (base) {
47+
case 2:
48+
buffer[i++] = 'b';
49+
break;
50+
case 8:
51+
buffer[i++] = 'o';
52+
break;
53+
case 16:
54+
buffer[i++] = 'x';
55+
break;
56+
case 64:
57+
buffer[i++] = '@';
58+
break;
59+
}
60+
buffer[i++] = '0';
61+
}
62+
s_mp_str_reverse(buffer, i);
63+
return i;
64+
}
65+
1966
#include <printf.h>
2067
static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, const void *const *args)
2168
{
@@ -29,13 +76,13 @@ static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, con
2976
/* Fiddle our bigint out of the argument list */
3077
a = *((const mp_int * const *)(args[0]));
3178

32-
if ((info->user & mp_hexmod) == 1) {
79+
if (info->user & mp_hexmod) {
3380
base = 16;
34-
} else if ((info->user & mp_binmod) == 1) {
81+
} else if (info->user & mp_binmod) {
3582
base = 2;
36-
} else if ((info->user & mp_octmod) == 1) {
83+
} else if (info->user & mp_octmod) {
3784
base = 8;
38-
} else if ((info->user & mp_basmod) == 1) {
85+
} else if (info->user & mp_basmod) {
3986
base = 64;
4087
} else {
4188
base = 10;
@@ -129,6 +176,128 @@ static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, con
129176
return len;
130177
}
131178

179+
#include <inttypes.h>
180+
#define LTM_FORMAT_BUFSIZ 127
181+
static int s_mp_print_mp_digit(FILE *stream, const struct printf_info *info, const void *const *args)
182+
{
183+
mp_digit a;
184+
int len = 0, base = 10, l = 0;
185+
char format[LTM_FORMAT_BUFSIZ] = {0};
186+
char *format_p;
187+
char buf[LTM_FORMAT_BUFSIZ] = {0};
188+
189+
a = *((mp_digit const *)(args[0]));
190+
191+
format_p = format;
192+
193+
*format_p++ = '%';
194+
len++;
195+
if (info->alt) {
196+
*format_p++ = '#';
197+
len++;
198+
}
199+
/* Not with an "u" specifier
200+
if(info->space){
201+
*format_p++ = ' ';
202+
len++;
203+
}
204+
*/
205+
if (info->group) {
206+
*format_p++ = '\'';
207+
len++;
208+
}
209+
/* Not with an "u" specifier
210+
if(info->showsign){
211+
*format_p++ = '+';
212+
len++;
213+
}
214+
*/
215+
if (info->width > 0) {
216+
/* ceil(log10(2^64)) + 1 */
217+
if ((len + 21) >= LTM_FORMAT_BUFSIZ) {
218+
return -1;
219+
}
220+
/* TODO: such a large cannon for such a tiny sparrow? */
221+
l = sprintf(format_p, "%d", info->left ? -info->width : info->width);
222+
format_p += l;
223+
len += l;
224+
}
225+
226+
if (info->prec > 0) {
227+
if ((len + 21) >= LTM_FORMAT_BUFSIZ) {
228+
return -1;
229+
}
230+
*format_p++ = '.';
231+
l = sprintf(format_p, "%d", info->prec);
232+
format_p += l;
233+
234+
}
235+
/* strlen("llu") + 1 */
236+
if ((len + 4) >= LTM_FORMAT_BUFSIZ) {
237+
return -1;
238+
}
239+
/* TODO: Single difference is PRT_64 to PRT_32 */
240+
#ifdef MP_64BIT
241+
if (info->user & mp_hexmod) {
242+
len += sprintf(format_p, "%s", ""PRIx64"");
243+
} else if ((info->user & mp_binmod)) {
244+
if ((len + 66) >= LTM_FORMAT_BUFSIZ) {
245+
return -1;
246+
}
247+
(void)s_mp_print_mp_digit_binary(a, 2, info->alt, buf);
248+
*format_p++ = 's';
249+
len++;
250+
base = 2;
251+
} else if (info->user & mp_octmod) {
252+
len += sprintf(format_p, "%s", ""PRIo64"");
253+
} else if (info->user & mp_basmod) {
254+
if ((len + 12) >= LTM_FORMAT_BUFSIZ) {
255+
return -1;
256+
}
257+
(void)s_mp_print_mp_digit_binary(a, 64, info->alt, buf);
258+
*format_p++ = 's';
259+
len++;
260+
base = 64;
261+
} else {
262+
len += sprintf(format_p, "%s", ""PRIu64"");
263+
}
264+
#else
265+
if (info->user & mp_hexmod) {
266+
len += sprintf(format_p, "%s", ""PRIx32"");
267+
} else if (info->user & mp_binmod) {
268+
if ((len + 34) >= LTM_FORMAT_BUFSIZ) {
269+
return -1;
270+
}
271+
(void)s_mp_print_mp_digit_binary(a, 2, info->alt, buf);
272+
*format_p++ = 's';
273+
len++;
274+
base = 2;
275+
} else if (info->user & mp_octmod) {
276+
len += sprintf(format_p, "%s", ""PRIo32"");
277+
} else if (info->user & mp_basmod) {
278+
if ((len + 7) >= LTM_FORMAT_BUFSIZ) {
279+
return -1;
280+
}
281+
(void)s_mp_print_mp_digit_binary(a, 64, info->alt, buf);
282+
*format_p++ = 's';
283+
len++;
284+
base = 64;
285+
} else {
286+
len += sprintf(format_p, "%s", ""PRIu32"");
287+
}
288+
/* Unlikely. */
289+
if (len >= LTM_FORMAT_BUFSIZ) {
290+
return -1;
291+
}
292+
#endif
293+
if ((base == 2) || (base == 64)) {
294+
len = fprintf(stream, format, buf);
295+
} else {
296+
len = fprintf(stream, format, a);
297+
}
298+
return len;
299+
}
300+
132301
static int s_mp_print_mp_int_arginfo(const struct printf_info *info, size_t n,
133302
int *argtypes, int *size)
134303
{
@@ -141,6 +310,22 @@ static int s_mp_print_mp_int_arginfo(const struct printf_info *info, size_t n,
141310
return 1;
142311
}
143312

313+
static int s_mp_print_mp_digit_arginfo(const struct printf_info *info, size_t n,
314+
int *argtypes, int *size)
315+
{
316+
(void)(info);
317+
318+
if (n > 0) {
319+
#ifdef MP_16BIT
320+
argtypes[0] = PA_INT | PA_FLAG_LONG_LONG;
321+
#else
322+
argtypes[0] = PA_INT | PA_FLAG_LONG;
323+
#endif
324+
size[0] = sizeof(mp_digit);
325+
}
326+
return 1;
327+
}
328+
144329
/* Fixed value: 'N' */
145330
mp_err mp_printf_extension(void)
146331
{
@@ -150,6 +335,10 @@ mp_err mp_printf_extension(void)
150335
/* Out of spec, which cannot happen if spec is fixed as we do it here. */
151336
err = MP_VAL;
152337
}
338+
/* We don't need two different functions. The specifier is in printf_info.spec (a wchar_t) */
339+
if (register_printf_specifier('M', s_mp_print_mp_digit, s_mp_print_mp_digit_arginfo)< 0) {
340+
err = MP_VAL;
341+
}
153342

154343
mp_hexmod = register_printf_modifier(L"k");
155344
if (mp_hexmod < 0) {

tommath_class.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,12 @@
718718
#if defined(MP_PRINTF_EXTENSION_C)
719719
# define MP_RADIX_SIZE_OVERESTIMATE_C
720720
# define MP_TO_RADIX_C
721+
# define S_MP_PRINT_MP_DIGIT_ARGINFO_C
722+
# define S_MP_PRINT_MP_DIGIT_BINARY_C
723+
# define S_MP_PRINT_MP_DIGIT_C
721724
# define S_MP_PRINT_MP_INT_ARGINFO_C
722725
# define S_MP_PRINT_MP_INT_C
726+
# define S_MP_STR_REVERSE_C
723727
#endif
724728

725729
#if defined(MP_RADIX_SIZE_C)

0 commit comments

Comments
 (0)