public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v8 0/3] New strfrom functions
@ 2016-10-14 17:31 Gabriel F. T. Gomes
  2016-10-14 17:31 ` [PATCH v8 3/3] Add tests for " Gabriel F. T. Gomes
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Gabriel F. T. Gomes @ 2016-10-14 17:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: joseph

Changes since v7:
  - Fix input type to avoid implicit conversions in the tests.
  - No changes to patches 1 and 2.

Tested on x86_64, ppc64, ppc64le, s390.

Gabriel F. T. Gomes (1):
  Add strfromd, strfromf, and strfroml functions

Rajalakshmi Srinivasaraghavan (2):
  Refactor strtod tests
  Add tests for strfrom functions

 NEWS                                               |   3 +
 manual/arith.texi                                  |  41 +++++
 stdlib/Makefile                                    |  11 +-
 stdlib/Versions                                    |   4 +
 stdlib/bits/stdlib-ldbl.h                          |   4 +
 stdlib/bug-strtod.c                                |   6 +-
 stdlib/bug-strtod2.c                               |   2 +-
 stdlib/stdlib.h                                    |  18 ++-
 stdlib/strfrom-skeleton.c                          | 149 +++++++++++++++++
 stdlib/strfromd.c                                  |  22 +++
 stdlib/strfromf.c                                  |  22 +++
 stdlib/strfroml.c                                  |  22 +++
 stdlib/tst-strfrom-locale.c                        | 178 +++++++++++++++++++++
 stdlib/tst-strfrom.c                               | 178 +++++++++++++++++++++
 stdlib/tst-strtod-round-skeleton.c                 |  24 ++-
 stdlib/tst-strtod.h                                |   7 +-
 stdlib/tst-strtod6.c                               |   2 +-
 sysdeps/arm/nacl/libc.abilist                      |   3 +
 sysdeps/ieee754/ldbl-opt/Makefile                  |   1 +
 sysdeps/ieee754/ldbl-opt/nldbl-strfroml.c          |   8 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |   3 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |   3 +
 sysdeps/unix/sysv/linux/arm/libc.abilist           |   3 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |   3 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |   3 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |   3 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |   3 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/microblaze/libc.abilist    |   3 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |   3 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |   3 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |   3 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |   3 +
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |   3 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |   3 +
 .../sysv/linux/powerpc/powerpc64/libc-le.abilist   |   3 +
 .../unix/sysv/linux/powerpc/powerpc64/libc.abilist |   3 +
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |   3 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |   3 +
 sysdeps/unix/sysv/linux/sh/libc.abilist            |   3 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |   3 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |   3 +
 .../sysv/linux/tile/tilegx/tilegx32/libc.abilist   |   3 +
 .../sysv/linux/tile/tilegx/tilegx64/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist  |   3 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |   3 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |   3 +
 48 files changed, 765 insertions(+), 24 deletions(-)
 create mode 100644 stdlib/strfrom-skeleton.c
 create mode 100644 stdlib/strfromd.c
 create mode 100644 stdlib/strfromf.c
 create mode 100644 stdlib/strfroml.c
 create mode 100644 stdlib/tst-strfrom-locale.c
 create mode 100644 stdlib/tst-strfrom.c
 create mode 100644 sysdeps/ieee754/ldbl-opt/nldbl-strfroml.c

-- 
2.4.11

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v8 3/3] Add tests for strfrom functions
  2016-10-14 17:31 [PATCH v8 0/3] New strfrom functions Gabriel F. T. Gomes
@ 2016-10-14 17:31 ` Gabriel F. T. Gomes
  2016-10-14 18:50   ` Gabriel F. T. Gomes
  2016-10-14 21:40   ` Joseph Myers
  2016-10-14 17:31 ` [PATCH v8 2/3] Refactor strtod tests Gabriel F. T. Gomes
  2016-10-14 17:31 ` [PATCH v8 1/3] Add strfromd, strfromf, and strfroml functions Gabriel F. T. Gomes
  2 siblings, 2 replies; 11+ messages in thread
From: Gabriel F. T. Gomes @ 2016-10-14 17:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: joseph

From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>

2016-10-13  Rajalakshmi Srinivasaraghavan  <raji@linux.vnet.ibm.com>

	* stdlib/Makefile (tests): Add tst-strfrom and tst-strfrom-locale.
	* stdlib/tst-strfrom.c: New file.
	* stdlib/tst-strfrom-locale.c: New file.

wi: http://dagger1.rch.stglabs.ibm.com:5678/b/tqzrQAkzP337NcJ5P/corelibs/uqHc2aKRqa6hNni2P
Change-Id: I7c5975a608c2a8085db544a7f9de31c921f545ca
---
 stdlib/Makefile             |   4 +-
 stdlib/tst-strfrom-locale.c | 178 ++++++++++++++++++++++++++++++++++++++++++++
 stdlib/tst-strfrom.c        | 178 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 359 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-strfrom-locale.c
 create mode 100644 stdlib/tst-strfrom.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index 3cacb8b..3cce9d9 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -79,7 +79,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   tst-setcontext3 tst-tls-atexit-nodelete		    \
 		   tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l    \
 		   tst-quick_exit tst-thread-quick_exit tst-width	    \
-		   tst-width-stdint
+		   tst-width-stdint tst-strfrom tst-strfrom-locale
 tests-static	:= tst-secure-getenv
 ifeq ($(have-cxx-thread_local),yes)
 CFLAGS-tst-quick_exit.o = -std=c++11
@@ -158,6 +158,8 @@ $(objpfx)tst-strtod5.out: $(gen-locales)
 $(objpfx)tst-strtol-locale.out: $(gen-locales)
 $(objpfx)tst-strtod-nan-locale.out: $(gen-locales)
 $(objpfx)tst-strfmon_l.out: $(gen-locales)
+$(objpfx)tst-strfrom.out: $(gen-locales)
+$(objpfx)tst-strfrom-locale.out: $(gen-locales)
 endif
 
 # Testdir has to be named stdlib and needs to be writable
diff --git a/stdlib/tst-strfrom-locale.c b/stdlib/tst-strfrom-locale.c
new file mode 100644
index 0000000..09945a9
--- /dev/null
+++ b/stdlib/tst-strfrom-locale.c
@@ -0,0 +1,178 @@
+/* Tests for strfromf, strfromd, strfroml functions.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#include <math.h>
+#include <locale.h>
+
+#include "tst-strtod.h"
+
+/* Hexadecimal tests.  */
+struct htest
+{
+  double val;
+  const char *fmt;
+  const char *exp[4];
+};
+static const struct htest htests[] = {
+  {0x1.ffp+6, "%a", { "0x1,ffp+6", "0x3,fep+5", "0x7,fcp+4", "0xf,f8p+3" } },
+  {0x1.88p+4, "%a", { "0x1,88p+4", "0x3,1p+3", "0x6,2p+2", "0xc,4p+1" } },
+  {-0x1.88p+5, "%A", { "-0X1,88P+5", "-0X3,1P+4", "-0X6,2P+3", "-0XC,4P+2" } },
+  {0x1.44p+10, "%a", { "0x1,44p+10", "0x2,88p+9", "0x5,1p+8", "0xa,2p+7"} },
+  {0x0.0040p+0, "%a",  { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13"} },
+  {10.0, "%a",  { "0x1,4p+3", "0x2,8p+2", "0x5p+1", "0xap+0"} },
+  {0, NULL, {NULL}},
+};
+
+/* Tests with buffer size small.  */
+struct stest
+{
+  const char *expect;
+  double val;
+  const char *fmt;
+  int size;
+  int rc;
+};
+static const struct stest stests[] = {
+  {"1234", 12345.345, "%g", 5, 7},
+  {"0,12", .125, "%f", 5, 8},
+  {"9,99", 9.999, "%.3f", 5, 5},
+  {"100", 1e2, "%g", 5, 3},
+  {NULL, 0, "%f", 50, 0},
+};
+
+struct val
+{
+  float f;
+  double d;
+  long double ld;
+};
+struct ltest
+{
+  const char *expect;
+  struct val values;
+  const char *fmt;
+  int size;
+  int rc;
+};
+static const struct ltest ltests[] = {
+  {"12,345000", { 12.345, 12.345, 12.345}, "%f", 50, 9},
+  {"9,999",  { 9.999, 9.999, 9.999}, "%.3f", 50, 5},
+  {"0,125000",  { .125, .125, .125}, "%f", 50, 8},
+  {"0,000000", { .0, .0, .0}, "%f", 50, 8},
+  {"0", { .0, .0, .0}, "%g", 50, 1},
+  {"9,900000", { 9.9, 9.9, 9.9}, "%f", 50, 8},
+  {"9,1", { 9.123456, 9.123456, 9.123456}, "%.5f", 4, 7},
+  {"9,91235", { 9.9123456, 9.91234567812345678, 9.91234567812345678}, "%g", 50, 7},
+  {"79,8765", { 79.876543, 79.8765432111, 79.8765432111}, "%G", 50, 7},
+  {"79,9", { 79.876543, 79.8765432111, 79.8765432111}, "%.3g", 50, 4},
+  {"1,000000e+38", { 1e+38, 1e+38, 1e+38}, "%e", 50, 12},
+  {"1,000000e+38", { 1e38, 1e38, 1e38}, "%e", 50, 12},
+  {"-1,000000e-37", { -1e-37, -1e-37, -1e-37}, "%e", 50, 13},
+  {"1,000000e-37", { 0.00000001e-29, 0.00000001e-29, 0.00000001e-29}, "%e", 50, 12},
+  {"1,000000e-37", { 1.000000e-37, 1.000000e-37, 1.000000e-37}, "%e", 50, 12},
+  {"5,900000e-16", { 5.9e-16, 5.9e-16, 5.9e-16}, "%e", 50, 12},
+  {"1,234500e+20", { 12.345e19, 12.345e19, 12.345e19}, "%e", 50, 12},
+  {"1,000000e+05", { 1e5, 1e5, 1e5}, "%e", 50, 12},
+  {"inf", { HUGE_VAL, HUGE_VAL, HUGE_VAL}, "%f", 50, 3},
+  {"-inf", { -HUGE_VAL, -HUGE_VAL, -HUGE_VAL}, "%g", 50, 4},
+  {"nan", { __builtin_nanf (""),  __builtin_nan (""),  __builtin_nanl ("")}, "%f", 50, 3},
+  {"NAN", {  __builtin_nansf (""), __builtin_nans (""), __builtin_nansl ("")}, "%G", 50, 3},
+  {"-NAN", { -NAN, -NAN, -NAN},"%G", 50, 4},
+  {"-INF", { -FLT_MAX * FLT_MAX, -DBL_MAX * DBL_MAX, -DBL_MAX * DBL_MAX}, "%G", 50, 4},
+  {NULL, {0}, "%e", 50, 0},
+};
+
+#define TEST_STRFROM(FSUF, FTYPE, FTOSTR, LSUF, CSUF)			\
+static int								\
+test_ ## FSUF (void)							\
+{									\
+  char buf[50], sbuf[5];						\
+  const struct ltest *lt;						\
+  const struct htest *ht;						\
+  const struct stest *st;						\
+  int status = 0;							\
+  int rc = 0, rc1 = 0;							\
+  for (st = stests; st->expect != NULL; ++st)				\
+    {									\
+      rc = FTOSTR (sbuf, st->size, st->fmt, st->val);			\
+      rc1 = (strcmp (sbuf, st->expect) != 0) || (rc != st->rc);		\
+      if (rc1)								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
+		  sbuf, rc, st->expect, st->rc);			\
+	  status++;							\
+	}								\
+    }									\
+  for (lt = ltests; lt->expect != NULL; ++lt)				\
+    {									\
+      rc = FTOSTR (buf, lt->size, lt->fmt, lt->values.FSUF);		\
+      rc1 = (strcmp (buf, lt->expect) != 0) || (rc != lt->rc);		\
+      if (rc1)								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
+		  buf, rc, lt->expect, lt->rc);				\
+	  status++;							\
+	}								\
+    }									\
+  for (ht = htests; ht->val != 0; ++ht)					\
+  {									\
+      rc = FTOSTR (buf, 50, ht->fmt, ht->val);				\
+      if (strcmp (buf, ht->exp[0]) == 0 ||				\
+	  strcmp (buf, ht->exp[1]) == 0 ||				\
+	  strcmp (buf, ht->exp[2]) == 0 ||				\
+	  strcmp (buf, ht->exp[3]) == 0)				\
+	continue;							\
+      else								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s or %s or %s "	\
+		  "or %s\n", buf, rc, ht->exp[0], ht->exp[1],		\
+		  ht->exp[2], ht->exp[3]);				\
+	  status++;							\
+	}								\
+  }									\
+  return status;							\
+}
+
+GEN_TEST_STRTOD_FOREACH (TEST_STRFROM)
+
+static int
+test_locale (const char *locale)
+{
+  printf ("Testing in locale: %s\n", locale);
+  if (setlocale (LC_ALL, locale) == NULL)
+    {
+      printf ("Cannot set locale %s\n", locale);
+    }
+  return STRTOD_TEST_FOREACH (test_);
+}
+static int
+do_test (void)
+{
+  int result = 0;
+  result += test_locale ("de_DE.UTF-8");
+  result += test_locale ("tr_TR.ISO-8859-9");
+  result += test_locale ("tr_TR.UTF-8");
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdlib/tst-strfrom.c b/stdlib/tst-strfrom.c
new file mode 100644
index 0000000..bcb6f29
--- /dev/null
+++ b/stdlib/tst-strfrom.c
@@ -0,0 +1,178 @@
+/* Tests for strfromf, strfromd, strfroml functions.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#include <math.h>
+#include <locale.h>
+
+#include "tst-strtod.h"
+
+/* Hexadecimal tests.  */
+struct htest
+{
+  double val;
+  const char *fmt;
+  const char *exp[4];
+};
+static const struct htest htests[] = {
+  {0x1.ffp+6, "%a", { "0x1.ffp+6", "0x3.fep+5", "0x7.fcp+4", "0xf.f8p+3" } },
+  {0x1.88p+4, "%a", { "0x1.88p+4", "0x3.1p+3", "0x6.2p+2", "0xc.4p+1" } },
+  {-0x1.88p+5, "%A", { "-0X1.88P+5", "-0X3.1P+4", "-0X6.2P+3", "-0XC.4P+2" } },
+  {0x1.44p+10, "%a", { "0x1.44p+10", "0x2.88p+9", "0x5.1p+8", "0xa.2p+7"} },
+  {0x0.0040p+0, "%a",  { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13"} },
+  {10.0, "%a",  { "0x1.4p+3", "0x2.8p+2", "0x5p+1", "0xap+0"} },
+  {0, NULL, {NULL}},
+};
+
+/* Tests with buffer size small.  */
+struct stest
+{
+  const char *expect;
+  double val;
+  const char *fmt;
+  int size;
+  int rc;
+};
+static const struct stest stests[] = {
+  {"1234", 12345.345, "%g", 5, 7},
+  {"0.12", .125, "%f", 5, 8},
+  {"9.99", 9.999, "%.3f", 5, 5},
+  {"100", 1e2, "%g", 5, 3},
+  {NULL, 0, "%f", 50, 0},
+};
+
+struct val
+{
+  float f;
+  double d;
+  long double ld;
+};
+struct ltest
+{
+  const char *expect;
+  struct val values;
+  const char *fmt;
+  int size;
+  int rc;
+};
+static const struct ltest ltests[] = {
+  {"12.345000", { 12.345, 12.345, 12.345}, "%f", 50, 9},
+  {"9.999",  { 9.999, 9.999, 9.999}, "%.3f", 50, 5},
+  {"0.125000",  { .125, .125, .125}, "%f", 50, 8},
+  {"0.000000", { .0, .0, .0}, "%f", 50, 8},
+  {"0", { .0, .0, .0}, "%g", 50, 1},
+  {"9.900000", { 9.9, 9.9, 9.9}, "%f", 50, 8},
+  {"9.1", { 9.123456, 9.123456, 9.123456}, "%.5f", 4, 7},
+  {"9.91235", { 9.9123456, 9.91234567812345678, 9.91234567812345678}, "%g", 50, 7},
+  {"79.8765", { 79.876543, 79.8765432111, 79.8765432111}, "%G", 50, 7},
+  {"79.9", { 79.876543, 79.8765432111, 79.8765432111}, "%.3g", 50, 4},
+  {"1.000000e+38", { 1e+38, 1e+38, 1e+38}, "%e", 50, 12},
+  {"1.000000e+38", { 1e38, 1e38, 1e38}, "%e", 50, 12},
+  {"-1.000000e-37", { -1e-37, -1e-37, -1e-37}, "%e", 50, 13},
+  {"1.000000e-37", { 0.00000001e-29, 0.00000001e-29, 0.00000001e-29}, "%e", 50, 12},
+  {"1.000000e-37", { 1.000000e-37, 1.000000e-37, 1.000000e-37}, "%e", 50, 12},
+  {"5.900000e-16", { 5.9e-16, 5.9e-16, 5.9e-16}, "%e", 50, 12},
+  {"1.234500e+20", { 12.345e19, 12.345e19, 12.345e19}, "%e", 50, 12},
+  {"1.000000e+05", { 1e5, 1e5, 1e5}, "%e", 50, 12},
+  {"inf", { HUGE_VAL, HUGE_VAL, HUGE_VAL}, "%f", 50, 3},
+  {"-inf", { -HUGE_VAL, -HUGE_VAL, -HUGE_VAL}, "%g", 50, 4},
+  {"nan", { __builtin_nanf (""),  __builtin_nan (""),  __builtin_nanl ("")}, "%f", 50, 3},
+  {"NAN", {  __builtin_nansf (""), __builtin_nans (""), __builtin_nansl ("")}, "%G", 50, 3},
+  {"-NAN", { -NAN, -NAN, -NAN},"%G", 50, 4},
+  {"-INF", { -FLT_MAX * FLT_MAX, -DBL_MAX * DBL_MAX, -DBL_MAX * DBL_MAX}, "%G", 50, 4},
+  {NULL, {0}, "%e", 50, 0},
+};
+
+#define TEST_STRFROM(FSUF, FTYPE, FTOSTR, LSUF, CSUF)			\
+static int								\
+test_ ## FSUF (void)							\
+{									\
+  char buf[50], sbuf[5];						\
+  const struct ltest *lt;						\
+  const struct htest *ht;						\
+  const struct stest *st;						\
+  int status = 0;							\
+  int rc = 0, rc1 = 0;							\
+  for (st = stests; st->expect != NULL; ++st)				\
+    {									\
+      rc = FTOSTR (sbuf, st->size, st->fmt, st->val);			\
+      rc1 = (strcmp (sbuf, st->expect) != 0) || (rc != st->rc);		\
+      if (rc1)								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
+		  sbuf, rc, st->expect, st->rc);			\
+	  status++;							\
+	}								\
+    }									\
+  for (lt = ltests; lt->expect != NULL; ++lt)				\
+    {									\
+      rc = FTOSTR (buf, lt->size, lt->fmt, lt->values.FSUF);		\
+      rc1 = (strcmp (buf, lt->expect) != 0) || (rc != lt->rc);		\
+      if (rc1)								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
+		  buf, rc, lt->expect, lt->rc);				\
+	  status++;							\
+	}								\
+    }									\
+  for (ht = htests; ht->val != 0; ++ht)					\
+  {									\
+      rc = FTOSTR (buf, 50, ht->fmt, ht->val);				\
+      if (strcmp (buf, ht->exp[0]) == 0 ||				\
+	  strcmp (buf, ht->exp[1]) == 0 ||				\
+	  strcmp (buf, ht->exp[2]) == 0 ||				\
+	  strcmp (buf, ht->exp[3]) == 0)				\
+	continue;							\
+      else								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s or %s or %s "	\
+		  "or %s\n", buf, rc, ht->exp[0], ht->exp[1],		\
+		  ht->exp[2], ht->exp[3]);				\
+	  status++;							\
+	}								\
+  }									\
+  return status;							\
+}
+
+GEN_TEST_STRTOD_FOREACH (TEST_STRFROM)
+
+static int
+test_locale (const char *locale)
+{
+  printf ("Testing in locale: %s\n", locale);
+  if (setlocale (LC_ALL, locale) == NULL)
+    {
+      printf ("Cannot set locale %s\n", locale);
+    }
+  return STRTOD_TEST_FOREACH (test_);
+}
+static int
+do_test (void)
+{
+  int result = 0;
+  result += test_locale ("C");
+  result += test_locale ("en_US.ISO-8859-1");
+  result += test_locale ("en_US.UTF-8");
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
-- 
2.4.11

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v8 1/3] Add strfromd, strfromf, and strfroml functions
  2016-10-14 17:31 [PATCH v8 0/3] New strfrom functions Gabriel F. T. Gomes
  2016-10-14 17:31 ` [PATCH v8 3/3] Add tests for " Gabriel F. T. Gomes
  2016-10-14 17:31 ` [PATCH v8 2/3] Refactor strtod tests Gabriel F. T. Gomes
@ 2016-10-14 17:31 ` Gabriel F. T. Gomes
  2 siblings, 0 replies; 11+ messages in thread
From: Gabriel F. T. Gomes @ 2016-10-14 17:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: joseph

ISO/IEC TS 18661-1 adds several functions in the strfrom family to stdlib.
This patch adds strfromd, strfromf, and strfroml.  This is being done in
preparation for the new floating-point type, float128.  The added functions
convert a floating-point value into a string, with configurable format.

2016-06-23  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>

	* NEWS: Mention the addition of strfromd, strfromf, and strfroml.
	* manual/arith.texi: Document strfromd, strfromf, strfroml.
	* stdlib/Makefile: Add strfromd, strfromf, and strfroml.
	* stdlib/Versions (GLIBC_2.25): Add strfromd, strfromf, and strfroml.
	* stdlib/stdlib.h (strfromd): New declaration.
	(strfromf): Likewise.
	(strfroml): Likewise.
	* stdlib/strfrom-skeleton.c: New file.  Generic implementation for
	strfrom.
	* stdlib/strfromd.c: New file.
	* stdlib/strfromf.c: Likewise.
	* stdlib/strfroml.c: Likewise.
	* stdlib/bits/stdlib-ldbl.h: Add redirection from strfroml to strfromd.
	* sysdeps/ieee754/ldbl-opt/Makefile: Add rule for nldbl-strfroml.c.
	* sysdeps/ieee754/ldbl-opt/nldbl-strfroml.c: New file;
	* sysdeps/arm/nacl/libc.abilist: Update.
	* sysdeps/unix/sysv/linux/aarch64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.
---
 NEWS                                               |   3 +
 manual/arith.texi                                  |  41 ++++++
 stdlib/Makefile                                    |   7 +
 stdlib/Versions                                    |   4 +
 stdlib/bits/stdlib-ldbl.h                          |   4 +
 stdlib/stdlib.h                                    |  18 ++-
 stdlib/strfrom-skeleton.c                          | 149 +++++++++++++++++++++
 stdlib/strfromd.c                                  |  22 +++
 stdlib/strfromf.c                                  |  22 +++
 stdlib/strfroml.c                                  |  22 +++
 sysdeps/arm/nacl/libc.abilist                      |   3 +
 sysdeps/ieee754/ldbl-opt/Makefile                  |   1 +
 sysdeps/ieee754/ldbl-opt/nldbl-strfroml.c          |   8 ++
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |   3 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |   3 +
 sysdeps/unix/sysv/linux/arm/libc.abilist           |   3 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |   3 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |   3 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |   3 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |   3 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/microblaze/libc.abilist    |   3 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |   3 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |   3 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |   3 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |   3 +
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |   3 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |   3 +
 .../sysv/linux/powerpc/powerpc64/libc-le.abilist   |   3 +
 .../unix/sysv/linux/powerpc/powerpc64/libc.abilist |   3 +
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |   3 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |   3 +
 sysdeps/unix/sysv/linux/sh/libc.abilist            |   3 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |   3 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |   3 +
 .../sysv/linux/tile/tilegx/tilegx32/libc.abilist   |   3 +
 .../sysv/linux/tile/tilegx/tilegx64/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist  |   3 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |   3 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |   3 +
 41 files changed, 387 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/strfrom-skeleton.c
 create mode 100644 stdlib/strfromd.c
 create mode 100644 stdlib/strfromf.c
 create mode 100644 stdlib/strfroml.c
 create mode 100644 sysdeps/ieee754/ldbl-opt/nldbl-strfroml.c

diff --git a/NEWS b/NEWS
index 22a5a5a..d08428d 100644
--- a/NEWS
+++ b/NEWS
@@ -57,6 +57,9 @@ Version 2.25
 
   - Total order functions: totalorder, totalorderf, totalorderl.
 
+* The functions strfromd, strfromf, and strfroml, from ISO/IEC TS 18661-1:2014,
+  are added to libc.  They convert a floating-point number into string.
+
 * The <sys/quota.h> header now includes the <linux/quota.h> header.  Support
   for the Linux quota interface which predates kernel version 2.4.22 has
   been removed.
diff --git a/manual/arith.texi b/manual/arith.texi
index 75d34c8..a61b513 100644
--- a/manual/arith.texi
+++ b/manual/arith.texi
@@ -20,6 +20,7 @@ These functions are declared in the header files @file{math.h} and
 * Complex Numbers::             The types.  Writing complex constants.
 * Operations on Complex::       Projection, conjugation, decomposition.
 * Parsing of Numbers::          Converting strings to numbers.
+* Printing of Floats::          Converting floating-point numbers to strings.
 * System V Number Conversion::  An archaic way to convert numbers to strings.
 @end menu
 
@@ -2772,6 +2773,46 @@ which take an additional argument, the locale to use in conversion.
 
 See also @ref{Parsing of Integers}.
 
+@node Printing of Floats
+@section Printing of Floats
+
+@pindex stdlib.h
+The @samp{strfrom} functions are declared in @file{stdlib.h}.
+
+@comment stdlib.h
+@comment ISO/IEC TS 18661-1
+@deftypefun int strfromd (char *restrict @var{string}, size_t @var{size}, const char *restrict @var{format}, double @var{value})
+@deftypefunx int strfromf (char *restrict @var{string}, size_t @var{size}, const char *restrict @var{format}, float @var{value})
+@deftypefunx int strfroml (char *restrict @var{string}, size_t @var{size}, const char *restrict @var{format}, long double @var{value})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@comment these functions depend on __printf_fp and __printf_fphex, which are
+@comment AS-unsafe (ascuheap) and AC-unsafe (acsmem).
+The functions @code{strfromd} (``string-from-double''), @code{strfromf}
+(``string-from-float''), and @code{strfroml} (``string-from-long-double'')
+convert the floating-point number @var{value} to a string of characters and
+stores them into the area pointed to by @var{string}.  The conversion
+writes at most @var{size} characters and respects the format specified by
+@var{format}.
+
+The format string must start with the character @samp{%}.  An optional
+precision follows, which starts with a period, @samp{.}, and may be
+followed by a decimal integer, representing the precision.  If a decimal
+integer is not specified after the period, the precision is taken to be
+zero.  The character @samp{*} is not allowed.  Finally, the format string
+ends with one of the following conversion specifiers: @samp{a}, @samp{A},
+@samp{e}, @samp{E}, @samp{f}, @samp{F}, @samp{g} or @samp{G} (@pxref{Table
+of Output Conversions}).  Invalid format strings result in undefined
+behavior.
+
+These functions return the number of characters that would have been
+written to @var{string} had @var{size} been sufficiently large, not
+counting the terminating null character.  Thus, the null-terminated output
+has been completely written if and only if the returned value is less than
+@var{size}.
+
+These functions were introduced by ISO/IEC TS 18661-1.
+@end deftypefun
+
 @node System V Number Conversion
 @section Old-fashioned System V number-to-string functions
 
diff --git a/stdlib/Makefile b/stdlib/Makefile
index de3ecbb..3cacb8b 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -46,6 +46,7 @@ routines	:=							      \
 	drand48_r erand48_r lrand48_r nrand48_r mrand48_r jrand48_r	      \
 	srand48_r seed48_r lcong48_r					      \
 	drand48-iter							      \
+	strfromf strfromd strfroml					      \
 	strtol strtoul strtoll strtoull					      \
 	strtol_l strtoul_l strtoll_l strtoull_l				      \
 	strtof strtod strtold						      \
@@ -122,6 +123,12 @@ CFLAGS-fmtmsg.c = -fexceptions
 CFLAGS-strfmon.c = $(libio-mtsafe)
 CFLAGS-strfmon_l.c = $(libio-mtsafe)
 
+# The strfrom class of functions call __printf_fp in order to convert the
+# floating-point value to characters.  This requires the value of IO_MTSAFE_IO.
+CFLAGS-strfromd.c = $(libio-mtsafe)
+CFLAGS-strfromf.c = $(libio-mtsafe)
+CFLAGS-strfroml.c = $(libio-mtsafe)
+
 CFLAGS-tst-bsearch.c = $(stack-align-test-flags)
 CFLAGS-tst-qsort.c = $(stack-align-test-flags)
 CFLAGS-tst-makecontext.c += -funwind-tables
diff --git a/stdlib/Versions b/stdlib/Versions
index 9c06b43..54416b7 100644
--- a/stdlib/Versions
+++ b/stdlib/Versions
@@ -112,6 +112,10 @@ libc {
   GLIBC_2.24 {
     quick_exit;
   }
+  GLIBC_2.25 {
+    # s*
+    strfromd; strfromf; strfroml;
+  }
   GLIBC_PRIVATE {
     # functions which have an additional interface since they are
     # are cancelable.
diff --git a/stdlib/bits/stdlib-ldbl.h b/stdlib/bits/stdlib-ldbl.h
index acff499..52fdc49 100644
--- a/stdlib/bits/stdlib-ldbl.h
+++ b/stdlib/bits/stdlib-ldbl.h
@@ -30,6 +30,10 @@ __END_NAMESPACE_C99
 __LDBL_REDIR1_DECL (strtold_l, strtod_l)
 #endif
 
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+__LDBL_REDIR1_DECL (strfroml, strfromd)
+#endif
+
 #ifdef __USE_MISC
 __LDBL_REDIR1_DECL (qecvt, ecvt)
 __LDBL_REDIR1_DECL (qfcvt, fcvt)
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index f0dc951..48f9a95 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -21,7 +21,8 @@
 
 #ifndef	_STDLIB_H
 
-#include <features.h>
+#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
+#include <bits/libc-header-start.h>
 
 /* Get size_t, wchar_t and NULL from <stddef.h>.  */
 #define		__need_size_t
@@ -178,6 +179,21 @@ extern unsigned long long int strtoull (const char *__restrict __nptr,
 __END_NAMESPACE_C99
 #endif /* ISO C99 or use MISC.  */
 
+/* Convert a floating-point number to a string.  */
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+extern int strfromd (char *__dest, size_t __size, const char *__format,
+		     double __f)
+     __THROW __nonnull ((3));
+
+extern int strfromf (char *__dest, size_t __size, const char *__format,
+		     float __f)
+     __THROW __nonnull ((3));
+
+extern int strfroml (char *__dest, size_t __size, const char *__format,
+		     long double __f)
+     __THROW __nonnull ((3));
+#endif
+
 
 #ifdef __USE_GNU
 /* The concept of one static locale per category is not very well
diff --git a/stdlib/strfrom-skeleton.c b/stdlib/strfrom-skeleton.c
new file mode 100644
index 0000000..8fd1beb
--- /dev/null
+++ b/stdlib/strfrom-skeleton.c
@@ -0,0 +1,149 @@
+/* Convert a floating-point number to string.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+/* Generic implementation for strfrom functions.  The implementation is generic
+   for several floating-point types (e.g.: float, double), so that each
+   function, such as strfromf and strfroml, share the same code, thus avoiding
+   code duplication.  */
+
+#include <ctype.h>
+#include "../libio/libioP.h"
+#include "../libio/strfile.h"
+#include <printf.h>
+#include <string.h>
+#include <locale/localeinfo.h>
+
+#define UCHAR_T char
+#define L_(Str) Str
+#define ISDIGIT(Ch) isdigit (Ch)
+#include "stdio-common/printf-parse.h"
+
+int
+STRFROM (char *dest, size_t size, const char *format, FLOAT f)
+{
+  _IO_strnfile sfile;
+#ifdef _IO_MTSAFE_IO
+  sfile.f._sbf._f._lock = NULL;
+#endif
+
+  int done;
+
+  /* Single-precision values need to be stored in a double type, because
+     __printf_fp_l and __printf_fphex do not accept the float type.  */
+  union {
+    double flt;
+    FLOAT value;
+  } fpnum;
+  const void *fpptr;
+  fpptr = &fpnum;
+
+  /* Variables to control the output format.  */
+  int precision = -1; /* printf_fp and printf_fphex treat this internally.  */
+  int specifier;
+  struct printf_info info;
+
+  /* Single-precision values need to be converted into double-precision,
+     because __printf_fp and __printf_fphex only accept double and long double
+     as the floating-point argument.  */
+  if (__builtin_types_compatible_p (FLOAT, float))
+    fpnum.flt = f;
+  else
+    fpnum.value = f;
+
+  /* Check if the first character in the format string is indeed the '%'
+     character.  Otherwise, abort.  */
+  if (*format == '%')
+    format++;
+  else
+    abort ();
+
+  /* The optional precision specification always starts with a '.'.  If such
+     character is present, read the precision.  */
+  if (*format == '.')
+    {
+      format++;
+
+      /* Parse the precision.  */
+      if (ISDIGIT (*format))
+	precision = read_int (&format);
+      /* If only the period is specified, the precision is taken as zero, as
+	 described in ISO/IEC 9899:2011, section 7.21.6.1, 4th paragraph, 3rd
+	 item.  */
+      else
+	precision = 0;
+    }
+
+  /* Now there is only the conversion specifier to be read.  */
+  switch (*format)
+    {
+    case 'a':
+    case 'A':
+    case 'e':
+    case 'E':
+    case 'f':
+    case 'F':
+    case 'g':
+    case 'G':
+      specifier = *format;
+      break;
+    default:
+      abort ();
+    }
+
+  /* The following code to prepare the virtual file has been adapted from the
+     function _IO_vsnprintf from libio.  */
+
+  if (size == 0)
+    {
+    /* When size is zero, nothing is written and dest may be a null pointer.
+       This is specified for snprintf in ISO/IEC 9899:2011, Section 7.21.6.5,
+       in the second paragraph.  Thus, if size is zero, prepare to use the
+       overflow buffer right from the start.  */
+      dest = sfile.overflow_buf;
+      size = sizeof (sfile.overflow_buf);
+    }
+
+  /* Prepare the virtual string file.  */
+  _IO_no_init (&sfile.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
+  _IO_JUMPS (&sfile.f._sbf) = &_IO_strn_jumps;
+  _IO_str_init_static_internal (&sfile.f, dest, size - 1, dest);
+
+  /* Prepare the format specification for printf_fp.  */
+  memset (&info, '\0', sizeof (info));
+
+  /* The functions strfromd and strfromf pass a floating-point number with
+     double precision to printf_fp, whereas strfroml passes a floating-point
+     number with long double precision.  The following line informs printf_fp
+     which type of floating-point number is being passed.  */
+  info.is_long_double = __builtin_types_compatible_p (FLOAT, long double);
+
+  /* Set info according to the format string.  */
+  info.prec = precision;
+  info.spec = specifier;
+
+  if (info.spec != 'a' && info.spec != 'A')
+    done = __printf_fp_l (&sfile.f._sbf._f, _NL_CURRENT_LOCALE, &info, &fpptr);
+  else
+    done = __printf_fphex (&sfile.f._sbf._f, &info, &fpptr);
+
+  /* Terminate the string.  */
+  if (sfile.f._sbf._f._IO_buf_base != sfile.overflow_buf)
+    *sfile.f._sbf._f._IO_write_ptr = '\0';
+
+  return done;
+}
diff --git a/stdlib/strfromd.c b/stdlib/strfromd.c
new file mode 100644
index 0000000..45a5790
--- /dev/null
+++ b/stdlib/strfromd.c
@@ -0,0 +1,22 @@
+/* Definitions for strfromd.  Implementation in stdlib/strfrom-skeleton.c.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#define FLOAT		double
+#define STRFROM		strfromd
+
+#include "strfrom-skeleton.c"
diff --git a/stdlib/strfromf.c b/stdlib/strfromf.c
new file mode 100644
index 0000000..f0b0858
--- /dev/null
+++ b/stdlib/strfromf.c
@@ -0,0 +1,22 @@
+/* Definitions for strfromf.  Implementation in stdlib/strfrom-skeleton.c.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#define FLOAT		float
+#define STRFROM		strfromf
+
+#include "strfrom-skeleton.c"
diff --git a/stdlib/strfroml.c b/stdlib/strfroml.c
new file mode 100644
index 0000000..8d5d15b
--- /dev/null
+++ b/stdlib/strfroml.c
@@ -0,0 +1,22 @@
+/* Definitions for strfroml.  Implementation in stdlib/strfrom-skeleton.c.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#define FLOAT		long double
+#define STRFROM		strfroml
+
+#include "strfrom-skeleton.c"
diff --git a/sysdeps/arm/nacl/libc.abilist b/sysdeps/arm/nacl/libc.abilist
index 4d3b0b9..807e43d 100644
--- a/sysdeps/arm/nacl/libc.abilist
+++ b/sysdeps/arm/nacl/libc.abilist
@@ -1846,3 +1846,6 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 gnu_dev_major F
 GLIBC_2.25 gnu_dev_makedev F
 GLIBC_2.25 gnu_dev_minor F
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile
index 12255d6..f465ed9 100644
--- a/sysdeps/ieee754/ldbl-opt/Makefile
+++ b/sysdeps/ieee754/ldbl-opt/Makefile
@@ -24,6 +24,7 @@ libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
 		 vdprintf_chk obstack_printf_chk obstack_vprintf_chk \
 		 syslog syslog_chk vsyslog vsyslog_chk \
 		 strfmon strfmon_l \
+		 strfroml \
 		 strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \
 		 qecvt qfcvt qgcvt qecvt_r qfcvt_r \
 		 isinf isnan finite signbit scalb log2 lgamma_r ceil \
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-strfroml.c b/sysdeps/ieee754/ldbl-opt/nldbl-strfroml.c
new file mode 100644
index 0000000..d6df69e
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-strfroml.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+strfroml (char *dest, size_t size, const char *format, long double f)
+{
+  return strfromd (dest, size, format, f);
+}
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 2c2f49e..77accdf 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2090,3 +2090,6 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 8afba47..659b7fc 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2001,6 +2001,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index de3bdf4..8bc979a 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -91,6 +91,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 3261b93..299b705 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1855,6 +1855,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 6465a55..f00345f 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2013,6 +2013,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 4536271..e5fcf88 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1877,6 +1877,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 287d7a5..8f382f6 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -92,6 +92,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index c9229fa..320b7fe 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1969,6 +1969,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 0409791..21b1426 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2090,3 +2090,6 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index f31653e..5c4b596 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1944,6 +1944,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index a56bd99..001fa6c 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1942,6 +1942,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 44552df..2d87001 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1940,6 +1940,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 8d2a09d..aa1ee66 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1935,6 +1935,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 0443b92..2471d68 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2131,3 +2131,6 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index ba9a29a..4b0cde8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1973,6 +1973,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index f19534c..0557c16 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1978,6 +1978,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index f8de1ab..821384e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2178,3 +2178,6 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 6819133..c40a3f1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -92,6 +92,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 _Exit F
 GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 4cd5d85..5b39a60 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1973,6 +1973,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 8cdb9df..a9db32f 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1874,6 +1874,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index 69791b4..294af0a 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1859,6 +1859,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index fce58a8..32747bd 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1965,6 +1965,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 16ce739..b0ac4d4 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1903,6 +1903,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
index f99c298..4d92d81 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
@@ -2097,3 +2097,6 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index c601ab0..a68aef7 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2097,3 +2097,6 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
index f99c298..4d92d81 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
@@ -2097,3 +2097,6 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 8e6fa57..b8623fc 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1854,6 +1854,9 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 1e12f48..a61d874 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2097,3 +2097,6 @@ GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 strfromd F
+GLIBC_2.25 strfromf F
+GLIBC_2.25 strfroml F
-- 
2.4.11

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v8 2/3] Refactor strtod tests
  2016-10-14 17:31 [PATCH v8 0/3] New strfrom functions Gabriel F. T. Gomes
  2016-10-14 17:31 ` [PATCH v8 3/3] Add tests for " Gabriel F. T. Gomes
@ 2016-10-14 17:31 ` Gabriel F. T. Gomes
  2016-10-14 17:31 ` [PATCH v8 1/3] Add strfromd, strfromf, and strfroml functions Gabriel F. T. Gomes
  2 siblings, 0 replies; 11+ messages in thread
From: Gabriel F. T. Gomes @ 2016-10-14 17:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: joseph

From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>

This patch changes strtod* tests to use strfrom* functions.

2016-08-30  Rajalakshmi Srinivasaraghavan  <raji@linux.vnet.ibm.com>

	* stdlib/bug-strtod.c: Refactor based on GEN_TEST_STRTOD_FOREACH.
	* stdlib/bug-strtod2.c: Likewise.
	* stdlib/tst-strtod-round-skeleton.c: Likewise.
	* stdlib/tst-strtod6.c: Likewise.
	* stdlib/tst-strtod.h (GEN_TEST_STRTOD_FOREACH): Use strfrom.
---
 stdlib/bug-strtod.c                |  6 +++---
 stdlib/bug-strtod2.c               |  2 +-
 stdlib/tst-strtod-round-skeleton.c | 24 +++++++++++-------------
 stdlib/tst-strtod.h                |  7 +++----
 stdlib/tst-strtod6.c               |  2 +-
 5 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/stdlib/bug-strtod.c b/stdlib/bug-strtod.c
index c8b56aa..ac5193e 100644
--- a/stdlib/bug-strtod.c
+++ b/stdlib/bug-strtod.c
@@ -23,7 +23,7 @@
 
 #include "tst-strtod.h"
 
-#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF)		\
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF)			\
 static int								\
 test_strto ## FSUF (void)						\
 {									\
@@ -45,8 +45,8 @@ test_strto ## FSUF (void)						\
 	{								\
 	  char fstr[FSTRLENMAX];					\
 	  char fcntstr[FSTRLENMAX];					\
-	  FTOSTR (fstr, sizeof (fstr), "%" FTOSTRM "g", f);		\
-	  FTOSTR (fcntstr, sizeof (fstr), "%" FTOSTRM "g", (FTYPE) cnt); \
+	  FTOSTR (fstr, sizeof (fstr), "%g", f);			\
+	  FTOSTR (fcntstr, sizeof (fstr), "%g", (FTYPE) cnt); 		\
 	  printf ("strto" #FSUF "(\"%s\") "				\
 		  "failed for cnt == %d (%s instead of %s)\n",		\
 		  buf, cnt, fstr, fcntstr);				\
diff --git a/stdlib/bug-strtod2.c b/stdlib/bug-strtod2.c
index cd13e9a..6128f2d 100644
--- a/stdlib/bug-strtod2.c
+++ b/stdlib/bug-strtod2.c
@@ -12,7 +12,7 @@ static const char *tests[] =
   };
 #define ntests (sizeof (tests) / sizeof (tests[0]))
 
-#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF)		\
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF)			\
 static int								\
 test_strto ## FSUF (void)						\
 {									\
diff --git a/stdlib/tst-strtod-round-skeleton.c b/stdlib/tst-strtod-round-skeleton.c
index 1853c52..2e99dbd 100644
--- a/stdlib/tst-strtod-round-skeleton.c
+++ b/stdlib/tst-strtod-round-skeleton.c
@@ -58,11 +58,11 @@
 
 /* Generator to create an FTYPE member variabled named FSUF
    used to populate struct member variables.  */
-#define FTYPE_MEMBER(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF)  \
+#define FTYPE_MEMBER(FSUF, FTYPE, FTOSTR, LSUF, CSUF)  \
        FTYPE FSUF;
 
 /* Likewise, but each member is of type bool.  */
-#define BOOL_MEMBER(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF)  \
+#define BOOL_MEMBER(FSUF, FTYPE, FTOSTR, LSUF, CSUF)  \
        bool FSUF;
 
 #define STRUCT_FOREACH_FLOAT_FTYPE GEN_TEST_STRTOD_FOREACH (FTYPE_MEMBER)
@@ -96,13 +96,13 @@
 /* long double is special, and handled above.  */
 
 /* Selector for expected result field of a given type.  */
-#define _ENTRY(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF, ...)  \
+#define _ENTRY(FSUF, FTYPE, FTOSTR, LSUF, CSUF, ...)  \
   CONCAT (CHOOSE_ ## FSUF (__VA_ARGS__), LSUF),
 #define ENTRY(...) \
   GEN_TEST_STRTOD_FOREACH (_ENTRY, __VA_ARGS__)
 
 /* Selector for boolean exact tag of expected results.  */
-#define _XNTRY(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF, ...)  \
+#define _XNTRY(FSUF, FTYPE, FTOSTR, LSUF, CSUF, ...)  \
   CHOOSE_ ## FSUF (__VA_ARGS__),
 #define XNTRY(...) \
   GEN_TEST_STRTOD_FOREACH (_XNTRY, __VA_ARGS__)
@@ -157,21 +157,19 @@ struct test {
 #define STR(x) STRX (x)
 #define FNPFXS STR (FNPFX)
 
-#define GEN_ONE_TEST(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF)	\
+#define GEN_ONE_TEST(FSUF, FTYPE, FTOSTR, LSUF, CSUF)		\
 {								\
   FTYPE f = STRTO (FSUF) (s, NULL);				\
   if (f != expected->FSUF					\
       || (copysign ## CSUF) (1.0 ## LSUF, f)			\
 	 != (copysign ## CSUF) (1.0 ## LSUF, expected->FSUF))	\
     {								\
-      CHAR efstr[FSTRLENMAX];					\
-      CHAR fstr[FSTRLENMAX];					\
-      FTOSTR (efstr, FSTRLENMAX, L_("%") L_(FTOSTRM) L_("a"),   \
-	      expected->FSUF);    				\
-      FTOSTR (fstr, FSTRLENMAX, L_("%") L_(FTOSTRM) L_("a"), f);\
-      printf (FNPFXS "to" #FSUF  " (" STRM ") returned " STRM   \
-	      " not " STRM " (%s)\n",				\
-	      s, fstr, efstr, mode_name);			\
+      char efstr[FSTRLENMAX];					\
+      char fstr[FSTRLENMAX];					\
+      FTOSTR (efstr, FSTRLENMAX, "%a", expected->FSUF);		\
+      FTOSTR (fstr, FSTRLENMAX, "%a", f);			\
+      printf (FNPFXS "to" #FSUF  " (" STRM ") returned %s not "	\
+	      "%s (%s)\n", s, fstr, efstr, mode_name);		\
       if (ROUNDING_TESTS (FTYPE, rnd_mode) || exact->FSUF)	\
 	result = 1;						\
       else							\
diff --git a/stdlib/tst-strtod.h b/stdlib/tst-strtod.h
index 607cf39..b8e9cd4 100644
--- a/stdlib/tst-strtod.h
+++ b/stdlib/tst-strtod.h
@@ -23,14 +23,13 @@
 
 /* Splat n variants of the same test for the various strtod functions.  */
 #define GEN_TEST_STRTOD_FOREACH(mfunc, ...)			 \
-    mfunc (  f,       float, snprintf,  "", f, f, ##__VA_ARGS__) \
-    mfunc (  d,      double, snprintf,  "",  ,  , ##__VA_ARGS__) \
-    mfunc ( ld, long double, snprintf, "L", L, l, ##__VA_ARGS__)
+    mfunc (  f,       float, strfromf, f, f, ##__VA_ARGS__)	 \
+    mfunc (  d,      double, strfromd,  ,  , ##__VA_ARGS__)	 \
+    mfunc ( ld, long double, strfroml, L, l, ##__VA_ARGS__)
 /* 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
 */
diff --git a/stdlib/tst-strtod6.c b/stdlib/tst-strtod6.c
index 6b3bb84..9bfbdc2 100644
--- a/stdlib/tst-strtod6.c
+++ b/stdlib/tst-strtod6.c
@@ -5,7 +5,7 @@
 
 #include "tst-strtod.h"
 
-#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF) \
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF)	  \
 static int						  \
 test_strto ## FSUF (const char str[])			  \
 {							  \
-- 
2.4.11

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v8 3/3] Add tests for strfrom functions
  2016-10-14 17:31 ` [PATCH v8 3/3] Add tests for " Gabriel F. T. Gomes
@ 2016-10-14 18:50   ` Gabriel F. T. Gomes
  2016-10-14 21:40   ` Joseph Myers
  1 sibling, 0 replies; 11+ messages in thread
From: Gabriel F. T. Gomes @ 2016-10-14 18:50 UTC (permalink / raw)
  To: libc-alpha; +Cc: joseph

On Fri, 14 Oct 2016 14:31:25 -0300
"Gabriel F. T. Gomes" <gftg@linux.vnet.ibm.com> wrote:

> From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
> 
> 2016-10-13  Rajalakshmi Srinivasaraghavan  <raji@linux.vnet.ibm.com>
> 
> 	* stdlib/Makefile (tests): Add tst-strfrom and tst-strfrom-locale.
> 	* stdlib/tst-strfrom.c: New file.
> 	* stdlib/tst-strfrom-locale.c: New file.
> 
> wi: http://dagger1.rch.stglabs.ibm.com:5678/b/tqzrQAkzP337NcJ5P/corelibs/uqHc2aKRqa6hNni2P
> Change-Id: I7c5975a608c2a8085db544a7f9de31c921f545ca

Please ignore these two lines...  I sent them by accident. :(
I already remove them in my local branch.

> ---
>  stdlib/Makefile             |   4 +-
>  stdlib/tst-strfrom-locale.c | 178 ++++++++++++++++++++++++++++++++++++++++++++
>  stdlib/tst-strfrom.c        | 178 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 359 insertions(+), 1 deletion(-)
>  create mode 100644 stdlib/tst-strfrom-locale.c
>  create mode 100644 stdlib/tst-strfrom.c
> 
> diff --git a/stdlib/Makefile b/stdlib/Makefile
> index 3cacb8b..3cce9d9 100644
> --- a/stdlib/Makefile
> +++ b/stdlib/Makefile
> @@ -79,7 +79,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
>  		   tst-setcontext3 tst-tls-atexit-nodelete		    \
>  		   tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l    \
>  		   tst-quick_exit tst-thread-quick_exit tst-width	    \
> -		   tst-width-stdint
> +		   tst-width-stdint tst-strfrom tst-strfrom-locale
>  tests-static	:= tst-secure-getenv
>  ifeq ($(have-cxx-thread_local),yes)
>  CFLAGS-tst-quick_exit.o = -std=c++11
> @@ -158,6 +158,8 @@ $(objpfx)tst-strtod5.out: $(gen-locales)
>  $(objpfx)tst-strtol-locale.out: $(gen-locales)
>  $(objpfx)tst-strtod-nan-locale.out: $(gen-locales)
>  $(objpfx)tst-strfmon_l.out: $(gen-locales)
> +$(objpfx)tst-strfrom.out: $(gen-locales)
> +$(objpfx)tst-strfrom-locale.out: $(gen-locales)
>  endif
> 
>  # Testdir has to be named stdlib and needs to be writable
> diff --git a/stdlib/tst-strfrom-locale.c b/stdlib/tst-strfrom-locale.c
> new file mode 100644
> index 0000000..09945a9
> --- /dev/null
> +++ b/stdlib/tst-strfrom-locale.c
> @@ -0,0 +1,178 @@
> +/* Tests for strfromf, strfromd, strfroml functions.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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/>.  */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <float.h>
> +#include <math.h>
> +#include <locale.h>
> +
> +#include "tst-strtod.h"
> +
> +/* Hexadecimal tests.  */
> +struct htest
> +{
> +  double val;
> +  const char *fmt;
> +  const char *exp[4];
> +};
> +static const struct htest htests[] = {
> +  {0x1.ffp+6, "%a", { "0x1,ffp+6", "0x3,fep+5", "0x7,fcp+4", "0xf,f8p+3" } },
> +  {0x1.88p+4, "%a", { "0x1,88p+4", "0x3,1p+3", "0x6,2p+2", "0xc,4p+1" } },
> +  {-0x1.88p+5, "%A", { "-0X1,88P+5", "-0X3,1P+4", "-0X6,2P+3", "-0XC,4P+2" } },
> +  {0x1.44p+10, "%a", { "0x1,44p+10", "0x2,88p+9", "0x5,1p+8", "0xa,2p+7"} },
> +  {0x0.0040p+0, "%a",  { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13"} },
> +  {10.0, "%a",  { "0x1,4p+3", "0x2,8p+2", "0x5p+1", "0xap+0"} },
> +  {0, NULL, {NULL}},
> +};
> +
> +/* Tests with buffer size small.  */
> +struct stest
> +{
> +  const char *expect;
> +  double val;
> +  const char *fmt;
> +  int size;
> +  int rc;
> +};
> +static const struct stest stests[] = {
> +  {"1234", 12345.345, "%g", 5, 7},
> +  {"0,12", .125, "%f", 5, 8},
> +  {"9,99", 9.999, "%.3f", 5, 5},
> +  {"100", 1e2, "%g", 5, 3},
> +  {NULL, 0, "%f", 50, 0},
> +};
> +
> +struct val
> +{
> +  float f;
> +  double d;
> +  long double ld;
> +};
> +struct ltest
> +{
> +  const char *expect;
> +  struct val values;
> +  const char *fmt;
> +  int size;
> +  int rc;
> +};
> +static const struct ltest ltests[] = {
> +  {"12,345000", { 12.345, 12.345, 12.345}, "%f", 50, 9},
> +  {"9,999",  { 9.999, 9.999, 9.999}, "%.3f", 50, 5},
> +  {"0,125000",  { .125, .125, .125}, "%f", 50, 8},
> +  {"0,000000", { .0, .0, .0}, "%f", 50, 8},
> +  {"0", { .0, .0, .0}, "%g", 50, 1},
> +  {"9,900000", { 9.9, 9.9, 9.9}, "%f", 50, 8},
> +  {"9,1", { 9.123456, 9.123456, 9.123456}, "%.5f", 4, 7},
> +  {"9,91235", { 9.9123456, 9.91234567812345678, 9.91234567812345678}, "%g", 50, 7},
> +  {"79,8765", { 79.876543, 79.8765432111, 79.8765432111}, "%G", 50, 7},
> +  {"79,9", { 79.876543, 79.8765432111, 79.8765432111}, "%.3g", 50, 4},
> +  {"1,000000e+38", { 1e+38, 1e+38, 1e+38}, "%e", 50, 12},
> +  {"1,000000e+38", { 1e38, 1e38, 1e38}, "%e", 50, 12},
> +  {"-1,000000e-37", { -1e-37, -1e-37, -1e-37}, "%e", 50, 13},
> +  {"1,000000e-37", { 0.00000001e-29, 0.00000001e-29, 0.00000001e-29}, "%e", 50, 12},
> +  {"1,000000e-37", { 1.000000e-37, 1.000000e-37, 1.000000e-37}, "%e", 50, 12},
> +  {"5,900000e-16", { 5.9e-16, 5.9e-16, 5.9e-16}, "%e", 50, 12},
> +  {"1,234500e+20", { 12.345e19, 12.345e19, 12.345e19}, "%e", 50, 12},
> +  {"1,000000e+05", { 1e5, 1e5, 1e5}, "%e", 50, 12},
> +  {"inf", { HUGE_VAL, HUGE_VAL, HUGE_VAL}, "%f", 50, 3},
> +  {"-inf", { -HUGE_VAL, -HUGE_VAL, -HUGE_VAL}, "%g", 50, 4},
> +  {"nan", { __builtin_nanf (""),  __builtin_nan (""),  __builtin_nanl ("")}, "%f", 50, 3},
> +  {"NAN", {  __builtin_nansf (""), __builtin_nans (""), __builtin_nansl ("")}, "%G", 50, 3},
> +  {"-NAN", { -NAN, -NAN, -NAN},"%G", 50, 4},
> +  {"-INF", { -FLT_MAX * FLT_MAX, -DBL_MAX * DBL_MAX, -DBL_MAX * DBL_MAX}, "%G", 50, 4},
> +  {NULL, {0}, "%e", 50, 0},
> +};
> +
> +#define TEST_STRFROM(FSUF, FTYPE, FTOSTR, LSUF, CSUF)			\
> +static int								\
> +test_ ## FSUF (void)							\
> +{									\
> +  char buf[50], sbuf[5];						\
> +  const struct ltest *lt;						\
> +  const struct htest *ht;						\
> +  const struct stest *st;						\
> +  int status = 0;							\
> +  int rc = 0, rc1 = 0;							\
> +  for (st = stests; st->expect != NULL; ++st)				\
> +    {									\
> +      rc = FTOSTR (sbuf, st->size, st->fmt, st->val);			\
> +      rc1 = (strcmp (sbuf, st->expect) != 0) || (rc != st->rc);		\
> +      if (rc1)								\
> +	{								\
> +	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
> +		  sbuf, rc, st->expect, st->rc);			\
> +	  status++;							\
> +	}								\
> +    }									\
> +  for (lt = ltests; lt->expect != NULL; ++lt)				\
> +    {									\
> +      rc = FTOSTR (buf, lt->size, lt->fmt, lt->values.FSUF);		\
> +      rc1 = (strcmp (buf, lt->expect) != 0) || (rc != lt->rc);		\
> +      if (rc1)								\
> +	{								\
> +	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
> +		  buf, rc, lt->expect, lt->rc);				\
> +	  status++;							\
> +	}								\
> +    }									\
> +  for (ht = htests; ht->val != 0; ++ht)					\
> +  {									\
> +      rc = FTOSTR (buf, 50, ht->fmt, ht->val);				\
> +      if (strcmp (buf, ht->exp[0]) == 0 ||				\
> +	  strcmp (buf, ht->exp[1]) == 0 ||				\
> +	  strcmp (buf, ht->exp[2]) == 0 ||				\
> +	  strcmp (buf, ht->exp[3]) == 0)				\
> +	continue;							\
> +      else								\
> +	{								\
> +	  printf (#FTOSTR ": got %s (%d), expected %s or %s or %s "	\
> +		  "or %s\n", buf, rc, ht->exp[0], ht->exp[1],		\
> +		  ht->exp[2], ht->exp[3]);				\
> +	  status++;							\
> +	}								\
> +  }									\
> +  return status;							\
> +}
> +
> +GEN_TEST_STRTOD_FOREACH (TEST_STRFROM)
> +
> +static int
> +test_locale (const char *locale)
> +{
> +  printf ("Testing in locale: %s\n", locale);
> +  if (setlocale (LC_ALL, locale) == NULL)
> +    {
> +      printf ("Cannot set locale %s\n", locale);
> +    }
> +  return STRTOD_TEST_FOREACH (test_);
> +}
> +static int
> +do_test (void)
> +{
> +  int result = 0;
> +  result += test_locale ("de_DE.UTF-8");
> +  result += test_locale ("tr_TR.ISO-8859-9");
> +  result += test_locale ("tr_TR.UTF-8");
> +  return result;
> +}
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/stdlib/tst-strfrom.c b/stdlib/tst-strfrom.c
> new file mode 100644
> index 0000000..bcb6f29
> --- /dev/null
> +++ b/stdlib/tst-strfrom.c
> @@ -0,0 +1,178 @@
> +/* Tests for strfromf, strfromd, strfroml functions.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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/>.  */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <float.h>
> +#include <math.h>
> +#include <locale.h>
> +
> +#include "tst-strtod.h"
> +
> +/* Hexadecimal tests.  */
> +struct htest
> +{
> +  double val;
> +  const char *fmt;
> +  const char *exp[4];
> +};
> +static const struct htest htests[] = {
> +  {0x1.ffp+6, "%a", { "0x1.ffp+6", "0x3.fep+5", "0x7.fcp+4", "0xf.f8p+3" } },
> +  {0x1.88p+4, "%a", { "0x1.88p+4", "0x3.1p+3", "0x6.2p+2", "0xc.4p+1" } },
> +  {-0x1.88p+5, "%A", { "-0X1.88P+5", "-0X3.1P+4", "-0X6.2P+3", "-0XC.4P+2" } },
> +  {0x1.44p+10, "%a", { "0x1.44p+10", "0x2.88p+9", "0x5.1p+8", "0xa.2p+7"} },
> +  {0x0.0040p+0, "%a",  { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13"} },
> +  {10.0, "%a",  { "0x1.4p+3", "0x2.8p+2", "0x5p+1", "0xap+0"} },
> +  {0, NULL, {NULL}},
> +};
> +
> +/* Tests with buffer size small.  */
> +struct stest
> +{
> +  const char *expect;
> +  double val;
> +  const char *fmt;
> +  int size;
> +  int rc;
> +};
> +static const struct stest stests[] = {
> +  {"1234", 12345.345, "%g", 5, 7},
> +  {"0.12", .125, "%f", 5, 8},
> +  {"9.99", 9.999, "%.3f", 5, 5},
> +  {"100", 1e2, "%g", 5, 3},
> +  {NULL, 0, "%f", 50, 0},
> +};
> +
> +struct val
> +{
> +  float f;
> +  double d;
> +  long double ld;
> +};
> +struct ltest
> +{
> +  const char *expect;
> +  struct val values;
> +  const char *fmt;
> +  int size;
> +  int rc;
> +};
> +static const struct ltest ltests[] = {
> +  {"12.345000", { 12.345, 12.345, 12.345}, "%f", 50, 9},
> +  {"9.999",  { 9.999, 9.999, 9.999}, "%.3f", 50, 5},
> +  {"0.125000",  { .125, .125, .125}, "%f", 50, 8},
> +  {"0.000000", { .0, .0, .0}, "%f", 50, 8},
> +  {"0", { .0, .0, .0}, "%g", 50, 1},
> +  {"9.900000", { 9.9, 9.9, 9.9}, "%f", 50, 8},
> +  {"9.1", { 9.123456, 9.123456, 9.123456}, "%.5f", 4, 7},
> +  {"9.91235", { 9.9123456, 9.91234567812345678, 9.91234567812345678}, "%g", 50, 7},
> +  {"79.8765", { 79.876543, 79.8765432111, 79.8765432111}, "%G", 50, 7},
> +  {"79.9", { 79.876543, 79.8765432111, 79.8765432111}, "%.3g", 50, 4},
> +  {"1.000000e+38", { 1e+38, 1e+38, 1e+38}, "%e", 50, 12},
> +  {"1.000000e+38", { 1e38, 1e38, 1e38}, "%e", 50, 12},
> +  {"-1.000000e-37", { -1e-37, -1e-37, -1e-37}, "%e", 50, 13},
> +  {"1.000000e-37", { 0.00000001e-29, 0.00000001e-29, 0.00000001e-29}, "%e", 50, 12},
> +  {"1.000000e-37", { 1.000000e-37, 1.000000e-37, 1.000000e-37}, "%e", 50, 12},
> +  {"5.900000e-16", { 5.9e-16, 5.9e-16, 5.9e-16}, "%e", 50, 12},
> +  {"1.234500e+20", { 12.345e19, 12.345e19, 12.345e19}, "%e", 50, 12},
> +  {"1.000000e+05", { 1e5, 1e5, 1e5}, "%e", 50, 12},
> +  {"inf", { HUGE_VAL, HUGE_VAL, HUGE_VAL}, "%f", 50, 3},
> +  {"-inf", { -HUGE_VAL, -HUGE_VAL, -HUGE_VAL}, "%g", 50, 4},
> +  {"nan", { __builtin_nanf (""),  __builtin_nan (""),  __builtin_nanl ("")}, "%f", 50, 3},
> +  {"NAN", {  __builtin_nansf (""), __builtin_nans (""), __builtin_nansl ("")}, "%G", 50, 3},
> +  {"-NAN", { -NAN, -NAN, -NAN},"%G", 50, 4},
> +  {"-INF", { -FLT_MAX * FLT_MAX, -DBL_MAX * DBL_MAX, -DBL_MAX * DBL_MAX}, "%G", 50, 4},
> +  {NULL, {0}, "%e", 50, 0},
> +};
> +
> +#define TEST_STRFROM(FSUF, FTYPE, FTOSTR, LSUF, CSUF)			\
> +static int								\
> +test_ ## FSUF (void)							\
> +{									\
> +  char buf[50], sbuf[5];						\
> +  const struct ltest *lt;						\
> +  const struct htest *ht;						\
> +  const struct stest *st;						\
> +  int status = 0;							\
> +  int rc = 0, rc1 = 0;							\
> +  for (st = stests; st->expect != NULL; ++st)				\
> +    {									\
> +      rc = FTOSTR (sbuf, st->size, st->fmt, st->val);			\
> +      rc1 = (strcmp (sbuf, st->expect) != 0) || (rc != st->rc);		\
> +      if (rc1)								\
> +	{								\
> +	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
> +		  sbuf, rc, st->expect, st->rc);			\
> +	  status++;							\
> +	}								\
> +    }									\
> +  for (lt = ltests; lt->expect != NULL; ++lt)				\
> +    {									\
> +      rc = FTOSTR (buf, lt->size, lt->fmt, lt->values.FSUF);		\
> +      rc1 = (strcmp (buf, lt->expect) != 0) || (rc != lt->rc);		\
> +      if (rc1)								\
> +	{								\
> +	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
> +		  buf, rc, lt->expect, lt->rc);				\
> +	  status++;							\
> +	}								\
> +    }									\
> +  for (ht = htests; ht->val != 0; ++ht)					\
> +  {									\
> +      rc = FTOSTR (buf, 50, ht->fmt, ht->val);				\
> +      if (strcmp (buf, ht->exp[0]) == 0 ||				\
> +	  strcmp (buf, ht->exp[1]) == 0 ||				\
> +	  strcmp (buf, ht->exp[2]) == 0 ||				\
> +	  strcmp (buf, ht->exp[3]) == 0)				\
> +	continue;							\
> +      else								\
> +	{								\
> +	  printf (#FTOSTR ": got %s (%d), expected %s or %s or %s "	\
> +		  "or %s\n", buf, rc, ht->exp[0], ht->exp[1],		\
> +		  ht->exp[2], ht->exp[3]);				\
> +	  status++;							\
> +	}								\
> +  }									\
> +  return status;							\
> +}
> +
> +GEN_TEST_STRTOD_FOREACH (TEST_STRFROM)
> +
> +static int
> +test_locale (const char *locale)
> +{
> +  printf ("Testing in locale: %s\n", locale);
> +  if (setlocale (LC_ALL, locale) == NULL)
> +    {
> +      printf ("Cannot set locale %s\n", locale);
> +    }
> +  return STRTOD_TEST_FOREACH (test_);
> +}
> +static int
> +do_test (void)
> +{
> +  int result = 0;
> +  result += test_locale ("C");
> +  result += test_locale ("en_US.ISO-8859-1");
> +  result += test_locale ("en_US.UTF-8");
> +  return result;
> +}
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v8 3/3] Add tests for strfrom functions
  2016-10-14 17:31 ` [PATCH v8 3/3] Add tests for " Gabriel F. T. Gomes
  2016-10-14 18:50   ` Gabriel F. T. Gomes
@ 2016-10-14 21:40   ` Joseph Myers
  2016-10-18 15:08     ` [PATCH v9 " Gabriel F. T. Gomes
  1 sibling, 1 reply; 11+ messages in thread
From: Joseph Myers @ 2016-10-14 21:40 UTC (permalink / raw)
  To: Gabriel F. T. Gomes; +Cc: libc-alpha

On Fri, 14 Oct 2016, Gabriel F. T. Gomes wrote:

> +  double val;

Some of the test arrays are still using double rather than using the type 
under test in a type-generic way (thus, either having multiple arrays or 
having a struct member per type as in the tst-strtod-round tests).

> +struct val
> +{
> +  float f;
> +  double d;
> +  long double ld;
> +};

Although this one has a struct with multiple types, it's not properly 
type-generic.  I'd expect use of something like STRUCT_FOREACH_FLOAT_FTYPE 
(in tst-strtod-round-skeleton.c) to define such a struct, and then such a 
macro concatenting a suffix to the constants to fill in the initializers.

If the tests are properly type-generic, only GEN_TEST_STRTOD_FOREACH / 
STRTOD_TEST_FOREACH in tst-strtod.h should likely need to change to make 
them cover an extra type.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v9 3/3] Add tests for strfrom functions
  2016-10-14 21:40   ` Joseph Myers
@ 2016-10-18 15:08     ` Gabriel F. T. Gomes
  2016-10-20 16:56       ` Joseph Myers
  0 siblings, 1 reply; 11+ messages in thread
From: Gabriel F. T. Gomes @ 2016-10-18 15:08 UTC (permalink / raw)
  To: libc-alpha; +Cc: joseph

From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>

Tested for x86_64, ppc64, ppc64le and s390.

-- 8< --
2016-10-18  Rajalakshmi Srinivasaraghavan  <raji@linux.vnet.ibm.com>

	* stdlib/Makefile (tests): Add tst-strfrom and tst-strfrom-locale.
	* stdlib/tst-strfrom.h: New file.
	* stdlib/tst-strfrom.c: New file.
	* stdlib/tst-strfrom-locale.c: New file.
---
 stdlib/Makefile             |   4 +-
 stdlib/tst-strfrom-locale.c | 115 ++++++++++++++++++++++++++++++++++++++++
 stdlib/tst-strfrom.c        | 116 ++++++++++++++++++++++++++++++++++++++++
 stdlib/tst-strfrom.h        | 126 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 360 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-strfrom-locale.c
 create mode 100644 stdlib/tst-strfrom.c
 create mode 100644 stdlib/tst-strfrom.h

diff --git a/stdlib/Makefile b/stdlib/Makefile
index 3cacb8b..3cce9d9 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -79,7 +79,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   tst-setcontext3 tst-tls-atexit-nodelete		    \
 		   tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l    \
 		   tst-quick_exit tst-thread-quick_exit tst-width	    \
-		   tst-width-stdint
+		   tst-width-stdint tst-strfrom tst-strfrom-locale
 tests-static	:= tst-secure-getenv
 ifeq ($(have-cxx-thread_local),yes)
 CFLAGS-tst-quick_exit.o = -std=c++11
@@ -158,6 +158,8 @@ $(objpfx)tst-strtod5.out: $(gen-locales)
 $(objpfx)tst-strtol-locale.out: $(gen-locales)
 $(objpfx)tst-strtod-nan-locale.out: $(gen-locales)
 $(objpfx)tst-strfmon_l.out: $(gen-locales)
+$(objpfx)tst-strfrom.out: $(gen-locales)
+$(objpfx)tst-strfrom-locale.out: $(gen-locales)
 endif
 
 # Testdir has to be named stdlib and needs to be writable
diff --git a/stdlib/tst-strfrom-locale.c b/stdlib/tst-strfrom-locale.c
new file mode 100644
index 0000000..e30f43e
--- /dev/null
+++ b/stdlib/tst-strfrom-locale.c
@@ -0,0 +1,115 @@
+/* Tests for strfromf, strfromd, strfroml functions.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include "tst-strfrom.h"
+
+static const struct test tests[] = {
+  TEST ("12,345000", "%f", 50, 9,
+	12.345, 12.345, 12.345),
+  TEST ("9,999", "%.3f", 50, 5,
+	9.999, 9.999, 9.999),
+  TEST ("0,125000", "%f", 50, 8,
+	.125, .125, .125),
+  TEST ("0,000000", "%f", 50, 8,
+	.0, .0, .0),
+  TEST ("0", "%g", 50, 1,
+	.0, .0, .0),
+  TEST ("9,900000", "%f", 50, 8,
+	9.9, 9.9, 9.9),
+  TEST ("9,1", "%.5f", 4, 7,
+	9.123456, 9.123456, 9.123456),
+  TEST ("9,91235", "%g", 50, 7,
+	9.9123456, 9.91234567812345678, 9.91234567812345678),
+  TEST ("79,8765", "%G", 50, 7,
+	79.876543, 79.8765432111, 79.8765432111),
+  TEST ("79,9", "%.3g", 50, 4,
+	79.876543, 79.8765432111, 79.8765432111),
+  TEST ("1,000000e+38", "%e", 50, 12,
+	1e+38, 1e+38, 1e+38),
+  TEST ("1,000000e+38", "%e", 50, 12,
+	1e38, 1e38, 1e38),
+  TEST ("-1,000000e-37", "%e", 50, 13,
+	-1e-37, -1e-37, -1e-37),
+  TEST ("1,000000e-37", "%e", 50, 12,
+	0.00000001e-29, 0.00000001e-29, 0.00000001e-29),
+  TEST ("1,000000e-37", "%e", 50, 12,
+	1.000000e-37, 1.000000e-37, 1.000000e-37),
+  TEST ("5,900000e-16", "%e", 50, 12,
+	5.9e-16, 5.9e-16, 5.9e-16),
+  TEST ("1,234500e+20", "%e", 50, 12,
+	12.345e19, 12.345e19, 12.345e19),
+  TEST ("1,000000e+05", "%e", 50, 12,
+	1e5, 1e5, 1e5),
+  TEST ("-NAN", "%G", 50, 4,
+	-NAN_, -NAN_, -NAN_),
+  TEST ("-inf", "%g", 50, 4,
+	-INF, -INF, -INF),
+  TEST ("inf", "%g", 50, 3,
+	INF, INF, INF)
+   };
+/* Tests with buffer size small.  */
+static const struct test stest[] = {
+  TEST ("1234", "%g", 5, 7,
+	12345.345, 12345.345, 12345.345),
+  TEST ("0,12", "%f", 5, 8,
+	.125, .125, .125),
+  TEST ("9,99", "%.3f", 5, 5,
+	9.999, 9.999, 9.999),
+  TEST ("100", "%g", 5, 3,
+	1e2, 1e2, 1e2)
+};
+/* Hexadecimal tests.  */
+static const struct htests htest[] = {
+  {"%a", { "0x1,ffp+6", "0x3,fep+5", "0x7,fcp+4", "0xf,f8p+3" },
+   {0x1.ffp+6, 0x1.ffp+6, 0x1.ffp+6}},
+  {"%a", { "0x1,88p+4", "0x3,1p+3", "0x6,2p+2", "0xc,4p+1" },
+   {0x1.88p+4, 0x1.88p+4, 0x1.88p+4}},
+  {"%A", { "-0X1,88P+5", "-0X3,1P+4", "-0X6,2P+3", "-0XC,4P+2" },
+   {-0x1.88p+5, -0x1.88p+5, -0x1.88p+5}},
+  {"%a", { "0x1,44p+10", "0x2,88p+9", "0x5,1p+8", "0xa,2p+7"},
+   {0x1.44p+10, 0x1.44p+10, 0x1.44p+10}},
+  {"%a", { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13"},
+   {0x0.0040p+0, 0x0.0040p+0, 0x0.0040p+0}},
+  {"%a", { "0x1,4p+3", "0x2,8p+2", "0x5p+1", "0xap+0"},
+   {10.0, 10.0, 10.0}}
+};
+GEN_TEST_STRTOD_FOREACH (TEST_STRFROM)
+
+static int
+test_locale (const char *locale)
+{
+  printf ("Testing in locale: %s\n", locale);
+  if (setlocale (LC_ALL, locale) == NULL)
+    {
+      printf ("Cannot set locale %s\n", locale);
+    }
+  return STRTOD_TEST_FOREACH (test_);
+}
+
+static int
+do_test (void)
+{
+  int result = 0;
+  result += test_locale ("de_DE.UTF-8");
+  result += test_locale ("tr_TR.ISO-8859-9");
+  result += test_locale ("tr_TR.UTF-8");
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdlib/tst-strfrom.c b/stdlib/tst-strfrom.c
new file mode 100644
index 0000000..686bede
--- /dev/null
+++ b/stdlib/tst-strfrom.c
@@ -0,0 +1,116 @@
+/* Tests for strfromf, strfromd, strfroml functions.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include "tst-strfrom.h"
+
+static const struct test tests[] = {
+  TEST ("12.345000", "%f", 50, 9,
+	12.345, 12.345, 12.345),
+  TEST ("9.999", "%.3f", 50, 5,
+	9.999, 9.999, 9.999),
+  TEST ("0.125000", "%f", 50, 8,
+	.125, .125, .125),
+  TEST ("0.000000", "%f", 50, 8,
+	.0, .0, .0),
+  TEST ("0", "%g", 50, 1,
+	.0, .0, .0),
+  TEST ("9.900000", "%f", 50, 8,
+	9.9, 9.9, 9.9),
+  TEST ("9.1", "%.5f", 4, 7,
+	9.123456, 9.123456, 9.123456),
+  TEST ("9.91235", "%g", 50, 7,
+	9.9123456, 9.91234567812345678, 9.91234567812345678),
+  TEST ("79.8765", "%G", 50, 7,
+	79.876543, 79.8765432111, 79.8765432111),
+  TEST ("79.9", "%.3g", 50, 4,
+	79.876543, 79.8765432111, 79.8765432111),
+  TEST ("1.000000e+38", "%e", 50, 12,
+	1e+38, 1e+38, 1e+38),
+  TEST ("1.000000e+38", "%e", 50, 12,
+	1e38, 1e38, 1e38),
+  TEST ("-1.000000e-37", "%e", 50, 13,
+	-1e-37, -1e-37, -1e-37),
+  TEST ("1.000000e-37", "%e", 50, 12,
+	0.00000001e-29, 0.00000001e-29, 0.00000001e-29),
+  TEST ("1.000000e-37", "%e", 50, 12,
+	1.000000e-37, 1.000000e-37, 1.000000e-37),
+  TEST ("5.900000e-16", "%e", 50, 12,
+	5.9e-16, 5.9e-16, 5.9e-16),
+  TEST ("1.234500e+20", "%e", 50, 12,
+	12.345e19, 12.345e19, 12.345e19),
+  TEST ("1.000000e+05", "%e", 50, 12,
+	1e5, 1e5, 1e5),
+  TEST ("-NAN", "%G", 50, 4,
+	-NAN_, -NAN_, -NAN_),
+  TEST ("-inf", "%g", 50, 4,
+	-INF, -INF, -INF),
+  TEST ("inf", "%g", 50, 3,
+	INF, INF, INF)
+   };
+
+/* Tests with buffer size small.  */
+static const struct test stest[] = {
+  TEST ("1234", "%g", 5, 7,
+	12345.345, 12345.345, 12345.345),
+  TEST ("0.12", "%f", 5, 8,
+	.125, .125, .125),
+  TEST ("9.99", "%.3f", 5, 5,
+	9.999, 9.999, 9.999),
+  TEST ("100", "%g", 5, 3,
+	1e2, 1e2, 1e2)
+};
+/* Hexadecimal tests.  */
+static const struct htests htest[] = {
+  {"%a", { "0x1.ffp+6", "0x3.fep+5", "0x7.fcp+4", "0xf.f8p+3" },
+   {0x1.ffp+6, 0x1.ffp+6, 0x1.ffp+6}},
+  {"%a", { "0x1.88p+4", "0x3.1p+3", "0x6.2p+2", "0xc.4p+1" },
+   {0x1.88p+4, 0x1.88p+4, 0x1.88p+4}},
+  {"%A", { "-0X1.88P+5", "-0X3.1P+4", "-0X6.2P+3", "-0XC.4P+2" },
+   {-0x1.88p+5, -0x1.88p+5, -0x1.88p+5}},
+  {"%a", { "0x1.44p+10", "0x2.88p+9", "0x5.1p+8", "0xa.2p+7"},
+   {0x1.44p+10, 0x1.44p+10, 0x1.44p+10}},
+  {"%a", { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13"},
+   {0x0.0040p+0, 0x0.0040p+0, 0x0.0040p+0}},
+  {"%a", { "0x1.4p+3", "0x2.8p+2", "0x5p+1", "0xap+0"},
+   {10.0, 10.0, 10.0}}
+};
+GEN_TEST_STRTOD_FOREACH (TEST_STRFROM)
+
+static int
+test_locale (const char *locale)
+{
+  printf ("Testing in locale: %s\n", locale);
+  if (setlocale (LC_ALL, locale) == NULL)
+    {
+      printf ("Cannot set locale %s\n", locale);
+    }
+  return STRTOD_TEST_FOREACH (test_);
+}
+
+static int
+do_test (void)
+{
+  int result = 0;
+  result += test_locale ("C");
+  result += test_locale ("en_US.ISO-8859-1");
+  result += test_locale ("en_US.UTF-8");
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdlib/tst-strfrom.h b/stdlib/tst-strfrom.h
new file mode 100644
index 0000000..f0acd94
--- /dev/null
+++ b/stdlib/tst-strfrom.h
@@ -0,0 +1,126 @@
+/* Tests for strfromf, strfromd, strfroml functions.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#include <math.h>
+#include <locale.h>
+
+#include "tst-strtod.h"
+
+#define _CONCAT(a, b) a ## b
+#define CONCAT(a, b) _CONCAT (a, b)
+
+/* Generator to create an FTYPE member variabled named FSUF
+ *    used to populate struct member variables.  */
+#define FTYPE_MEMBER(FSUF, FTYPE, FTOSTR, LSUF, CSUF)  \
+       FTYPE FSUF;
+
+#define STRUCT_FOREACH_FLOAT_FTYPE GEN_TEST_STRTOD_FOREACH (FTYPE_MEMBER)
+
+/* Add type specific choosing macros below.  */
+#define CHOOSE_f(f,...) f
+#define CHOOSE_d(f,d,...) d
+#define CHOOSE_ld(f,d,ld...) ld
+
+/* Selector for expected result field of a given type.  */
+#define _ENTRY(FSUF, FTYPE, FTOSTR, LSUF, CSUF, ...)  \
+  CONCAT (CHOOSE_ ## FSUF (__VA_ARGS__), LSUF),
+#define ENTRY(...) \
+  GEN_TEST_STRTOD_FOREACH (_ENTRY, __VA_ARGS__)
+
+/* This is hacky way around the seemingly unavoidable macro
+ * expansion of the INFINITY or HUGE_VAL like macros in the
+ * above.  It is assumed the compiler will implicitly convert
+ * the infinity correctly.  */
+#define INF INFINITY + 0.0
+#define NAN_ NAN + 0.0
+
+struct test_input
+{
+  STRUCT_FOREACH_FLOAT_FTYPE
+};
+struct test {
+  const char *s;
+  const char *fmt;
+  int size;
+  int rc;
+  struct test_input t;
+};
+
+#define TEST(s, fmt, size, rc, f, d, ld)	\
+  {						\
+    s, fmt, size, rc,  { ENTRY (f, d, ld) }	\
+  }
+/* Hexadecimal tests.  */
+struct htests
+{
+  const char *fmt;
+  const char *exp[4];
+  struct test_input t;
+};
+
+#define TEST_STRFROM(FSUF, FTYPE, FTOSTR, LSUF, CSUF)			\
+static int								\
+test_ ## FSUF (void)							\
+{									\
+  char buf[50], sbuf[5];						\
+  int status = 0;							\
+  int i, rc = 0, rc1 = 0;						\
+  for (i = 0; i < sizeof (stest) / sizeof (stest[0]); i++)		\
+    {									\
+      rc = FTOSTR (sbuf, stest[i].size, stest[i].fmt, stest[i].t.FSUF);	\
+      rc1 = (strcmp (sbuf, stest[i].s) != 0) || (rc != stest[i].rc);	\
+      if (rc1)								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
+		  sbuf, rc, stest[i].s, stest[i].rc);			\
+	  status++;							\
+	}								\
+    }									\
+  for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)		\
+    {									\
+      rc = FTOSTR (buf, tests[i].size, tests[i].fmt, tests[i].t.FSUF);	\
+      rc1 = (strcmp (buf, tests[i].s) != 0) || (rc != tests[i].rc);	\
+      if (rc1)								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
+		  buf, rc, tests[i].s, tests[i].rc);			\
+	  status++;							\
+	}								\
+    }									\
+  for (i = 0; i < sizeof (htest) / sizeof (htest[0]); i++)		\
+    {									\
+      rc = FTOSTR (buf, 50, htest[i].fmt, htest[i].t.FSUF);		\
+      if (strcmp (buf, htest[i].exp[0]) == 0 ||				\
+	  strcmp (buf, htest[i].exp[1]) == 0 ||				\
+	  strcmp (buf, htest[i].exp[2]) == 0 ||				\
+	  strcmp (buf, htest[i].exp[3]) == 0)				\
+	continue;							\
+      else								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s or %s or %s "	\
+		  "or %s\n", buf, rc, htest[i].exp[0], htest[i].exp[1],	\
+		  htest[i].exp[2], htest[i].exp[3]);			\
+	  status++;							\
+	}								\
+    }									\
+  return status;							\
+}
-- 
2.4.11

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v9 3/3] Add tests for strfrom functions
  2016-10-18 15:08     ` [PATCH v9 " Gabriel F. T. Gomes
@ 2016-10-20 16:56       ` Joseph Myers
  2016-10-24 14:57         ` [PATCH v10 " Gabriel F. T. Gomes
  0 siblings, 1 reply; 11+ messages in thread
From: Joseph Myers @ 2016-10-20 16:56 UTC (permalink / raw)
  To: Gabriel F. T. Gomes; +Cc: libc-alpha

On Tue, 18 Oct 2016, Gabriel F. T. Gomes wrote:

> +/* Hexadecimal tests.  */
> +static const struct htests htest[] = {
> +  {"%a", { "0x1,ffp+6", "0x3,fep+5", "0x7,fcp+4", "0xf,f8p+3" },
> +   {0x1.ffp+6, 0x1.ffp+6, 0x1.ffp+6}},
> +  {"%a", { "0x1,88p+4", "0x3,1p+3", "0x6,2p+2", "0xc,4p+1" },
> +   {0x1.88p+4, 0x1.88p+4, 0x1.88p+4}},
> +  {"%A", { "-0X1,88P+5", "-0X3,1P+4", "-0X6,2P+3", "-0XC,4P+2" },
> +   {-0x1.88p+5, -0x1.88p+5, -0x1.88p+5}},
> +  {"%a", { "0x1,44p+10", "0x2,88p+9", "0x5,1p+8", "0xa,2p+7"},
> +   {0x1.44p+10, 0x1.44p+10, 0x1.44p+10}},
> +  {"%a", { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13"},
> +   {0x0.0040p+0, 0x0.0040p+0, 0x0.0040p+0}},
> +  {"%a", { "0x1,4p+3", "0x2,8p+2", "0x5p+1", "0xap+0"},
> +   {10.0, 10.0, 10.0}}
> +};

These still aren't type-generic.

> +/* Hexadecimal tests.  */
> +static const struct htests htest[] = {
> +  {"%a", { "0x1.ffp+6", "0x3.fep+5", "0x7.fcp+4", "0xf.f8p+3" },
> +   {0x1.ffp+6, 0x1.ffp+6, 0x1.ffp+6}},
> +  {"%a", { "0x1.88p+4", "0x3.1p+3", "0x6.2p+2", "0xc.4p+1" },
> +   {0x1.88p+4, 0x1.88p+4, 0x1.88p+4}},
> +  {"%A", { "-0X1.88P+5", "-0X3.1P+4", "-0X6.2P+3", "-0XC.4P+2" },
> +   {-0x1.88p+5, -0x1.88p+5, -0x1.88p+5}},
> +  {"%a", { "0x1.44p+10", "0x2.88p+9", "0x5.1p+8", "0xa.2p+7"},
> +   {0x1.44p+10, 0x1.44p+10, 0x1.44p+10}},
> +  {"%a", { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13"},
> +   {0x0.0040p+0, 0x0.0040p+0, 0x0.0040p+0}},
> +  {"%a", { "0x1.4p+3", "0x2.8p+2", "0x5p+1", "0xap+0"},
> +   {10.0, 10.0, 10.0}}

Likewise.

> +#define TEST(s, fmt, size, rc, f, d, ld)	\
> +  {						\
> +    s, fmt, size, rc,  { ENTRY (f, d, ld) }	\
> +  }

You should have one argument to TEST that is the constant used for all 
types (and that then gets the appropriate suffix added to it for each 
type).  It should not be necessary to update the tables of tests at all 
when adding a new floating-point type (in general, the idea of making such 
tests type-generic is so that as little as possible needs to change to 
make them test a new type; ideally only the definitions of 
GEN_TEST_STRTOD_FOREACH and STRTOD_TEST_FOREACH).  The only obvious 
differences I see between the constants in your tests for different types 
is that some have more precision in the constants for double and long 
double, but it's fine to have the extra digits in the float constant even 
if they aren't significant to its value.

That is, the definition should look something like

{ s, fmt, size, rc, { GEN_TEST_STRTOD_FOREACH (SOMETHING, f) } }

where SOMETHING expands to concatenate its 7th argument (the 
floating-point number) with its 5th (the constant suffix) (followed by a 
comma).  Then I think you can get rid of the ENTRY and CHOOSE macros.

(tst-strtod-round is different because it involves data for every 
floating-point *format*, which then needs mapping to the supported types.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v10 3/3] Add tests for strfrom functions
  2016-10-20 16:56       ` Joseph Myers
@ 2016-10-24 14:57         ` Gabriel F. T. Gomes
  2016-10-25 16:18           ` Joseph Myers
  0 siblings, 1 reply; 11+ messages in thread
From: Gabriel F. T. Gomes @ 2016-10-24 14:57 UTC (permalink / raw)
  To: libc-alpha; +Cc: joseph

From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>

Changes since v9:
  - Make non-type-generic input type-generic.
  - Refactor tables of input.
  - Add type suffix to input.

Tested for powerpc64, powerpc64le, x86_64 and s390
---8<---
2016-10-22  Rajalakshmi Srinivasaraghavan  <raji@linux.vnet.ibm.com>

	* stdlib/Makefile (tests): Add tst-strfrom and tst-strfrom-locale.
	* stdlib/tst-strfrom.h: New file.
	* stdlib/tst-strfrom.c: New file.
	* stdlib/tst-strfrom-locale.c: New file.
---
 stdlib/Makefile             |   4 +-
 stdlib/tst-strfrom-locale.c |  91 +++++++++++++++++++++++++++++++++
 stdlib/tst-strfrom.c        |  91 +++++++++++++++++++++++++++++++++
 stdlib/tst-strfrom.h        | 120 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 305 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-strfrom-locale.c
 create mode 100644 stdlib/tst-strfrom.c
 create mode 100644 stdlib/tst-strfrom.h

diff --git a/stdlib/Makefile b/stdlib/Makefile
index 3cacb8b..3cce9d9 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -79,7 +79,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   tst-setcontext3 tst-tls-atexit-nodelete		    \
 		   tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l    \
 		   tst-quick_exit tst-thread-quick_exit tst-width	    \
-		   tst-width-stdint
+		   tst-width-stdint tst-strfrom tst-strfrom-locale
 tests-static	:= tst-secure-getenv
 ifeq ($(have-cxx-thread_local),yes)
 CFLAGS-tst-quick_exit.o = -std=c++11
@@ -158,6 +158,8 @@ $(objpfx)tst-strtod5.out: $(gen-locales)
 $(objpfx)tst-strtol-locale.out: $(gen-locales)
 $(objpfx)tst-strtod-nan-locale.out: $(gen-locales)
 $(objpfx)tst-strfmon_l.out: $(gen-locales)
+$(objpfx)tst-strfrom.out: $(gen-locales)
+$(objpfx)tst-strfrom-locale.out: $(gen-locales)
 endif
 
 # Testdir has to be named stdlib and needs to be writable
diff --git a/stdlib/tst-strfrom-locale.c b/stdlib/tst-strfrom-locale.c
new file mode 100644
index 0000000..08d374f
--- /dev/null
+++ b/stdlib/tst-strfrom-locale.c
@@ -0,0 +1,91 @@
+/* Tests for strfromf, strfromd, strfroml functions.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include "tst-strfrom.h"
+
+static const struct test tests[] = {
+  TEST ("12,345000", "%f", 50, 9, 12.345),
+  TEST ("9,999", "%.3f", 50, 5, 9.999),
+  TEST ("0,125000", "%f", 50, 8, .125),
+  TEST ("0,000000", "%f", 50, 8, .0),
+  TEST ("0", "%g", 50, 1, .0),
+  TEST ("9,900000", "%f", 50, 8, 9.9),
+  TEST ("9,1", "%.5f", 4, 7, 9.123456),
+  TEST ("9,91235", "%g", 50, 7, 9.91234567812345678),
+  TEST ("79,8765", "%G", 50, 7, 79.8765432111),
+  TEST ("79,9", "%.3g", 50, 4, 79.8765432111),
+  TEST ("1,000000e+38", "%e", 50, 12, 1e+38),
+  TEST ("1,000000e+38", "%e", 50, 12, 1e38),
+  TEST ("-1,000000e-37", "%e", 50, 13, -1e-37),
+  TEST ("1,000000e-37", "%e", 50, 12, 0.00000001e-29),
+  TEST ("1,000000e-37", "%e", 50, 12, 1.000000e-37),
+  TEST ("5,900000e-16", "%e", 50, 12, 5.9e-16),
+  TEST ("1,234500e+20", "%e", 50, 12, 12.345e19),
+  TEST ("1,000000e+05", "%e", 50, 12, 1e5),
+  TEST ("-NAN", "%G", 50, 4, -NAN_),
+  TEST ("-inf", "%g", 50, 4, -INF),
+  TEST ("inf", "%g", 50, 3, INF)
+};
+/* Tests with buffer size small.  */
+static const struct test stest[] = {
+  TEST ("1234", "%g", 5, 7, 12345.345),
+  TEST ("0,12", "%f", 5, 8, .125),
+  TEST ("9,99", "%.3f", 5, 5, 9.999),
+  TEST ("100", "%g", 5, 3, 1e2)
+};
+/* Hexadecimal tests.  */
+static const struct htests htest[] = {
+  HTEST ("%a", { "0x1,ffp+6", "0x3,fep+5", "0x7,fcp+4", "0xf,f8p+3" },
+	0x1.ffp+6),
+  HTEST ("%a", { "0x1,88p+4", "0x3,1p+3", "0x6,2p+2", "0xc,4p+1" },
+	0x1.88p+4),
+  HTEST ("%A", { "-0X1,88P+5", "-0X3,1P+4", "-0X6,2P+3", "-0XC,4P+2" },
+	-0x1.88p+5),
+  HTEST ("%a", { "0x1,44p+10", "0x2,88p+9", "0x5,1p+8", "0xa,2p+7" },
+	0x1.44p+10),
+  HTEST ("%a", { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13" },
+	0x0.0040p+0),
+  HTEST ("%a", { "0x1,4p+3", "0x2,8p+2", "0x5p+1", "0xap+0" },
+	10.0)
+};
+
+GEN_TEST_STRTOD_FOREACH (TEST_STRFROM)
+
+static int
+test_locale (const char *locale)
+{
+  printf ("Testing in locale: %s\n", locale);
+  if (setlocale (LC_ALL, locale) == NULL)
+    {
+      printf ("Cannot set locale %s\n", locale);
+    }
+  return STRTOD_TEST_FOREACH (test_);
+}
+
+static int
+do_test (void)
+{
+  int result = 0;
+  result += test_locale ("de_DE.UTF-8");
+  result += test_locale ("tr_TR.ISO-8859-9");
+  result += test_locale ("tr_TR.UTF-8");
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdlib/tst-strfrom.c b/stdlib/tst-strfrom.c
new file mode 100644
index 0000000..3c990be
--- /dev/null
+++ b/stdlib/tst-strfrom.c
@@ -0,0 +1,91 @@
+/* Tests for strfromf, strfromd, strfroml functions.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include "tst-strfrom.h"
+
+static const struct test tests[] = {
+  TEST ("12.345000", "%f", 50, 9, 12.345),
+  TEST ("9.999", "%.3f", 50, 5, 9.999),
+  TEST ("0.125000", "%f", 50, 8, .125),
+  TEST ("0.000000", "%f", 50, 8, .0),
+  TEST ("0", "%g", 50, 1, .0),
+  TEST ("9.900000", "%f", 50, 8, 9.9),
+  TEST ("9.1", "%.5f", 4, 7, 9.123456),
+  TEST ("9.91235", "%g", 50, 7, 9.91234567812345678),
+  TEST ("79.8765", "%G", 50, 7, 79.8765432111),
+  TEST ("79.9", "%.3g", 50, 4, 79.8765432111),
+  TEST ("1.000000e+38", "%e", 50, 12, 1e+38),
+  TEST ("1.000000e+38", "%e", 50, 12, 1e38),
+  TEST ("-1.000000e-37", "%e", 50, 13, -1e-37),
+  TEST ("1.000000e-37", "%e", 50, 12, 0.00000001e-29),
+  TEST ("1.000000e-37", "%e", 50, 12, 1.000000e-37),
+  TEST ("5.900000e-16", "%e", 50, 12, 5.9e-16),
+  TEST ("1.234500e+20", "%e", 50, 12, 12.345e19),
+  TEST ("1.000000e+05", "%e", 50, 12, 1e5),
+  TEST ("-NAN", "%G", 50, 4, -NAN_),
+  TEST ("-inf", "%g", 50, 4, -INF),
+  TEST ("inf", "%g", 50, 3, INF)
+};
+/* Tests with buffer size small.  */
+static const struct test stest[] = {
+  TEST ("1234", "%g", 5, 7, 12345.345),
+  TEST ("0.12", "%f", 5, 8, .125),
+  TEST ("9.99", "%.3f", 5, 5, 9.999),
+  TEST ("100", "%g", 5, 3, 1e2)
+};
+/* Hexadecimal tests.  */
+static const struct htests htest[] = {
+  HTEST ("%a", { "0x1.ffp+6", "0x3.fep+5", "0x7.fcp+4", "0xf.f8p+3" },
+	0x1.ffp+6),
+  HTEST ("%a", { "0x1.88p+4", "0x3.1p+3", "0x6.2p+2", "0xc.4p+1" },
+	0x1.88p+4),
+  HTEST ("%A", { "-0X1.88P+5", "-0X3.1P+4", "-0X6.2P+3", "-0XC.4P+2" },
+	-0x1.88p+5),
+  HTEST ("%a", { "0x1.44p+10", "0x2.88p+9", "0x5.1p+8", "0xa.2p+7" },
+	0x1.44p+10),
+  HTEST ("%a", { "0x1p-10", "0x2p-11", "0x4p-12", "0x8p-13" },
+	0x0.0040p+0),
+  HTEST ("%a", { "0x1.4p+3", "0x2.8p+2", "0x5p+1", "0xap+0" },
+	10.0)
+};
+
+GEN_TEST_STRTOD_FOREACH (TEST_STRFROM)
+
+static int
+test_locale (const char *locale)
+{
+  printf ("Testing in locale: %s\n", locale);
+  if (setlocale (LC_ALL, locale) == NULL)
+    {
+      printf ("Cannot set locale %s\n", locale);
+    }
+  return STRTOD_TEST_FOREACH (test_);
+}
+
+static int
+do_test (void)
+{
+  int result = 0;
+  result += test_locale ("C");
+  result += test_locale ("en_US.ISO-8859-1");
+  result += test_locale ("en_US.UTF-8");
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdlib/tst-strfrom.h b/stdlib/tst-strfrom.h
new file mode 100644
index 0000000..795a93f
--- /dev/null
+++ b/stdlib/tst-strfrom.h
@@ -0,0 +1,120 @@
+/* Tests for strfromf, strfromd, strfroml functions.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#include <math.h>
+#include <locale.h>
+
+#include "tst-strtod.h"
+
+#define _CONCAT(a, b) a ## b
+#define CONCAT(a, b) _CONCAT (a, b)
+
+/* Generator to create an FTYPE member variabled named FSUF
+ *    used to populate struct member variables.  */
+#define FTYPE_MEMBER(FSUF, FTYPE, FTOSTR, LSUF, CSUF)  \
+       FTYPE FSUF;
+
+#define STRUCT_FOREACH_FLOAT_FTYPE GEN_TEST_STRTOD_FOREACH (FTYPE_MEMBER)
+
+#define ENTRY(FSUF, FTYPE, FTOSTR, LSUF, CSUF, ...)  \
+   CONCAT (__VA_ARGS__, CSUF),
+/* This is hacky way around the seemingly unavoidable macro
+ * expansion of the INFINITY or HUGE_VAL like macros in the
+ * above.  It is assumed the compiler will implicitly convert
+ * the infinity correctly.  */
+#define INF INFINITY + 0.0
+#define NAN_ NAN + 0.0
+
+struct test_input
+{
+  STRUCT_FOREACH_FLOAT_FTYPE
+};
+struct test {
+  const char *s;
+  const char *fmt;
+  int size;
+  int rc;
+  struct test_input t;
+};
+#define TEST(s, fmt, size, rc, val)				\
+  {								\
+    s, fmt, size, rc, { GEN_TEST_STRTOD_FOREACH(ENTRY, val) } 	\
+  }
+/* Hexadecimal tests.  */
+struct htests
+{
+  const char *fmt;
+  const char *exp[4];
+  struct test_input t;
+};
+#define HTEST(fmt, exp1, exp2, exp3, exp4, val)				\
+  {									\
+    fmt, exp1, exp2, exp3, exp4, { GEN_TEST_STRTOD_FOREACH(ENTRY, val) }\
+  }
+
+#define TEST_STRFROM(FSUF, FTYPE, FTOSTR, LSUF, CSUF)			\
+static int								\
+test_ ## FSUF (void)							\
+{									\
+  char buf[50], sbuf[5];						\
+  int status = 0;							\
+  int i, rc = 0, rc1 = 0;						\
+  for (i = 0; i < sizeof (stest) / sizeof (stest[0]); i++)		\
+    {									\
+      rc = FTOSTR (sbuf, stest[i].size, stest[i].fmt, stest[i].t.FSUF);	\
+      rc1 = (strcmp (sbuf, stest[i].s) != 0) || (rc != stest[i].rc);	\
+      if (rc1)								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
+		  sbuf, rc, stest[i].s, stest[i].rc);			\
+	  status++;							\
+	}								\
+    }									\
+  for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)		\
+    {									\
+      rc = FTOSTR (buf, tests[i].size, tests[i].fmt, tests[i].t.FSUF);	\
+      rc1 = (strcmp (buf, tests[i].s) != 0) || (rc != tests[i].rc);	\
+      if (rc1)								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s (%d)\n",		\
+		  buf, rc, tests[i].s, tests[i].rc);			\
+	  status++;							\
+	}								\
+    }									\
+  for (i = 0; i < sizeof (htest) / sizeof (htest[0]); i++)		\
+    {									\
+      rc = FTOSTR (buf, 50, htest[i].fmt, htest[i].t.FSUF);		\
+      if (strcmp (buf, htest[i].exp[0]) == 0 ||				\
+	  strcmp (buf, htest[i].exp[1]) == 0 ||				\
+	  strcmp (buf, htest[i].exp[2]) == 0 ||				\
+	  strcmp (buf, htest[i].exp[3]) == 0)				\
+	continue;							\
+      else								\
+	{								\
+	  printf (#FTOSTR ": got %s (%d), expected %s or %s or %s "	\
+		  "or %s\n", buf, rc, htest[i].exp[0], htest[i].exp[1],	\
+		  htest[i].exp[2], htest[i].exp[3]);			\
+	  status++;							\
+	}								\
+    }									\
+  return status;							\
+}
-- 
2.4.11

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v10 3/3] Add tests for strfrom functions
  2016-10-24 14:57         ` [PATCH v10 " Gabriel F. T. Gomes
@ 2016-10-25 16:18           ` Joseph Myers
  2016-10-26  0:27             ` Gabriel F. T. Gomes
  0 siblings, 1 reply; 11+ messages in thread
From: Joseph Myers @ 2016-10-25 16:18 UTC (permalink / raw)
  To: Gabriel F. T. Gomes; +Cc: libc-alpha

On Mon, 24 Oct 2016, Gabriel F. T. Gomes wrote:

> +    s, fmt, size, rc, { GEN_TEST_STRTOD_FOREACH(ENTRY, val) } 	\

> +    fmt, exp1, exp2, exp3, exp4, { GEN_TEST_STRTOD_FOREACH(ENTRY, val) }\

Missing space before '(' in function-like macro calls.

The patch (and thus the previous two in the series as well) is OK with 
that fixed.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v10 3/3] Add tests for strfrom functions
  2016-10-25 16:18           ` Joseph Myers
@ 2016-10-26  0:27             ` Gabriel F. T. Gomes
  0 siblings, 0 replies; 11+ messages in thread
From: Gabriel F. T. Gomes @ 2016-10-26  0:27 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha

On Tue, 25 Oct 2016 16:18:26 +0000
Joseph Myers <joseph@codesourcery.com> wrote:

> On Mon, 24 Oct 2016, Gabriel F. T. Gomes wrote:
> 
> > +    s, fmt, size, rc, { GEN_TEST_STRTOD_FOREACH(ENTRY, val) } 	\  
> 
> > +    fmt, exp1, exp2, exp3, exp4, { GEN_TEST_STRTOD_FOREACH(ENTRY, val) }\  
> 
> Missing space before '(' in function-like macro calls.
> 
> The patch (and thus the previous two in the series as well) is OK with 
> that fixed.
> 

Thanks. Pushed with the fixes as cd74aa4d.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-10-26  0:27 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-14 17:31 [PATCH v8 0/3] New strfrom functions Gabriel F. T. Gomes
2016-10-14 17:31 ` [PATCH v8 3/3] Add tests for " Gabriel F. T. Gomes
2016-10-14 18:50   ` Gabriel F. T. Gomes
2016-10-14 21:40   ` Joseph Myers
2016-10-18 15:08     ` [PATCH v9 " Gabriel F. T. Gomes
2016-10-20 16:56       ` Joseph Myers
2016-10-24 14:57         ` [PATCH v10 " Gabriel F. T. Gomes
2016-10-25 16:18           ` Joseph Myers
2016-10-26  0:27             ` Gabriel F. T. Gomes
2016-10-14 17:31 ` [PATCH v8 2/3] Refactor strtod tests Gabriel F. T. Gomes
2016-10-14 17:31 ` [PATCH v8 1/3] Add strfromd, strfromf, and strfroml functions Gabriel F. T. Gomes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).