From e0f9152733fda5ffd356ab453a242377c3fbea2e Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 6 Apr 2019 12:24:53 +0100 Subject: [PATCH] [Feature] Use fpconv girsu2 implementation for printing floats --- CMakeLists.txt | 2 ++ src/CMakeLists.txt | 1 + src/libutil/printf.c | 54 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66fd2ffc9..cf4223840 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -499,6 +499,7 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/" "${CMAKE_SOURCE_DIR}/contrib/linenoise" "${CMAKE_SOURCE_DIR}/contrib/uthash" "${CMAKE_SOURCE_DIR}/contrib/http-parser" + "${CMAKE_SOURCE_DIR}/contrib/fpconv" "${CMAKE_SOURCE_DIR}/contrib/libottery" "${CMAKE_SOURCE_DIR}/contrib/xxhash" "${CMAKE_SOURCE_DIR}/contrib/cdb" @@ -1247,6 +1248,7 @@ ENDIF(GLIB_COMPAT) ADD_SUBDIRECTORY(contrib/xxhash) ADD_SUBDIRECTORY(contrib/cdb) ADD_SUBDIRECTORY(contrib/http-parser) +ADD_SUBDIRECTORY(contrib/fpconv) ADD_SUBDIRECTORY(contrib/lc-btrie) ADD_SUBDIRECTORY(contrib/libottery) ADD_SUBDIRECTORY(contrib/zstd) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 22d28e770..f755779e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -183,6 +183,7 @@ ELSE() ENDIF() TARGET_LINK_LIBRARIES(rspamd-server rspamd-http-parser) +TARGET_LINK_LIBRARIES(rspamd-server rspamd-fpconv) TARGET_LINK_LIBRARIES(rspamd-server rspamd-cdb) TARGET_LINK_LIBRARIES(rspamd-server rspamd-lpeg) TARGET_LINK_LIBRARIES(rspamd-server lcbtrie) 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; -- 2.39.5