Skip to content

Commit 0227d84

Browse files
committed
Addition of modifiers
1 parent 47b04cc commit 0227d84

File tree

3 files changed

+160
-31
lines changed

3 files changed

+160
-31
lines changed

demo/test.c

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -329,17 +329,45 @@ static int test_mp_printf_extension(void)
329329
char *fgets_return;
330330
int idx = 0;
331331

332-
const char *test_values[2] = {
332+
const char *test_values[41] = {
333333
"4DDCFDE0D20EF8663B34D19F829FDD",
334334
"-51D9769BDAE5B38121F2A31D881E5F"
335335
};
336-
const char *test_strings[12] = {
336+
const char *test_strings[] = {
337337
"Right aligned AAA 404289102523688521157725445716877277 BBB\n",
338338
"Left aligned AAA 404289102523688521157725445716877277 BBB\n",
339+
"Right aligned AAA +404289102523688521157725445716877277 BBB\n",
340+
"Left aligned AAA +404289102523688521157725445716877277 BBB\n",
341+
"Right aligned AAA 404289102523688521157725445716877277 BBB\n",
342+
"Left aligned AAA 404289102523688521157725445716877277 BBB\n",
343+
"hex with right align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
344+
"hex with left align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
345+
"hex with right align AAA +4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
346+
"hex with left align AAA +4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
347+
"hex with right align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
348+
"hex with left align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
339349
"hex with right align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
340350
"hex with left align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
351+
"hex with right align AAA +0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
352+
"hex with left align AAA +0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
353+
"hex with right align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
354+
"hex with left align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
355+
"Right aligned AAA -424986725583297217766029037085924959 BBB\n",
356+
"Left aligned AAA -424986725583297217766029037085924959 BBB\n",
357+
"Right aligned AAA -424986725583297217766029037085924959 BBB\n",
358+
"Left aligned AAA -424986725583297217766029037085924959 BBB\n",
341359
"Right aligned AAA -424986725583297217766029037085924959 BBB\n",
342360
"Left aligned AAA -424986725583297217766029037085924959 BBB\n",
361+
"hex with right align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
362+
"hex with left align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
363+
"hex with right align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
364+
"hex with left align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
365+
"hex with right align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
366+
"hex with left align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
367+
"hex with right align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
368+
"hex with left align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
369+
"hex with right align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
370+
"hex with left align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
343371
"hex with right align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
344372
"hex with left align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
345373
"Right aligned AAA 0 BBB\n",
@@ -348,24 +376,56 @@ static int test_mp_printf_extension(void)
348376
"hex with left align AAA 0x0 BBB\n"
349377
};
350378

351-
const char *print_strings[12] = {
379+
const char *print_strings[41] = {
352380
"Right aligned AAA %50N BBB\n",
353381
"Left aligned AAA %-50N BBB\n",
354-
"hex with right align AAA %#50N BBB\n",
355-
"hex with left align AAA %#-50N BBB\n",
356-
/* at idx == 4 mp_exch(&p,&q); */
382+
"Right aligned AAA %+50N BBB\n",
383+
"Left aligned AAA %+-50N BBB\n",
384+
"Right aligned AAA %' '50N BBB\n",
385+
"Left aligned AAA %' '-50N BBB\n",
386+
387+
"hex with right align AAA %50kN BBB\n",
388+
"hex with left align AAA %-50kN BBB\n",
389+
"hex with right align AAA %+50kN BBB\n",
390+
"hex with left align AAA %+-50kN BBB\n",
391+
"hex with right align AAA %' '50kN BBB\n",
392+
"hex with left align AAA %' '-50kN BBB\n",
393+
394+
"hex with right align AAA %#50kN BBB\n",
395+
"hex with left align AAA %#-50kN BBB\n",
396+
"hex with right align AAA %#+50kN BBB\n",
397+
"hex with left align AAA %#+-50kN BBB\n",
398+
"hex with right align AAA %#' '50kN BBB\n",
399+
"hex with left align AAA %#' '-50kN BBB\n",
400+
/* at idx == 18 mp_exch(&p,&q); */
357401
"Right aligned AAA %50N BBB\n",
358402
"Left aligned AAA %-50N BBB\n",
359-
"hex with right align AAA %#50N BBB\n",
360-
"hex with left align AAA %#-50N BBB\n",
361-
/* at idx == 8 mp_zero(&p); */
403+
"Right aligned AAA %+50N BBB\n",
404+
"Left aligned AAA %+-50N BBB\n",
405+
"Right aligned AAA %' '50N BBB\n",
406+
"Left aligned AAA %' '-50N BBB\n",
407+
408+
"hex with right align AAA %50kN BBB\n",
409+
"hex with left align AAA %-50kN BBB\n",
410+
"hex with right align AAA %+50kN BBB\n",
411+
"hex with left align AAA %+-50kN BBB\n",
412+
"hex with right align AAA %' '50kN BBB\n",
413+
"hex with left align AAA %' '-50kN BBB\n",
414+
415+
"hex with right align AAA %#50kN BBB\n",
416+
"hex with left align AAA %#-50kN BBB\n",
417+
"hex with right align AAA %#+50kN BBB\n",
418+
"hex with left align AAA %#+-50kN BBB\n",
419+
"hex with right align AAA %#' '50kN BBB\n",
420+
"hex with left align AAA %#' '-50kN BBB\n",
421+
422+
/* at idx == 36 mp_zero(&p); */
362423
"Right aligned AAA %50N BBB\n",
363424
"Left aligned AAA %-50N BBB\n",
364-
"hex with right align AAA %#50N BBB\n",
365-
"hex with left align AAA %#-50N BBB\n",
425+
"hex with right align AAA %#50kN BBB\n",
426+
"hex with left align AAA %#-50kN BBB\n",
366427
};
367428

368-
369429
mp_int p, q;
370430

371431
test_file = fopen("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a", "w+");
@@ -382,11 +442,11 @@ static int test_mp_printf_extension(void)
382442

383443
DO(mp_printf_extension());
384444

385-
for (idx = 0; idx < 12; idx++) {
386-
if (idx == 4) {
445+
for (idx = 0; idx < 40; idx++) {
446+
if (idx == 18) {
387447
mp_exch(&p,&q);
388448
}
389-
if (idx == 8) {
449+
if (idx == 36) {
390450
mp_zero(&p);
391451
}
392452
characters_printed = fprintf(test_file, print_strings[idx], &p);

doc/bn.tex

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,22 +2423,31 @@ \subsection{To ASCII}
24232423

24242424
Also available in that case is a small extension to \texttt{printf(3)} to print
24252425
a big integer in a formated way. Not every formating is supported (e.g.: no
2426-
thousands separator) but normal alignment works well. Only representations available
2427-
are hexadecimal (slaways with prefix) and decimal.
2426+
thousands separator, no leading zeros) but normal alignment works well.
2427+
2428+
Modifiers (\texttt{k,b,r,@})\footnote{There are only so many letters in the alphabet
2429+
and almost all useful ones were already taken, so it is \texttt{k} for hexadecimal representation like in ``eks'' and
2430+
\texttt{r} like in Rear Admiral Grace Brewster Murray Hopper (07 r's) for octals.}
2431+
come before the specifier. See example below for the necessary details.
2432+
2433+
This function is not threadsafe!
24282434
\index{mp\_printf\_extension}
24292435
\begin{alltt}
24302436
mp_err p_printf_extension(void);
24312437
\end{alltt}
24322438
Example:
24332439
\begin{alltt}
2434-
24352440
/* Switch on the extension */
24362441
if((err = mp_printf_extension(void)) != MP_OKAY) goto LTM_ERR;
24372442
...
24382443
/* Do some calculation */
24392444
...
2440-
/* print them out */
2441-
printf("In hex: %#N and in decimal: %N\textbackslash{}n");
2445+
/* print the results */
2446+
2447+
printf("In hex: %kN and in decimal: %N\textbackslash{}n", &a, &a);
2448+
printf("In bin: %bN and in base 64: %@N\textbackslash{}n", &a, &a);
2449+
printf("And finally octal: %oN \textbackslash{}n", &a);
2450+
24422451
\end{alltt}
24432452

24442453
\subsection{From ASCII}

mp_printf_extension.c

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,69 @@ mp_err mp_printf_extension(void)
1414

1515
/* TODO: find min version of glibc. Seems to be >2.9, check */
1616
#if (!(defined MP_NO_FILE) && (defined __GLIBC__))
17+
18+
/* The functions in printf.h are not threadsafe to begin with */
19+
static int mp_hexmod = 0;
20+
static int mp_octmod = 0;
21+
static int mp_binmod = 0;
22+
static int mp_basmod = 0;
23+
1724
#include <printf.h>
1825
static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, const void *const *args)
1926
{
2027
mp_err err = MP_OKAY;
2128
const mp_int *a;
2229
char *buf, *start_buf;
23-
int base = 10;
30+
int base;
2431
size_t size, written;
2532
int len;
2633
size_t extra_len = 0u;
2734
int idx = 0;
35+
char *prefixed_zero = "";
2836

2937
/* Fiddle our bigint out of the argument list */
3038
a = *((const mp_int * const *)(args[0]));
3139

32-
/* The only way to change base without changing identifier */
33-
if (info->alt == 1u) {
40+
if ((info->user & mp_hexmod) == 1) {
3441
base = 16;
42+
} else if ((info->user & mp_binmod) == 1) {
43+
base = 2;
44+
} else if ((info->user & mp_octmod) == 1) {
45+
base = 8;
46+
} else if ((info->user & mp_basmod) == 1) {
47+
base = 64;
48+
} else {
49+
base = 10;
3550
}
3651

3752
if (mp_iszero(a)) {
38-
return fprintf(stream, "%*s",
39-
(info->left ? -info->width : info->width),
40-
(base == 16 ? "0x0" : "0"));
53+
if (info->alt == 1u) {
54+
switch (base) {
55+
case 2:
56+
prefixed_zero = "0b0";
57+
break;
58+
case 8:
59+
prefixed_zero = "0o0";
60+
break;
61+
case 16:
62+
prefixed_zero = "0x0";
63+
break;
64+
case 64:
65+
prefixed_zero = "0@0";
66+
break;
67+
}
68+
return fprintf(stream, "%*s", (info->left ? -info->width : info->width), prefixed_zero);
69+
}
70+
return fprintf(stream, "%*s", (info->left ? -info->width : info->width), "0");
4171
}
4272

43-
4473
/* Get some estimate of the size of "a" in the given base */
4574
if ((err = mp_radix_size_overestimate(a, base, &size)) != MP_OKAY) {
4675
return -1;
4776
}
4877

4978
/* The minus sign comes before the "0x", we have to take precaution */
50-
if (base == 16) {
79+
if ((base != 10) && (info->alt == 1u)) {
5180
extra_len += 2;
5281
}
5382

@@ -77,23 +106,37 @@ static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, con
77106

78107
if (mp_isneg(a)) {
79108
start_buf[idx++] = '-';
80-
} else {
109+
} else {
81110
if (info->space) {
82111
start_buf[idx++] = ' ';
83112
} else if (info->showsign) {
84113
start_buf[idx++] = '+';
85114
}
86115
}
87116

88-
if (base == 16) {
117+
if ((base != 10) && (info->alt == 1u)) {
89118
start_buf[idx++] = '0';
90-
start_buf[idx] = 'x';
119+
switch (base) {
120+
case 2:
121+
start_buf[idx] = 'b';
122+
break;
123+
case 8:
124+
start_buf[idx] = 'o';
125+
break;
126+
case 16:
127+
start_buf[idx] = 'x';
128+
break;
129+
case 64:
130+
start_buf[idx] = '@';
131+
break;
132+
}
91133
}
92134
len = fprintf(stream, "%*s", (info->left ? -info->width : info->width), start_buf);
93135

94136
MP_FREE(start_buf, size + extra_len);
95137
return len;
96138
}
139+
97140
static int s_mp_print_mp_int_arginfo(const struct printf_info *info, size_t n,
98141
int *argtypes, int *size)
99142
{
@@ -116,6 +159,23 @@ mp_err mp_printf_extension(void)
116159
err = MP_VAL;
117160
}
118161

162+
mp_hexmod = register_printf_modifier(L"k");
163+
if (mp_hexmod < 0) {
164+
return MP_VAL;
165+
}
166+
mp_binmod = register_printf_modifier(L"b");
167+
if (mp_binmod < 0) {
168+
return MP_VAL;
169+
}
170+
mp_octmod = register_printf_modifier(L"r");
171+
if (mp_octmod < 0) {
172+
return MP_VAL;
173+
}
174+
mp_basmod = register_printf_modifier(L"@");
175+
if (mp_basmod < 0) {
176+
return MP_VAL;
177+
}
178+
119179
return err;
120180
}
121181
#endif

0 commit comments

Comments
 (0)