Ethereal-dev: [Ethereal-dev] Change of printf format for floats and doubles

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Gilbert Ramirez <gram@xxxxxxxxxxxxxxx>
Date: Wed, 02 Jul 2003 03:18:14 -0000
I discovered a problem where "Match Selected" on an FT_DOUBLE field
would produce a display filter that would not match the selected field.
My testing is on ia32/Linux. Try "Match Selected" on ntp.rootdelay
("Root Delay") in the attached capture file.

It turns out that the precision of the "double" C type is 15 digits, not
14 as were using in proto.c ("%.14g"). So the generated display filter
was short one digit of precision.

Attached is a fix to use FLT_DIG and DBL_DIG, the apparently
ANSI-standard way of specifying the implementation's precision for float
and double-precision float numbers.  I may be way off on this, but it
fixes my problem on ia32/Linux.  I have not tested on other platforms.

Can anyone find a problem with this patch?

--gilbert


Attachment: float-format.cap
Description: Binary data

? float-format.diff
? epan/.proto.c.swp
? epan/ftypes/test
? tools/.dfilter-test.py.swp
? tools/dfilter-test.py
Index: epan/proto.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/epan/proto.c,v
retrieving revision 1.90
diff -u -r1.90 proto.c
--- epan/proto.c	10 Jun 2003 18:03:23 -0000	1.90
+++ epan/proto.c	2 Jul 2003 03:09:21 -0000
@@ -29,6 +29,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <glib.h>
+#include <float.h>
 
 #ifdef NEED_SNPRINTF_H
 # include "snprintf.h"
@@ -2511,14 +2512,16 @@
 
 		case FT_FLOAT:
 			ret = snprintf(label_str, ITEM_LABEL_LENGTH,
-				"%s: %.9g", hfinfo->name, fvalue_get_floating(fi->value));
+				"%s: %." STRINGIFY(FLT_DIG) "f",
+				hfinfo->name, fvalue_get_floating(fi->value));
 			if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
 				label_str[ITEM_LABEL_LENGTH - 1] = '\0';
 			break;
 
 		case FT_DOUBLE:
 			ret = snprintf(label_str, ITEM_LABEL_LENGTH,
-				"%s: %.14g", hfinfo->name, fvalue_get_floating(fi->value));
+				"%s: %." STRINGIFY(DBL_DIG) "g",
+				hfinfo->name, fvalue_get_floating(fi->value));
 			if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
 				label_str[ITEM_LABEL_LENGTH - 1] = '\0';
 			break;
@@ -3631,7 +3634,8 @@
 			 */
 			dfilter_len = abbrev_len + 4 + 1 + 26 + 1;
 			buf = g_malloc0(dfilter_len);
-			snprintf(buf, dfilter_len, "%s == %f", hfinfo->abbrev,
+			snprintf(buf, dfilter_len, "%s == %." STRINGIFY(FLT_DIG) "f",
+					hfinfo->abbrev,
 					fvalue_get_floating(finfo->value));
 			break;
 
@@ -3647,7 +3651,8 @@
 			 */
 			dfilter_len = abbrev_len + 4 + 1 + 26 + 1;
 			buf = g_malloc0(dfilter_len);
-			snprintf(buf, dfilter_len, "%s == %f", hfinfo->abbrev,
+			snprintf(buf, dfilter_len, "%s == %." STRINGIFY(DBL_DIG) "g",
+					hfinfo->abbrev,
 					fvalue_get_floating(finfo->value));
 			break;
 
Index: epan/strutil.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/epan/strutil.h,v
retrieving revision 1.9
diff -u -r1.9 strutil.h
--- epan/strutil.h	28 Aug 2002 20:40:45 -0000	1.9
+++ epan/strutil.h	2 Jul 2003 03:09:21 -0000
@@ -34,4 +34,9 @@
 gchar*     format_text(const guchar *line, int len);
 gchar*     bytes_to_str(const guint8 *, int);
 gchar*     bytes_to_str_punct(const guint8 *, int, gchar punct);
+
+/* Surround a string or a macro, resolved to a string, with double quotes */
+#define _STRINGIFY(a)           # a
+#define STRINGIFY(a)            _STRINGIFY(a)
+
 #endif /* __STRUTIL_H__ */