commit e0f9152: [Feature] Use fpconv girsu2 implementation for printing floats

Vsevolod Stakhov vsevolod at highsecure.ru
Sat Apr 6 11:28:26 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-04-06 12:24:53 +0100
URL: https://github.com/rspamd/rspamd/commit/e0f9152733fda5ffd356ab453a242377c3fbea2e

[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;
 


More information about the Commits mailing list