about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--stdlib/bug-strtod.c104
-rw-r--r--stdlib/tst-strtod.h50
3 files changed, 96 insertions, 65 deletions
diff --git a/ChangeLog b/ChangeLog
index ab323b2d57..de34b56c9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2016-05-23  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
+
+	* stdlib/tst-strtod6.c (do_test): Use new type generic
+	invocation of the test function.
+	(test): Refactor into ...
+	(TEST_STRTOD): New macro base function.
+
 2016-05-23  Florian Weimer  <fweimer@redhat.com>
 
 	CVE-2016-4429
diff --git a/stdlib/bug-strtod.c b/stdlib/bug-strtod.c
index 82e7d30b42..c8b56aa7e1 100644
--- a/stdlib/bug-strtod.c
+++ b/stdlib/bug-strtod.c
@@ -21,73 +21,47 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "tst-strtod.h"
+
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF)		\
+static int								\
+test_strto ## FSUF (void)						\
+{									\
+  char buf[300];							\
+  int cnt;								\
+  int result = 0;							\
+									\
+  for (cnt = 0; cnt < 200; ++cnt)					\
+    {									\
+      ssize_t n;							\
+      FTYPE f;								\
+									\
+      n = sprintf (buf, "%d", cnt);					\
+      memset (buf + n, '0', cnt);					\
+      sprintf (buf + n + cnt, ".000e-%d", cnt);				\
+      f = strto ## FSUF (buf, NULL);					\
+									\
+      if (f != (FTYPE) cnt)						\
+	{								\
+	  char fstr[FSTRLENMAX];					\
+	  char fcntstr[FSTRLENMAX];					\
+	  FTOSTR (fstr, sizeof (fstr), "%" FTOSTRM "g", f);		\
+	  FTOSTR (fcntstr, sizeof (fstr), "%" FTOSTRM "g", (FTYPE) cnt); \
+	  printf ("strto" #FSUF "(\"%s\") "				\
+		  "failed for cnt == %d (%s instead of %s)\n",		\
+		  buf, cnt, fstr, fcntstr);				\
+	  result = 1;							\
+	}								\
+      else								\
+	printf ( "strto" #FSUF "() fine for cnt == %d\n", cnt);		\
+    }									\
+  return result;							\
+}
+
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
 
 int
 main (void)
 {
-  char buf[300];
-  int cnt;
-  int result = 0;
-
-  for (cnt = 0; cnt < 200; ++cnt)
-    {
-      ssize_t n;
-      float f;
-
-      n = sprintf (buf, "%d", cnt);
-      memset (buf + n, '0', cnt);
-      sprintf (buf + n + cnt, ".000e-%d", cnt);
-      f = strtof (buf, NULL);
-
-      if (f != (float) cnt)
-	{
-	  printf ("strtof(\"%s\") failed for cnt == %d (%g instead of %g)\n",
-		  buf, cnt, f, (float) cnt);
-	  result = 1;
-	}
-      else
-	printf ("strtof() fine for cnt == %d\n", cnt);
-    }
-
-  for (cnt = 0; cnt < 200; ++cnt)
-    {
-      ssize_t n;
-      double f;
-
-      n = sprintf (buf, "%d", cnt);
-      memset (buf + n, '0', cnt);
-      sprintf (buf + n + cnt, ".000e-%d", cnt);
-      f = strtod (buf, NULL);
-
-      if (f != (double) cnt)
-	{
-	  printf ("strtod(\"%s\") failed for cnt == %d (%g instead of %g)\n",
-		  buf, cnt, f, (double) cnt);
-	  result = 1;
-	}
-      else
-	printf ("strtod() fine for cnt == %d\n", cnt);
-    }
-
-  for (cnt = 0; cnt < 200; ++cnt)
-    {
-      ssize_t n;
-      long double f;
-
-      n = sprintf (buf, "%d", cnt);
-      memset (buf + n, '0', cnt);
-      sprintf (buf + n + cnt, ".000e-%d", cnt);
-      f = strtold (buf, NULL);
-
-      if (f != (long double) cnt)
-	{
-	  printf ("strtold(\"%s\") failed for cnt == %d (%Lg instead of %Lg)\n",
-		  buf, cnt, f, (long double) cnt);
-	  result = 1;
-	}
-      else
-	printf ("strtold() fine for cnt == %d\n", cnt);
-    }
-
-  return result;
+  return STRTOD_TEST_FOREACH (test_strto);
 }
diff --git a/stdlib/tst-strtod.h b/stdlib/tst-strtod.h
new file mode 100644
index 0000000000..d53c1de95a
--- /dev/null
+++ b/stdlib/tst-strtod.h
@@ -0,0 +1,50 @@
+/* Common utilities for testing strtod and its derivatives.
+   This file is part of the GNU C Library.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TST_STRTOD_H
+#define _TST_STRTOD_H
+
+#define FSTRLENMAX 128
+
+/* Splat n variants of the same test for the various strtod functions.  */
+#define GEN_TEST_STRTOD_FOREACH(mfunc)		  \
+    mfunc (  f,       float, snprintf,  "", f, f) \
+    mfunc (  d,      double, snprintf,  "",  ,  ) \
+    mfunc ( ld, long double, snprintf, "L", L, l)
+/* The arguments to the generated macros are:
+   FSUF - Function suffix
+   FTYPE - float type
+   FTOSTR - float to string func
+   FTOSTRM - Optional modifier for FTOSTR format
+   LSUF - Literal suffix
+   CSUF - C standardish suffix for many of the math functions
+*/
+
+
+
+#define STRTOD_TEST_FOREACH(mfunc, ...)	  \
+({					  \
+   int result = 0;			  \
+   result |= mfunc ## f  (__VA_ARGS__);   \
+   result |= mfunc ## d  (__VA_ARGS__);   \
+   result |= mfunc ## ld (__VA_ARGS__);   \
+   result;				  \
+})
+
+
+#endif