Skip to content

Commit 340c49f

Browse files
committed
Addition of modifiers
1 parent d7dec62 commit 340c49f

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
@@ -335,17 +335,45 @@ static int test_mp_printf_extension(void)
335335
char *fgets_return;
336336
int idx = 0;
337337

338-
const char *test_values[2] = {
338+
const char *test_values[41] = {
339339
"4DDCFDE0D20EF8663B34D19F829FDD",
340340
"-51D9769BDAE5B38121F2A31D881E5F"
341341
};
342-
const char *test_strings[12] = {
342+
const char *test_strings[] = {
343343
"Right aligned AAA 404289102523688521157725445716877277 BBB\n",
344344
"Left aligned AAA 404289102523688521157725445716877277 BBB\n",
345+
"Right aligned AAA +404289102523688521157725445716877277 BBB\n",
346+
"Left aligned AAA +404289102523688521157725445716877277 BBB\n",
347+
"Right aligned AAA 404289102523688521157725445716877277 BBB\n",
348+
"Left aligned AAA 404289102523688521157725445716877277 BBB\n",
349+
"hex with right align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
350+
"hex with left align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
351+
"hex with right align AAA +4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
352+
"hex with left align AAA +4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
353+
"hex with right align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
354+
"hex with left align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
345355
"hex with right align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
346356
"hex with left align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
357+
"hex with right align AAA +0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
358+
"hex with left align AAA +0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
359+
"hex with right align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
360+
"hex with left align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n",
361+
"Right aligned AAA -424986725583297217766029037085924959 BBB\n",
362+
"Left aligned AAA -424986725583297217766029037085924959 BBB\n",
363+
"Right aligned AAA -424986725583297217766029037085924959 BBB\n",
364+
"Left aligned AAA -424986725583297217766029037085924959 BBB\n",
347365
"Right aligned AAA -424986725583297217766029037085924959 BBB\n",
348366
"Left aligned AAA -424986725583297217766029037085924959 BBB\n",
367+
"hex with right align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
368+
"hex with left align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
369+
"hex with right align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
370+
"hex with left align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
371+
"hex with right align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
372+
"hex with left align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n",
373+
"hex with right align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
374+
"hex with left align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
375+
"hex with right align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
376+
"hex with left align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
349377
"hex with right align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
350378
"hex with left align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n",
351379
"Right aligned AAA 0 BBB\n",
@@ -354,24 +382,56 @@ static int test_mp_printf_extension(void)
354382
"hex with left align AAA 0x0 BBB\n"
355383
};
356384

357-
const char *print_strings[12] = {
385+
const char *print_strings[41] = {
358386
"Right aligned AAA %50N BBB\n",
359387
"Left aligned AAA %-50N BBB\n",
360-
"hex with right align AAA %#50N BBB\n",
361-
"hex with left align AAA %#-50N BBB\n",
362-
/* at idx == 4 mp_exch(&p,&q); */
388+
"Right aligned AAA %+50N BBB\n",
389+
"Left aligned AAA %+-50N BBB\n",
390+
"Right aligned AAA %' '50N BBB\n",
391+
"Left aligned AAA %' '-50N BBB\n",
392+
393+
"hex with right align AAA %50kN BBB\n",
394+
"hex with left align AAA %-50kN BBB\n",
395+
"hex with right align AAA %+50kN BBB\n",
396+
"hex with left align AAA %+-50kN BBB\n",
397+
"hex with right align AAA %' '50kN BBB\n",
398+
"hex with left align AAA %' '-50kN BBB\n",
399+
400+
"hex with right align AAA %#50kN BBB\n",
401+
"hex with left align AAA %#-50kN BBB\n",
402+
"hex with right align AAA %#+50kN BBB\n",
403+
"hex with left align AAA %#+-50kN BBB\n",
404+
"hex with right align AAA %#' '50kN BBB\n",
405+
"hex with left align AAA %#' '-50kN BBB\n",
406+
/* at idx == 18 mp_exch(&p,&q); */
363407
"Right aligned AAA %50N BBB\n",
364408
"Left aligned AAA %-50N BBB\n",
365-
"hex with right align AAA %#50N BBB\n",
366-
"hex with left align AAA %#-50N BBB\n",
367-
/* at idx == 8 mp_zero(&p); */
409+
"Right aligned AAA %+50N BBB\n",
410+
"Left aligned AAA %+-50N BBB\n",
411+
"Right aligned AAA %' '50N BBB\n",
412+
"Left aligned AAA %' '-50N BBB\n",
413+
414+
"hex with right align AAA %50kN BBB\n",
415+
"hex with left align AAA %-50kN BBB\n",
416+
"hex with right align AAA %+50kN BBB\n",
417+
"hex with left align AAA %+-50kN BBB\n",
418+
"hex with right align AAA %' '50kN BBB\n",
419+
"hex with left align AAA %' '-50kN BBB\n",
420+
421+
"hex with right align AAA %#50kN BBB\n",
422+
"hex with left align AAA %#-50kN BBB\n",
423+
"hex with right align AAA %#+50kN BBB\n",
424+
"hex with left align AAA %#+-50kN BBB\n",
425+
"hex with right align AAA %#' '50kN BBB\n",
426+
"hex with left align AAA %#' '-50kN BBB\n",
427+
428+
/* at idx == 36 mp_zero(&p); */
368429
"Right aligned AAA %50N BBB\n",
369430
"Left aligned AAA %-50N BBB\n",
370-
"hex with right align AAA %#50N BBB\n",
371-
"hex with left align AAA %#-50N BBB\n",
431+
"hex with right align AAA %#50kN BBB\n",
432+
"hex with left align AAA %#-50kN BBB\n",
372433
};
373434

374-
375435
mp_int p, q;
376436

377437
test_file = fopen("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a", "w+");
@@ -388,11 +448,11 @@ static int test_mp_printf_extension(void)
388448

389449
DO(mp_printf_extension());
390450

391-
for (idx = 0; idx < 12; idx++) {
392-
if (idx == 4) {
451+
for (idx = 0; idx < 40; idx++) {
452+
if (idx == 18) {
393453
mp_exch(&p,&q);
394454
}
395-
if (idx == 8) {
455+
if (idx == 36) {
396456
mp_zero(&p);
397457
}
398458
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)