diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-04-06 12:24:53 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-04-06 12:24:53 +0100 |
commit | e0f9152733fda5ffd356ab453a242377c3fbea2e (patch) | |
tree | 5e242ddf5bb85faa4458ce01490029b49b0a264a /src/libutil/printf.c | |
parent | 4f9f85c6d1b7ca4bfab4599cb76e885c71ad07f6 (diff) | |
download | rspamd-e0f9152733fda5ffd356ab453a242377c3fbea2e.tar.gz rspamd-e0f9152733fda5ffd356ab453a242377c3fbea2e.zip |
[Feature] Use fpconv girsu2 implementation for printing floats
Diffstat (limited to 'src/libutil/printf.c')
-rw-r--r-- | src/libutil/printf.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/src/libutil/printf.c b/src/libutil/printf.c index 3c4acef47..403fa8877 100644 --- a/src/libutil/printf.c +++ b/src/libutil/printf.c @@ -40,6 +40,7 @@ #include "printf.h" #include "str_util.h" +#include "contrib/fpconv/fpconv.h" /** * From FreeBSD libutil code @@ -590,7 +591,7 @@ rspamd_vprintf_common (rspamd_printf_append_func func, const gchar *fmt, va_list args) { - gchar zero, numbuf[G_ASCII_DTOSTR_BUF_SIZE], dtoabuf[8], *p, *last, c; + gchar zero, numbuf[G_ASCII_DTOSTR_BUF_SIZE], dtoabuf[24], *p, *last, c; const gchar *buf_start = fmt, *fmt_start = NULL; gint d; gdouble f; @@ -948,23 +949,52 @@ rspamd_vprintf_common (rspamd_printf_append_func func, case 'f': case 'g': f = (gdouble) va_arg (args, double); - rspamd_strlcpy (dtoabuf, fmt_start, MIN (sizeof (dtoabuf), - (fmt - fmt_start + 2))); - g_ascii_formatd (numbuf, sizeof (numbuf), dtoabuf, (double)f); - slen = strlen (numbuf); - RSPAMD_PRINTF_APPEND (numbuf, slen); + slen = fpconv_dtoa (f, dtoabuf); + + if (frac_width != 0) { + const gchar *dot_pos = memchr (dtoabuf, '.', slen); + + if (dot_pos) { + if (frac_width < (slen - ((dot_pos - dtoabuf) + 1))) { + /* Truncate */ + slen = (dot_pos - dtoabuf) + 1 + /* xxx. */ + frac_width; /* .yyy */ + } + else if (frac_width + dot_pos + 1 < dtoabuf + sizeof (dtoabuf)) { + /* Expand */ + frac_width -= slen - ((dot_pos - dtoabuf) + 1); + memset (dtoabuf + slen, '0', frac_width); + slen += frac_width; + } + } + else { + /* Expand */ + frac_width = MIN (frac_width, sizeof (dtoabuf) - slen - 1); + dtoabuf[slen ++] = '.'; + memset (dtoabuf + slen, '0', frac_width); + slen += frac_width; + } + } + + RSPAMD_PRINTF_APPEND (dtoabuf, slen); continue; case 'F': case 'G': f = (gdouble) va_arg (args, long double); - slen = rspamd_strlcpy (dtoabuf, fmt_start, MIN (sizeof (dtoabuf), - (fmt - fmt_start + 2))); - dtoabuf[slen - 1] = g_ascii_tolower (dtoabuf[slen - 1]); - g_ascii_formatd (numbuf, sizeof (numbuf), dtoabuf, (double)f); - slen = strlen (numbuf); - RSPAMD_PRINTF_APPEND (numbuf, slen); + slen = fpconv_dtoa (f, dtoabuf); + + if (frac_width != 0) { + const gchar *dot_pos = memchr (dtoabuf, '.', slen); + + if (dot_pos && frac_width < (slen - ((dot_pos - dtoabuf) + 1))) { + slen = (dot_pos - dtoabuf) + 1 + /* xxx. */ + frac_width; /* .yyy */ + } + } + + RSPAMD_PRINTF_APPEND (dtoabuf, slen); continue; |