Skip to content

Commit 0f05820

Browse files
committed
old method
1 parent 6edd7e1 commit 0f05820

File tree

2 files changed

+97
-30
lines changed

2 files changed

+97
-30
lines changed

demo/test.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ static int test_mp_printf_extension(void)
494494
if ((characters_printed - (int)slen) != 0) {
495495
fprintf(stderr, "%d test_mp_print_extension: failed to print o:%zu t:%d\n",
496496
idx, slen, characters_printed);
497+
fprintf(stderr,"\"%s\"\n",test_strings[idx]);
498+
fprintf(stderr,"\"%s\"\n",print_strings[idx]);
497499
goto LBL_ERR;
498500
}
499501
if (!write_only) {

mp_printf_extension.c

Lines changed: 95 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static void s_mp_str_reverse(char *s, int len)
3030
}
3131
}
3232
static const char s_mp_base64[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
33-
/* TODO: formatting. Precision and thousands separators (latter needs locale environment, so prob. not) */
33+
/* TODO: thousands separators (needs locale environment, so prob. not) */
3434
static int s_mp_print_mp_digit_binary(mp_digit number, mp_digit base, bool prefix, char *buffer)
3535
{
3636
mp_digit cp, digit;
@@ -63,14 +63,19 @@ static int s_mp_print_mp_digit_binary(mp_digit number, mp_digit base, bool prefi
6363
return i;
6464
}
6565

66+
/* Function for the output to a stream, adjust to your needs */
67+
#ifndef MP_FPUTC
68+
#define MP_FPUTC(c, stream) fputc((c), (stream))
69+
#endif
70+
6671
#include <printf.h>
6772
static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, const void *const *args)
6873
{
6974
mp_err err = MP_OKAY;
7075
const mp_int *a;
7176
char *buf, *start_buf;
72-
char *prefixed_zero = "";
73-
int base, len, idx = 0;
77+
int base, length_number, min_width;
78+
int idx = 0, fill_zeros = 0, length_printed = 0, i;
7479
size_t size, written, extra_len = 0u;
7580

7681
/* Fiddle our bigint out of the argument list */
@@ -88,27 +93,6 @@ static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, con
8893
base = 10;
8994
}
9095

91-
if (mp_iszero(a)) {
92-
if (info->alt == 1u) {
93-
switch (base) {
94-
case 2:
95-
prefixed_zero = "0b0";
96-
break;
97-
case 8:
98-
prefixed_zero = "0o0";
99-
break;
100-
case 16:
101-
prefixed_zero = "0x0";
102-
break;
103-
case 64:
104-
prefixed_zero = "0@0";
105-
break;
106-
}
107-
return fprintf(stream, "%*s", (info->left ? -info->width : info->width), prefixed_zero);
108-
}
109-
return fprintf(stream, "%*s", (info->left ? -info->width : info->width), "0");
110-
}
111-
11296
/* Get some estimate of the size of "a" in the given base */
11397
if ((err = mp_radix_size_overestimate(a, base, &size)) != MP_OKAY) {
11498
return -1;
@@ -123,6 +107,14 @@ static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, con
123107
extra_len++;
124108
}
125109

110+
/* Minimum length, fill with leading zeros if not reached */
111+
if (info->prec > 0) {
112+
if (info->prec > (int)size) {
113+
/* exact number is in written later */
114+
size = (size_t)info->prec;
115+
}
116+
}
117+
126118
buf = MP_MALLOC(size + extra_len);
127119
if (buf == NULL) {
128120
return -1;
@@ -138,6 +130,7 @@ static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, con
138130
buf--;
139131
}
140132

133+
141134
if ((err = mp_to_radix(a, buf, size, &written, base)) != MP_OKAY) {
142135
MP_FREE(start_buf, size + extra_len);
143136
return -1;
@@ -146,34 +139,106 @@ static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, con
146139
if (mp_isneg(a)) {
147140
start_buf[idx++] = '-';
148141
} else {
142+
/* For alignment of numbers with and without a sign. */
149143
if (info->space) {
150144
start_buf[idx++] = ' ';
145+
/* Always print the sign (default is for negative numbers only) */
151146
} else if (info->showsign) {
152147
start_buf[idx++] = '+';
153148
}
154149
}
155150

151+
/* "info->alt" holds the information if a prefix is wanted */
156152
if ((base != 10) && (info->alt == 1u)) {
157153
start_buf[idx++] = '0';
158154
switch (base) {
159155
case 2:
160-
start_buf[idx] = 'b';
156+
/* Non-standard extension */
157+
start_buf[idx++] = 'b';
161158
break;
162159
case 8:
163-
start_buf[idx] = 'o';
160+
start_buf[idx++] = 'o';
164161
break;
165162
case 16:
166-
start_buf[idx] = 'x';
163+
start_buf[idx++] = 'x';
167164
break;
168165
case 64:
169-
start_buf[idx] = '@';
166+
/* Non-standard extension */
167+
start_buf[idx++] = '@';
170168
break;
171169
}
172170
}
173-
len = fprintf(stream, "%*s", (info->left ? -info->width : info->width), start_buf);
171+
172+
/* As mentioned above: the minus sign gets overwritten. */
173+
if (mp_isneg(a)) {
174+
written--;
175+
}
176+
177+
/* Length of the number with the prefix but without the leading zeros (prec) */
178+
length_number = idx + (int)written - 1;
179+
180+
/* Include minimum length if set*/
181+
if (info->prec > length_number) {
182+
min_width = info->width - info->prec;
183+
} else {
184+
min_width = info->width - length_number;
185+
}
186+
187+
/* Print padding to the left for alignment to the right */
188+
if (!(info->left) && (min_width > 0)) {
189+
while (min_width--) {
190+
if (info->pad != 0) {
191+
/* TODO: The type of info->pad is wchar_t, make a note in
192+
the docs not to use a wchar_t pad */
193+
MP_FPUTC((int)(info->pad),stream);
194+
length_printed++;
195+
} else {
196+
MP_FPUTC(' ',stream);
197+
length_printed++;
198+
}
199+
}
200+
}
201+
202+
/* Print the prefix */
203+
for (i = 0; i < idx; i++) {
204+
MP_FPUTC(start_buf[i],stream);
205+
length_printed++;
206+
}
207+
208+
/* Add leading zeros if set */
209+
if (info->prec > 0) {
210+
/* Prefix length, if there is any, is in idx*/
211+
fill_zeros = info->prec - idx - (int)written + 1;
212+
/* No truncating */
213+
if (fill_zeros > 0) {
214+
while (fill_zeros--) {
215+
MP_FPUTC('0',stream);
216+
length_printed++;
217+
}
218+
}
219+
}
220+
221+
/* Print the number itself */
222+
while (start_buf[idx] != '\0') {
223+
MP_FPUTC(start_buf[idx++],stream);
224+
length_printed++;
225+
}
226+
227+
/* Print padding to the right for alignment to the left */
228+
if ((info->left) && (min_width > 0)) {
229+
while (min_width--) {
230+
if (info->pad != 0) {
231+
MP_FPUTC((int)(info->pad),stream);
232+
length_printed++;
233+
} else {
234+
MP_FPUTC(' ',stream);
235+
length_printed++;
236+
}
237+
}
238+
}
174239

175240
MP_FREE(start_buf, size + extra_len);
176-
return len;
241+
return length_printed;
177242
}
178243

179244
#include <inttypes.h>

0 commit comments

Comments
 (0)