This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2 3/9] Remove duplicated code from __printf_fp_l, __printf_fphex, and __printf_size


Changes since v1:

  - Also refactored the code in printf_size.c because it had the same problem
    of __printf_fp_l and __printf_fphex.

-- 8< --
In __printf_fp_l, __printf_fphex, and __printf_size the blocks of code that are
used to read a double or long double argument, check for special values and
convert to multiprecision are similar.  When adding float128 support to libc,
more code would be duplicated to deal with the extra type.  This patch moves
the repetitive code to a macro which is now used by double and long double and
will be used for float128 when support is added, thus avoiding more
duplication.

Tested for powerpc64le and s390x.

2017-05-29  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>

	* stdio-common/printf_fp.c (PRINTF_FP_FETCH): New macro.
	(__printf_fp_l): Use the new macro to avoid duplicating code.
	* stdio-common/printf_fphex.c (PRINTF_FPHEX_FETCH): New macro.
	(__printf_fphex): Use the new macro to avoid duplicating code.
	* stdio-common/printf_size.c (PRINTF_SIZE_FETCH): New macro.
	(__printf_size): Use the new macro to avoid duplicating code.
---
 stdio-common/printf_fp.c    | 130 ++++++++++++++++----------------------------
 stdio-common/printf_fphex.c | 110 ++++++++++++++-----------------------
 stdio-common/printf_size.c  |  75 ++++++++++---------------
 3 files changed, 116 insertions(+), 199 deletions(-)

diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 7845d96..6d8c381 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -327,94 +327,58 @@ __printf_fp_l (FILE *fp, locale_t loc,
   else
     grouping = NULL;
 
+#define PRINTF_FP_FETCH(FLOAT, VAR, SUFFIX, MANT_DIG)			\
+  {									\
+    VAR = *(const FLOAT *) args[0];					\
+									\
+    /* Check for special values: not a number or infinity.  */		\
+    if (isnan (VAR))							\
+      {									\
+	is_neg = signbit (VAR);						\
+	if (isupper (info->spec))					\
+	  {								\
+	    special = "NAN";						\
+	    wspecial = L"NAN";						\
+	  }								\
+	else								\
+	  {								\
+	    special = "nan";						\
+	    wspecial = L"nan";						\
+	  }								\
+      }									\
+    else if (isinf (VAR))						\
+      {									\
+	is_neg = signbit (VAR);						\
+	if (isupper (info->spec))					\
+	  {								\
+	    special = "INF";						\
+	    wspecial = L"INF";						\
+	  }								\
+	else								\
+	  {								\
+	    special = "inf";						\
+	    wspecial = L"inf";						\
+	  }								\
+      }									\
+    else								\
+      {									\
+	p.fracsize = __mpn_extract_##SUFFIX				\
+		     (fp_input,						\
+		      (sizeof (fp_input) / sizeof (fp_input[0])),	\
+		      &p.exponent, &is_neg, VAR);			\
+	to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - MANT_DIG;	\
+      }									\
+  }
+
   /* Fetch the argument value.	*/
 #ifndef __NO_LONG_DOUBLE_MATH
   if (info->is_long_double && sizeof (long double) > sizeof (double))
-    {
-      fpnum.ldbl = *(const long double *) args[0];
-
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.ldbl))
-	{
-	  is_neg = signbit (fpnum.ldbl);
-	  if (isupper (info->spec))
-	    {
-	      special = "NAN";
-	      wspecial = L"NAN";
-	    }
-	    else
-	      {
-		special = "nan";
-		wspecial = L"nan";
-	      }
-	}
-      else if (isinf (fpnum.ldbl))
-	{
-	  is_neg = signbit (fpnum.ldbl);
-	  if (isupper (info->spec))
-	    {
-	      special = "INF";
-	      wspecial = L"INF";
-	    }
-	  else
-	    {
-	      special = "inf";
-	      wspecial = L"inf";
-	    }
-	}
-      else
-	{
-	  p.fracsize = __mpn_extract_long_double (fp_input,
-						(sizeof (fp_input) /
-						 sizeof (fp_input[0])),
-						&p.exponent, &is_neg,
-						fpnum.ldbl);
-	  to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - LDBL_MANT_DIG;
-	}
-    }
+    PRINTF_FP_FETCH (long double, fpnum.ldbl, long_double, LDBL_MANT_DIG)
   else
-#endif	/* no long double */
-    {
-      fpnum.dbl = *(const double *) args[0];
+#endif
+    PRINTF_FP_FETCH (double, fpnum.dbl, double, DBL_MANT_DIG)
 
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.dbl))
-	{
-	  is_neg = signbit (fpnum.dbl);
-	  if (isupper (info->spec))
-	    {
-	      special = "NAN";
-	      wspecial = L"NAN";
-	    }
-	  else
-	    {
-	      special = "nan";
-	      wspecial = L"nan";
-	    }
-	}
-      else if (isinf (fpnum.dbl))
-	{
-	  is_neg = signbit (fpnum.dbl);
-	  if (isupper (info->spec))
-	    {
-	      special = "INF";
-	      wspecial = L"INF";
-	    }
-	  else
-	    {
-	      special = "inf";
-	      wspecial = L"inf";
-	    }
-	}
-      else
-	{
-	  p.fracsize = __mpn_extract_double (fp_input,
-					   (sizeof (fp_input)
-					    / sizeof (fp_input[0])),
-					   &p.exponent, &is_neg, fpnum.dbl);
-	  to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - DBL_MANT_DIG;
-	}
-    }
+#undef PRINTF_FP_FETCH
 
   if (special)
     {
diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c
index b207e00..3a25854 100644
--- a/stdio-common/printf_fphex.c
+++ b/stdio-common/printf_fphex.c
@@ -157,82 +157,52 @@ __printf_fphex (FILE *fp,
   /* The decimal point character must never be zero.  */
   assert (*decimal != '\0' && decimalwc != L'\0');
 
+#define PRINTF_FPHEX_FETCH(FLOAT, VAR)					\
+  {									\
+    VAR = *(const FLOAT *) args[0];					\
+									\
+    /* Check for special values: not a number or infinity.  */		\
+    if (isnan (VAR))							\
+      {									\
+	if (isupper (info->spec))					\
+	  {								\
+	    special = "NAN";						\
+	    wspecial = L"NAN";						\
+	  }								\
+	else								\
+	  {								\
+	    special = "nan";						\
+	    wspecial = L"nan";						\
+	  }								\
+      }									\
+    else								\
+      {									\
+	if (isinf (VAR))						\
+	  {								\
+	    if (isupper (info->spec))					\
+	      {								\
+		special = "INF";					\
+		wspecial = L"INF";					\
+	      }								\
+	    else							\
+	      {								\
+		special = "inf";					\
+		wspecial = L"inf";					\
+	      }								\
+	  }								\
+      }									\
+    negative = signbit (VAR);						\
+  }
 
   /* Fetch the argument value.	*/
 #ifndef __NO_LONG_DOUBLE_MATH
   if (info->is_long_double && sizeof (long double) > sizeof (double))
-    {
-      fpnum.ldbl = *(const long double *) args[0];
-
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.ldbl))
-	{
-	  if (isupper (info->spec))
-	    {
-	      special = "NAN";
-	      wspecial = L"NAN";
-	    }
-	  else
-	    {
-	      special = "nan";
-	      wspecial = L"nan";
-	    }
-	}
-      else
-	{
-	  if (isinf (fpnum.ldbl))
-	    {
-	      if (isupper (info->spec))
-		{
-		  special = "INF";
-		  wspecial = L"INF";
-		}
-	      else
-		{
-		  special = "inf";
-		  wspecial = L"inf";
-		}
-	    }
-	}
-      negative = signbit (fpnum.ldbl);
-    }
+    PRINTF_FPHEX_FETCH (long double, fpnum.ldbl)
   else
-#endif	/* no long double */
-    {
-      fpnum.dbl.d = *(const double *) args[0];
+#endif
+    PRINTF_FPHEX_FETCH (double, fpnum.dbl.d)
 
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.dbl.d))
-	{
-	  if (isupper (info->spec))
-	    {
-	      special = "NAN";
-	      wspecial = L"NAN";
-	    }
-	  else
-	    {
-	      special = "nan";
-	      wspecial = L"nan";
-	    }
-	}
-      else
-	{
-	  if (isinf (fpnum.dbl.d))
-	    {
-	      if (isupper (info->spec))
-		{
-		  special = "INF";
-		  wspecial = L"INF";
-		}
-	      else
-		{
-		  special = "inf";
-		  wspecial = L"inf";
-		}
-	    }
-	}
-      negative = signbit (fpnum.dbl.d);
-    }
+#undef PRINTF_FPHEX_FETCH
 
   if (special)
     {
diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c
index 9403aea..cdcd2f7 100644
--- a/stdio-common/printf_size.c
+++ b/stdio-common/printf_size.c
@@ -118,57 +118,40 @@ __printf_size (FILE *fp, const struct printf_info *info,
   int done = 0;
   int wide = info->wide;
 
+#define PRINTF_SIZE_FETCH(FLOAT, VAR)					\
+  {									\
+    VAR = *(const FLOAT *) args[0];					\
+									\
+    /* Check for special values: not a number or infinity.  */		\
+    if (isnan (VAR))							\
+      {									\
+	special = "nan";						\
+	wspecial = L"nan";						\
+	/* is_neg = 0; Already zero */					\
+      }									\
+    else if (isinf (VAR))						\
+      {									\
+	is_neg = signbit (VAR);						\
+	special = "inf";						\
+	wspecial = L"inf";						\
+      }									\
+    else								\
+      while (VAR >= divisor && tag[1] != '\0')				\
+	{								\
+	  VAR /= divisor;						\
+	  ++tag;							\
+	}								\
+  }
+
   /* Fetch the argument value.	*/
 #ifndef __NO_LONG_DOUBLE_MATH
   if (info->is_long_double && sizeof (long double) > sizeof (double))
-    {
-      fpnum.ldbl = *(const long double *) args[0];
-
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.ldbl))
-	{
-	  special = "nan";
-	  wspecial = L"nan";
-	  // is_neg = 0;	Already zero
-	}
-      else if (isinf (fpnum.ldbl))
-	{
-	  is_neg = signbit (fpnum.ldbl);
-	  special = "inf";
-	  wspecial = L"inf";
-	}
-      else
-	while (fpnum.ldbl >= divisor && tag[1] != '\0')
-	  {
-	    fpnum.ldbl /= divisor;
-	    ++tag;
-	  }
-    }
+    PRINTF_SIZE_FETCH (long double, fpnum.ldbl)
   else
-#endif	/* no long double */
-    {
-      fpnum.dbl.d = *(const double *) args[0];
+#endif
+    PRINTF_SIZE_FETCH (double, fpnum.dbl.d)
 
-      /* Check for special values: not a number or infinity.  */
-      if (isnan (fpnum.dbl.d))
-	{
-	  special = "nan";
-	  wspecial = L"nan";
-	  // is_neg = 0;	Already zero
-	}
-      else if (isinf (fpnum.dbl.d))
-	{
-	  is_neg = signbit (fpnum.dbl.d);
-	  special = "inf";
-	  wspecial = L"inf";
-	}
-      else
-	while (fpnum.dbl.d >= divisor && tag[1] != '\0')
-	  {
-	    fpnum.dbl.d /= divisor;
-	    ++tag;
-	  }
-    }
+#undef PRINTF_SIZE_FETCH
 
   if (special)
     {
-- 
2.4.11


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]