]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Feature] Use fpconv girsu2 implementation for printing floats
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 6 Apr 2019 11:24:53 +0000 (12:24 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 6 Apr 2019 11:24:53 +0000 (12:24 +0100)
CMakeLists.txt
src/CMakeLists.txt
src/libutil/printf.c

index 66fd2ffc9f973938ce9bbe3b5bb863ca2947f240..cf4223840cc0f8f51ad35f2769c4e6c595277c1b 100644 (file)
@@ -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)
index 22d28e770e8d4b0508c855245c640a19dba60d9f..f755779e6925b5bba2c3bb98e975eedfb10895bb 100644 (file)
@@ -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)
index 3c4acef47740f6d1a6e80a2e00842f35b89f156f..403fa88772f51aa519c23fc0e1297ab6b57d2538 100644 (file)
@@ -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;