about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog49
-rw-r--r--include/stdlib.h18
-rw-r--r--include/wchar.h3
-rw-r--r--stdlib/Makefile1
-rw-r--r--stdlib/strtod_l.c48
-rw-r--r--stdlib/strtod_nan.c24
-rw-r--r--stdlib/strtod_nan_double.h30
-rw-r--r--stdlib/strtod_nan_float.h29
-rw-r--r--stdlib/strtod_nan_main.c63
-rw-r--r--stdlib/strtod_nan_narrow.h22
-rw-r--r--stdlib/strtod_nan_wide.h22
-rw-r--r--stdlib/strtof_l.c11
-rw-r--r--stdlib/strtof_nan.c24
-rw-r--r--stdlib/strtold_nan.c30
-rw-r--r--sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h33
-rw-r--r--sysdeps/ieee754/ldbl-128/strtold_l.c13
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h30
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/strtold_l.c10
-rw-r--r--sysdeps/ieee754/ldbl-64-128/strtold_l.c13
-rw-r--r--sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h30
-rw-r--r--sysdeps/ieee754/ldbl-96/strtold_l.c10
-rw-r--r--wcsmbs/Makefile1
-rw-r--r--wcsmbs/wcstod_l.c3
-rw-r--r--wcsmbs/wcstod_nan.c23
-rw-r--r--wcsmbs/wcstof_l.c3
-rw-r--r--wcsmbs/wcstof_nan.c23
-rw-r--r--wcsmbs/wcstold_l.c3
-rw-r--r--wcsmbs/wcstold_nan.c30
28 files changed, 504 insertions, 95 deletions
diff --git a/ChangeLog b/ChangeLog
index 78ba1f9c19..343a936105 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,54 @@
 2015-11-24  Joseph Myers  <joseph@codesourcery.com>
 
+	* stdlib/strtod_nan.c: New file.
+	* stdlib/strtod_nan_double.h: Likewise.
+	* stdlib/strtod_nan_float.h: Likewise.
+	* stdlib/strtod_nan_main.c: Likewise.
+	* stdlib/strtod_nan_narrow.h: Likewise.
+	* stdlib/strtod_nan_wide.h: Likewise.
+	* stdlib/strtof_nan.c: Likewise.
+	* stdlib/strtold_nan.c: Likewise.
+	* sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h: Likewise.
+	* sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h: Likewise.
+	* sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h: Likewise.
+	* wcsmbs/wcstod_nan.c: Likewise.
+	* wcsmbs/wcstof_nan.c: Likewise.
+	* wcsmbs/wcstold_nan.c: Likewise.
+	* stdlib/Makefile (routines): Add strtof_nan, strtod_nan and
+	strtold_nan.
+	* wcsmbs/Makefile (routines): Add wcstod_nan, wcstold_nan and
+	wcstof_nan.
+	* include/stdlib.h (__strtof_nan): Declare and use
+	libc_hidden_proto.
+	(__strtod_nan): Likewise.
+	(__strtold_nan): Likewise.
+	(__wcstof_nan): Likewise.
+	(__wcstod_nan): Likewise.
+	(__wcstold_nan): Likewise.
+	* include/wchar.h (____wcstoull_l_internal): Declare.
+	* stdlib/strtod_l.c: Do not include <ieee754.h>.
+	(____strtoull_l_internal): Remove declaration.
+	(STRTOF_NAN): Define macro.
+	(SET_MANTISSA): Remove macro.
+	(STRTOULL): Likewise.
+	(____STRTOF_INTERNAL): Use STRTOF_NAN to parse NaN payload.
+	* stdlib/strtof_l.c (____strtoull_l_internal): Remove declaration.
+	(STRTOF_NAN): Define macro.
+	(SET_MANTISSA): Remove macro.
+	* sysdeps/ieee754/ldbl-128/strtold_l.c (STRTOF_NAN): Define macro.
+	(SET_MANTISSA): Remove macro.
+	* sysdeps/ieee754/ldbl-128ibm/strtold_l.c (STRTOF_NAN): Define
+	macro.
+	(SET_MANTISSA): Remove macro.
+	* sysdeps/ieee754/ldbl-64-128/strtold_l.c (STRTOF_NAN): Define
+	macro.
+	(SET_MANTISSA): Remove macro.
+	* sysdeps/ieee754/ldbl-96/strtold_l.c (STRTOF_NAN): Define macro.
+	(SET_MANTISSA): Remove macro.
+	* wcsmbs/wcstod_l.c (____wcstoull_l_internal): Remove declaration.
+	* wcsmbs/wcstof_l.c (____wcstoull_l_internal): Likewise.
+	* wcsmbs/wcstold_l.c (____wcstoull_l_internal): Likewise.
+
 	[BZ #19266]
 	* stdlib/strtod_l.c (____STRTOF_INTERNAL): Check directly for
 	upper case and lower case letters inside NAN(), not using TOLOWER.
diff --git a/include/stdlib.h b/include/stdlib.h
index dcb83a5027..352339e859 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -203,6 +203,24 @@ libc_hidden_proto (strtoll)
 libc_hidden_proto (strtoul)
 libc_hidden_proto (strtoull)
 
+extern float __strtof_nan (const char *, char **, char) internal_function;
+extern double __strtod_nan (const char *, char **, char) internal_function;
+extern long double __strtold_nan (const char *, char **, char)
+     internal_function;
+extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t)
+     internal_function;
+extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t)
+     internal_function;
+extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t)
+     internal_function;
+
+libc_hidden_proto (__strtof_nan)
+libc_hidden_proto (__strtod_nan)
+libc_hidden_proto (__strtold_nan)
+libc_hidden_proto (__wcstof_nan)
+libc_hidden_proto (__wcstod_nan)
+libc_hidden_proto (__wcstold_nan)
+
 extern char *__ecvt (double __value, int __ndigit, int *__restrict __decpt,
 		     int *__restrict __sign);
 extern char *__fcvt (double __value, int __ndigit, int *__restrict __decpt,
diff --git a/include/wchar.h b/include/wchar.h
index 67d0248f00..0f33d094ed 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -52,6 +52,9 @@ extern unsigned long long int __wcstoull_internal (const wchar_t *
 						   __restrict __endptr,
 						   int __base,
 						   int __group) __THROW;
+extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
+						       wchar_t **, int, int,
+						       __locale_t);
 libc_hidden_proto (__wcstof_internal)
 libc_hidden_proto (__wcstod_internal)
 libc_hidden_proto (__wcstold_internal)
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 10d9406813..d7ae165fc7 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -50,6 +50,7 @@ routines	:=							      \
 	strtol_l strtoul_l strtoll_l strtoull_l				      \
 	strtof strtod strtold						      \
 	strtof_l strtod_l strtold_l					      \
+	strtof_nan strtod_nan strtold_nan				      \
 	system canonicalize						      \
 	a64l l64a							      \
 	rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg		      \
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
index 7307d98b24..21692914fd 100644
--- a/stdlib/strtod_l.c
+++ b/stdlib/strtod_l.c
@@ -20,8 +20,6 @@
 #include <xlocale.h>
 
 extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
-extern unsigned long long int ____strtoull_l_internal (const char *, char **,
-						       int, int, __locale_t);
 
 /* Configuration part.  These macros are defined by `strtold.c',
    `strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the
@@ -33,27 +31,20 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
 # ifdef USE_WIDE_CHAR
 #  define STRTOF	wcstod_l
 #  define __STRTOF	__wcstod_l
+#  define STRTOF_NAN	__wcstod_nan
 # else
 #  define STRTOF	strtod_l
 #  define __STRTOF	__strtod_l
+#  define STRTOF_NAN	__strtod_nan
 # endif
 # define MPN2FLOAT	__mpn_construct_double
 # define FLOAT_HUGE_VAL	HUGE_VAL
-# define SET_MANTISSA(flt, mant) \
-  do { union ieee754_double u;						      \
-       u.d = (flt);							      \
-       u.ieee_nan.mantissa0 = (mant) >> 32;				      \
-       u.ieee_nan.mantissa1 = (mant);					      \
-       if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0)			      \
-	 (flt) = u.d;							      \
-  } while (0)
 #endif
 /* End of configuration part.  */
 
 #include <ctype.h>
 #include <errno.h>
 #include <float.h>
-#include <ieee754.h>
 #include "../locale/localeinfo.h"
 #include <locale.h>
 #include <math.h>
@@ -105,7 +96,6 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
 # define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr)
 # define STRNCASECMP(S1, S2, N) \
   __wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
-# define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc)
 #else
 # define STRING_TYPE char
 # define CHAR_TYPE char
@@ -117,7 +107,6 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
 # define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr)
 # define STRNCASECMP(S1, S2, N) \
   __strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
-# define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc)
 #endif
 
 
@@ -649,33 +638,14 @@ ____STRTOF_INTERNAL (const STRING_TYPE *nptr, STRING_TYPE **endptr, int group,
 	  if (*cp == L_('('))
 	    {
 	      const STRING_TYPE *startp = cp;
-	      do
-		++cp;
-	      while ((*cp >= L_('0') && *cp <= L_('9'))
-		     || (*cp >= L_('A') && *cp <= L_('Z'))
-		     || (*cp >= L_('a') && *cp <= L_('z'))
-		     || *cp == L_('_'));
-
-	      if (*cp != L_(')'))
-		/* The closing brace is missing.  Only match the NAN
-		   part.  */
-		cp = startp;
+	      STRING_TYPE *endp;
+	      retval = STRTOF_NAN (cp + 1, &endp, L_(')'));
+	      if (*endp == L_(')'))
+		/* Consume the closing parenthesis.  */
+		cp = endp + 1;
 	      else
-		{
-		  /* This is a system-dependent way to specify the
-		     bitmask used for the NaN.  We expect it to be
-		     a number which is put in the mantissa of the
-		     number.  */
-		  STRING_TYPE *endp;
-		  unsigned long long int mant;
-
-		  mant = STRTOULL (startp + 1, &endp, 0);
-		  if (endp == cp)
-		    SET_MANTISSA (retval, mant);
-
-		  /* Consume the closing brace.  */
-		  ++cp;
-		}
+		/* Only match the NAN part.  */
+		cp = startp;
 	    }
 
 	  if (endptr != NULL)
diff --git a/stdlib/strtod_nan.c b/stdlib/strtod_nan.c
new file mode 100644
index 0000000000..2a0a89fc73
--- /dev/null
+++ b/stdlib/strtod_nan.c
@@ -0,0 +1,24 @@
+/* Convert string for NaN payload to corresponding NaN.  Narrow
+   strings, double.
+   Copyright (C) 2015 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 <strtod_nan_narrow.h>
+#include <strtod_nan_double.h>
+
+#define STRTOD_NAN __strtod_nan
+#include <strtod_nan_main.c>
diff --git a/stdlib/strtod_nan_double.h b/stdlib/strtod_nan_double.h
new file mode 100644
index 0000000000..f5bdb03e90
--- /dev/null
+++ b/stdlib/strtod_nan_double.h
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN.  For double.
+   Copyright (C) 1997-2015 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 SET_MANTISSA(flt, mant)				\
+  do							\
+    {							\
+      union ieee754_double u;				\
+      u.d = (flt);					\
+      u.ieee_nan.mantissa0 = (mant) >> 32;		\
+      u.ieee_nan.mantissa1 = (mant);			\
+      if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0)	\
+	(flt) = u.d;					\
+    }							\
+  while (0)
diff --git a/stdlib/strtod_nan_float.h b/stdlib/strtod_nan_float.h
new file mode 100644
index 0000000000..4c52de8bed
--- /dev/null
+++ b/stdlib/strtod_nan_float.h
@@ -0,0 +1,29 @@
+/* Convert string for NaN payload to corresponding NaN.  For float.
+   Copyright (C) 1997-2015 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 SET_MANTISSA(flt, mant)			\
+  do						\
+    {						\
+      union ieee754_float u;			\
+      u.f = (flt);				\
+      u.ieee_nan.mantissa = (mant);		\
+      if (u.ieee.mantissa != 0)			\
+	(flt) = u.f;				\
+    }						\
+  while (0)
diff --git a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c
new file mode 100644
index 0000000000..bc37a63a27
--- /dev/null
+++ b/stdlib/strtod_nan_main.c
@@ -0,0 +1,63 @@
+/* Convert string for NaN payload to corresponding NaN.
+   Copyright (C) 1997-2015 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 <ieee754.h>
+#include <locale.h>
+#include <math.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+
+/* If STR starts with an optional n-char-sequence as defined by ISO C
+   (a sequence of ASCII letters, digits and underscores), followed by
+   ENDC, return a NaN whose payload is set based on STR.  Otherwise,
+   return a default NAN.  If ENDPTR is not NULL, set *ENDPTR to point
+   to the character after the initial n-char-sequence.  */
+
+internal_function
+FLOAT
+STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc)
+{
+  const STRING_TYPE *cp = str;
+
+  while ((*cp >= L_('0') && *cp <= L_('9'))
+	 || (*cp >= L_('A') && *cp <= L_('Z'))
+	 || (*cp >= L_('a') && *cp <= L_('z'))
+	 || *cp == L_('_'))
+    ++cp;
+
+  FLOAT retval = NAN;
+  if (*cp != endc)
+    goto out;
+
+  /* This is a system-dependent way to specify the bitmask used for
+     the NaN.  We expect it to be a number which is put in the
+     mantissa of the number.  */
+  STRING_TYPE *endp;
+  unsigned long long int mant;
+
+  mant = STRTOULL (str, &endp, 0);
+  if (endp == cp)
+    SET_MANTISSA (retval, mant);
+
+ out:
+  if (endptr != NULL)
+    *endptr = (STRING_TYPE *) cp;
+  return retval;
+}
+libc_hidden_def (STRTOD_NAN)
diff --git a/stdlib/strtod_nan_narrow.h b/stdlib/strtod_nan_narrow.h
new file mode 100644
index 0000000000..bd7704529b
--- /dev/null
+++ b/stdlib/strtod_nan_narrow.h
@@ -0,0 +1,22 @@
+/* Convert string for NaN payload to corresponding NaN.  Narrow strings.
+   Copyright (C) 1997-2015 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 STRING_TYPE char
+#define L_(Ch) Ch
+#define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0,	\
+						   _nl_C_locobj_ptr)
diff --git a/stdlib/strtod_nan_wide.h b/stdlib/strtod_nan_wide.h
new file mode 100644
index 0000000000..783fbf4796
--- /dev/null
+++ b/stdlib/strtod_nan_wide.h
@@ -0,0 +1,22 @@
+/* Convert string for NaN payload to corresponding NaN.  Wide strings.
+   Copyright (C) 1997-2015 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 STRING_TYPE wchar_t
+#define L_(Ch) L##Ch
+#define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0,	\
+						   _nl_C_locobj_ptr)
diff --git a/stdlib/strtof_l.c b/stdlib/strtof_l.c
index 2a8646a8f6..491256f3b9 100644
--- a/stdlib/strtof_l.c
+++ b/stdlib/strtof_l.c
@@ -20,26 +20,19 @@
 #include <xlocale.h>
 
 extern float ____strtof_l_internal (const char *, char **, int, __locale_t);
-extern unsigned long long int ____strtoull_l_internal (const char *, char **,
-						       int, int, __locale_t);
 
 #define	FLOAT		float
 #define	FLT		FLT
 #ifdef USE_WIDE_CHAR
 # define STRTOF		wcstof_l
 # define __STRTOF	__wcstof_l
+# define STRTOF_NAN	__wcstof_nan
 #else
 # define STRTOF		strtof_l
 # define __STRTOF	__strtof_l
+# define STRTOF_NAN	__strtof_nan
 #endif
 #define	MPN2FLOAT	__mpn_construct_float
 #define	FLOAT_HUGE_VAL	HUGE_VALF
-#define SET_MANTISSA(flt, mant) \
-  do { union ieee754_float u;						      \
-       u.f = (flt);							      \
-       u.ieee_nan.mantissa = (mant);					      \
-       if (u.ieee.mantissa != 0)					      \
-	 (flt) = u.f;							      \
-  } while (0)
 
 #include "strtod_l.c"
diff --git a/stdlib/strtof_nan.c b/stdlib/strtof_nan.c
new file mode 100644
index 0000000000..b971310f7c
--- /dev/null
+++ b/stdlib/strtof_nan.c
@@ -0,0 +1,24 @@
+/* Convert string for NaN payload to corresponding NaN.  Narrow
+   strings, float.
+   Copyright (C) 2015 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 <strtod_nan_narrow.h>
+#include <strtod_nan_float.h>
+
+#define STRTOD_NAN __strtof_nan
+#include <strtod_nan_main.c>
diff --git a/stdlib/strtold_nan.c b/stdlib/strtold_nan.c
new file mode 100644
index 0000000000..dd43032609
--- /dev/null
+++ b/stdlib/strtold_nan.c
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN.  Narrow
+   strings, long double.
+   Copyright (C) 2015 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 <math.h>
+
+/* This function is unused if long double and double have the same
+   representation.  */
+#ifndef __NO_LONG_DOUBLE_MATH
+# include <strtod_nan_narrow.h>
+# include <strtod_nan_ldouble.h>
+
+# define STRTOD_NAN __strtold_nan
+# include <strtod_nan_main.c>
+#endif
diff --git a/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
new file mode 100644
index 0000000000..e0da4e217e
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
@@ -0,0 +1,33 @@
+/* Convert string for NaN payload to corresponding NaN.  For ldbl-128.
+   Copyright (C) 1997-2015 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 SET_MANTISSA(flt, mant)				\
+  do							\
+    {							\
+      union ieee854_long_double u;			\
+      u.d = (flt);					\
+      u.ieee_nan.mantissa0 = 0;				\
+      u.ieee_nan.mantissa1 = 0;				\
+      u.ieee_nan.mantissa2 = (mant) >> 32;		\
+      u.ieee_nan.mantissa3 = (mant);			\
+      if ((u.ieee.mantissa0 | u.ieee.mantissa1		\
+	   | u.ieee.mantissa2 | u.ieee.mantissa3) != 0)	\
+	(flt) = u.d;					\
+    }							\
+  while (0)
diff --git a/sysdeps/ieee754/ldbl-128/strtold_l.c b/sysdeps/ieee754/ldbl-128/strtold_l.c
index d1ae57e304..0b2ed27aa8 100644
--- a/sysdeps/ieee754/ldbl-128/strtold_l.c
+++ b/sysdeps/ieee754/ldbl-128/strtold_l.c
@@ -25,22 +25,13 @@
 #ifdef USE_WIDE_CHAR
 # define STRTOF		wcstold_l
 # define __STRTOF	__wcstold_l
+# define STRTOF_NAN	__wcstold_nan
 #else
 # define STRTOF		strtold_l
 # define __STRTOF	__strtold_l
+# define STRTOF_NAN	__strtold_nan
 #endif
 #define MPN2FLOAT	__mpn_construct_long_double
 #define FLOAT_HUGE_VAL	HUGE_VALL
-#define SET_MANTISSA(flt, mant) \
-  do { union ieee854_long_double u;					      \
-       u.d = (flt);							      \
-       u.ieee_nan.mantissa0 = 0;					      \
-       u.ieee_nan.mantissa1 = 0;					      \
-       u.ieee_nan.mantissa2 = (mant) >> 32;				      \
-       u.ieee_nan.mantissa3 = (mant);					      \
-       if ((u.ieee.mantissa0 | u.ieee.mantissa1				      \
-	    | u.ieee.mantissa2 | u.ieee.mantissa3) != 0)		      \
-	 (flt) = u.d;							      \
-  } while (0)
 
 #include <strtod_l.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
new file mode 100644
index 0000000000..876a4bba03
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN.  For ldbl-128ibm.
+   Copyright (C) 1997-2015 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 SET_MANTISSA(flt, mant)					\
+  do								\
+    {								\
+      union ibm_extended_long_double u;				\
+      u.ld = (flt);						\
+      u.d[0].ieee_nan.mantissa0 = (mant) >> 32;			\
+      u.d[0].ieee_nan.mantissa1 = (mant);			\
+      if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0)	\
+	(flt) = u.ld;						\
+    }								\
+  while (0)
diff --git a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
index 3e2f69e353..6cd963b2cc 100644
--- a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
+++ b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
@@ -30,25 +30,19 @@ extern long double ____new_wcstold_l (const wchar_t *, wchar_t **, __locale_t);
 # define STRTOF		__new_wcstold_l
 # define __STRTOF	____new_wcstold_l
 # define ____STRTOF_INTERNAL ____wcstold_l_internal
+# define STRTOF_NAN	__wcstold_nan
 #else
 extern long double ____new_strtold_l (const char *, char **, __locale_t);
 # define STRTOF		__new_strtold_l
 # define __STRTOF	____new_strtold_l
 # define ____STRTOF_INTERNAL ____strtold_l_internal
+# define STRTOF_NAN	__strtold_nan
 #endif
 extern __typeof (__STRTOF) STRTOF;
 libc_hidden_proto (__STRTOF)
 libc_hidden_proto (STRTOF)
 #define MPN2FLOAT	__mpn_construct_long_double
 #define FLOAT_HUGE_VAL	HUGE_VALL
-# define SET_MANTISSA(flt, mant) \
-  do { union ibm_extended_long_double u;				      \
-       u.ld = (flt);							      \
-       u.d[0].ieee_nan.mantissa0 = (mant) >> 32;			      \
-       u.d[0].ieee_nan.mantissa1 = (mant);				      \
-       if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0)	      \
-	 (flt) = u.ld;							      \
-  } while (0)
 
 #include <strtod_l.c>
 
diff --git a/sysdeps/ieee754/ldbl-64-128/strtold_l.c b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
index 3944a43643..6cd963b2cc 100644
--- a/sysdeps/ieee754/ldbl-64-128/strtold_l.c
+++ b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
@@ -30,28 +30,19 @@ extern long double ____new_wcstold_l (const wchar_t *, wchar_t **, __locale_t);
 # define STRTOF		__new_wcstold_l
 # define __STRTOF	____new_wcstold_l
 # define ____STRTOF_INTERNAL ____wcstold_l_internal
+# define STRTOF_NAN	__wcstold_nan
 #else
 extern long double ____new_strtold_l (const char *, char **, __locale_t);
 # define STRTOF		__new_strtold_l
 # define __STRTOF	____new_strtold_l
 # define ____STRTOF_INTERNAL ____strtold_l_internal
+# define STRTOF_NAN	__strtold_nan
 #endif
 extern __typeof (__STRTOF) STRTOF;
 libc_hidden_proto (__STRTOF)
 libc_hidden_proto (STRTOF)
 #define MPN2FLOAT	__mpn_construct_long_double
 #define FLOAT_HUGE_VAL	HUGE_VALL
-#define SET_MANTISSA(flt, mant) \
-  do { union ieee854_long_double u;					      \
-       u.d = (flt);							      \
-       u.ieee_nan.mantissa0 = 0;					      \
-       u.ieee_nan.mantissa1 = 0;					      \
-       u.ieee_nan.mantissa2 = (mant) >> 32;				      \
-       u.ieee_nan.mantissa3 = (mant);					      \
-       if ((u.ieee.mantissa0 | u.ieee.mantissa1				      \
-	    | u.ieee.mantissa2 | u.ieee.mantissa3) != 0)		      \
-	 (flt) = u.d;							      \
-  } while (0)
 
 #include <strtod_l.c>
 
diff --git a/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
new file mode 100644
index 0000000000..6f033594ac
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN.  For ldbl-96.
+   Copyright (C) 1997-2015 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 SET_MANTISSA(flt, mant)				\
+  do							\
+    {							\
+      union ieee854_long_double u;			\
+      u.d = (flt);					\
+      u.ieee_nan.mantissa0 = (mant) >> 32;		\
+      u.ieee_nan.mantissa1 = (mant);			\
+      if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0)	\
+	(flt) = u.d;					\
+    }							\
+  while (0)
diff --git a/sysdeps/ieee754/ldbl-96/strtold_l.c b/sysdeps/ieee754/ldbl-96/strtold_l.c
index c082e7472e..db92242d59 100644
--- a/sysdeps/ieee754/ldbl-96/strtold_l.c
+++ b/sysdeps/ieee754/ldbl-96/strtold_l.c
@@ -25,19 +25,13 @@
 #ifdef USE_WIDE_CHAR
 # define STRTOF		wcstold_l
 # define __STRTOF	__wcstold_l
+# define STRTOF_NAN	__wcstold_nan
 #else
 # define STRTOF		strtold_l
 # define __STRTOF	__strtold_l
+# define STRTOF_NAN	__strtold_nan
 #endif
 #define MPN2FLOAT	__mpn_construct_long_double
 #define FLOAT_HUGE_VAL	HUGE_VALL
-#define SET_MANTISSA(flt, mant) \
-  do { union ieee854_long_double u;					      \
-       u.d = (flt);							      \
-       u.ieee_nan.mantissa0 = (mant) >> 32;				      \
-       u.ieee_nan.mantissa1 = (mant);					      \
-       if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0)			      \
-	 (flt) = u.d;							      \
-  } while (0)
 
 #include <stdlib/strtod_l.c>
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index 773cfdb932..e5de439fcd 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -33,6 +33,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 	    wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \
 	    wcstol_l wcstoul_l wcstoll_l wcstoull_l \
 	    wcstod_l wcstold_l wcstof_l \
+	    wcstod_nan wcstold_nan wcstof_nan \
 	    wcscoll wcsxfrm \
 	    wcwidth wcswidth \
 	    wcscoll_l wcsxfrm_l \
diff --git a/wcsmbs/wcstod_l.c b/wcsmbs/wcstod_l.c
index 9c026d8225..0fe820c77b 100644
--- a/wcsmbs/wcstod_l.c
+++ b/wcsmbs/wcstod_l.c
@@ -23,9 +23,6 @@
 
 extern double ____wcstod_l_internal (const wchar_t *, wchar_t **, int,
 				     __locale_t);
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
-						       wchar_t **, int, int,
-						       __locale_t);
 
 #define	USE_WIDE_CHAR	1
 
diff --git a/wcsmbs/wcstod_nan.c b/wcsmbs/wcstod_nan.c
new file mode 100644
index 0000000000..b3dd6af835
--- /dev/null
+++ b/wcsmbs/wcstod_nan.c
@@ -0,0 +1,23 @@
+/* Convert string for NaN payload to corresponding NaN.  Wide strings, double.
+   Copyright (C) 2015 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 "../stdlib/strtod_nan_wide.h"
+#include "../stdlib/strtod_nan_double.h"
+
+#define STRTOD_NAN __wcstod_nan
+#include "../stdlib/strtod_nan_main.c"
diff --git a/wcsmbs/wcstof_l.c b/wcsmbs/wcstof_l.c
index bcf9834738..392ea49e98 100644
--- a/wcsmbs/wcstof_l.c
+++ b/wcsmbs/wcstof_l.c
@@ -25,8 +25,5 @@
 
 extern float ____wcstof_l_internal (const wchar_t *, wchar_t **, int,
 				    __locale_t);
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
-						       wchar_t **, int, int,
-						       __locale_t);
 
 #include <stdlib/strtof_l.c>
diff --git a/wcsmbs/wcstof_nan.c b/wcsmbs/wcstof_nan.c
new file mode 100644
index 0000000000..c5f667a8e5
--- /dev/null
+++ b/wcsmbs/wcstof_nan.c
@@ -0,0 +1,23 @@
+/* Convert string for NaN payload to corresponding NaN.  Wide strings, float.
+   Copyright (C) 2015 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 "../stdlib/strtod_nan_wide.h"
+#include "../stdlib/strtod_nan_float.h"
+
+#define STRTOD_NAN __wcstof_nan
+#include "../stdlib/strtod_nan_main.c"
diff --git a/wcsmbs/wcstold_l.c b/wcsmbs/wcstold_l.c
index 8df93afb56..f5d055470c 100644
--- a/wcsmbs/wcstold_l.c
+++ b/wcsmbs/wcstold_l.c
@@ -24,8 +24,5 @@
 
 extern long double ____wcstold_l_internal (const wchar_t *, wchar_t **, int,
 					   __locale_t);
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
-						       wchar_t **, int, int,
-						       __locale_t);
 
 #include <strtold_l.c>
diff --git a/wcsmbs/wcstold_nan.c b/wcsmbs/wcstold_nan.c
new file mode 100644
index 0000000000..ef905d3c2c
--- /dev/null
+++ b/wcsmbs/wcstold_nan.c
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN.  Wide strings,
+   long double.
+   Copyright (C) 2015 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 <math.h>
+
+/* This function is unused if long double and double have the same
+   representation.  */
+#ifndef __NO_LONG_DOUBLE_MATH
+# include "../stdlib/strtod_nan_wide.h"
+# include <strtod_nan_ldouble.h>
+
+# define STRTOD_NAN __wcstold_nan
+# include "../stdlib/strtod_nan_main.c"
+#endif