1
0
mirror of https://github.com/openbsd/src.git synced 2024-12-21 23:18:00 -08:00

Use LibreSSLs specialized functions to print base 10 and base 16.

Also optimize the general case a bit. ok semarie@
This commit is contained in:
otto 2024-11-07 16:20:00 +00:00
parent 949c1c4ec8
commit f4f5a46ba7

View File

@ -1,4 +1,4 @@
/* $OpenBSD: inout.c,v 1.23 2023/03/08 04:43:10 guenther Exp $ */
/* $OpenBSD: inout.c,v 1.24 2024/11/07 16:20:00 otto Exp $ */
/*
* Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
@ -38,7 +38,7 @@ static void src_freestring(struct source *);
static void flushwrap(FILE *);
static void putcharwrap(FILE *, int);
static void printwrap(FILE *, const char *);
static char *get_digit(u_long, int, u_int);
static void get_digit(u_long, int, u_int, char *, size_t);
static struct vtable stream_vtable = {
src_getcharstream,
@ -264,20 +264,17 @@ read_string(struct source *src)
return p;
}
static char *
get_digit(u_long num, int digits, u_int base)
static void
get_digit(u_long num, int digits, u_int base, char *buf, size_t sz)
{
char *p;
if (base <= 16) {
p = bmalloc(2);
p[0] = num >= 10 ? num + 'A' - 10 : num + '0';
p[1] = '\0';
buf[0] = num >= 10 ? num + 'A' - 10 : num + '0';
buf[1] = '\0';
} else {
if (asprintf(&p, "%0*lu", digits, num) == -1)
err(1, NULL);
int ret = snprintf(buf, sz, "%0*lu", digits, num);
if (ret < 0 || (size_t)ret >= sz)
err(1, "truncation");
}
return p;
}
void
@ -285,11 +282,10 @@ printnumber(FILE *f, const struct number *b, u_int base)
{
struct number *int_part, *fract_part;
int digits;
char buf[11];
size_t sz;
char buf[12], *str, *p;
size_t allocated;
int i;
struct stack stack;
char *p;
BN_ULONG *mem;
charcount = 0;
lastchar = -1;
@ -307,24 +303,49 @@ printnumber(FILE *f, const struct number *b, u_int base)
}
split_number(b, int_part->number, fract_part->number);
i = 0;
stack_init(&stack);
while (!BN_is_zero(int_part->number)) {
BN_ULONG rem = BN_div_word(int_part->number, base);
stack_pushstring(&stack, get_digit(rem, digits, base));
i++;
if (base == 10 && !BN_is_zero(int_part->number)) {
str = BN_bn2dec(int_part->number);
bn_checkp(str);
p = str;
while (*p)
putcharwrap(f, *p++);
free(str);
} else if (base == 16 && !BN_is_zero(int_part->number)) {
str = BN_bn2hex(int_part->number);
bn_checkp(str);
p = str;
if (*p == '-')
putcharwrap(f, *p++);
/* skip leading zero's */
while (*p == '0')
p++;
while (*p)
putcharwrap(f, *p++);
free(str);
} else {
i = 0;
allocated = 1;
mem = breallocarray(NULL, allocated, sizeof(BN_ULONG));
while (!BN_is_zero(int_part->number)) {
if (i >= allocated) {
allocated *= 2;
mem = breallocarray(mem, allocated,
sizeof(BN_ULONG));
}
mem[i++] = BN_div_word(int_part->number, base);
}
if (BN_is_negative(b->number))
putcharwrap(f, '-');
for (i = i - 1; i >= 0; i--) {
get_digit(mem[i], digits, base, buf,
sizeof(buf));
if (base > 16)
putcharwrap(f, ' ');
printwrap(f, buf);
}
free(mem);
}
sz = i;
if (BN_is_negative(b->number))
putcharwrap(f, '-');
for (i = 0; i < sz; i++) {
p = stack_popstring(&stack);
if (base > 16)
putcharwrap(f, ' ');
printwrap(f, p);
free(p);
}
stack_clear(&stack);
if (b->scale > 0) {
struct number *num_base;
BIGNUM *mult, *stop;
@ -352,13 +373,12 @@ printnumber(FILE *f, const struct number *b, u_int base)
bmachine_scale());
split_number(fract_part, int_part->number, NULL);
rem = BN_get_word(int_part->number);
p = get_digit(rem, digits, base);
get_digit(rem, digits, base, buf, sizeof(buf));
int_part->scale = 0;
normalize(int_part, fract_part->scale);
bn_check(BN_sub(fract_part->number, fract_part->number,
int_part->number));
printwrap(f, p);
free(p);
printwrap(f, buf);
bn_check(BN_mul_word(mult, base));
}
free_number(num_base);