summary refs log tree commit diff
path: root/stdio-common
diff options
context:
space:
mode:
Diffstat (limited to 'stdio-common')
-rw-r--r--stdio-common/Makefile11
-rw-r--r--stdio-common/Versions5
-rw-r--r--stdio-common/_itoa.c5
-rw-r--r--stdio-common/asprintf.c12
-rw-r--r--stdio-common/bits/printf-ldbl.h24
-rw-r--r--stdio-common/bug16.c43
-rw-r--r--stdio-common/bug17.c31
-rw-r--r--stdio-common/ctermid.c36
-rw-r--r--stdio-common/cuserid.c35
-rw-r--r--stdio-common/dprintf.c9
-rw-r--r--stdio-common/errlist.c37
-rw-r--r--stdio-common/flockfile.c30
-rw-r--r--stdio-common/fprintf.c10
-rw-r--r--stdio-common/fscanf.c6
-rw-r--r--stdio-common/ftrylockfile.c31
-rw-r--r--stdio-common/funlockfile.c30
-rw-r--r--stdio-common/fxprintf.c56
-rw-r--r--stdio-common/perror.c7
-rw-r--r--stdio-common/printf-parsemb.c5
-rw-r--r--stdio-common/printf-prs.c7
-rw-r--r--stdio-common/printf.c8
-rw-r--r--stdio-common/printf.h6
-rw-r--r--stdio-common/printf_fp.c139
-rw-r--r--stdio-common/printf_fphex.c493
-rw-r--r--stdio-common/printf_size.c6
-rw-r--r--stdio-common/psignal.c25
-rw-r--r--stdio-common/remove.c33
-rw-r--r--stdio-common/rename.c41
-rw-r--r--stdio-common/renameat.c50
-rw-r--r--stdio-common/scanf.c5
-rw-r--r--stdio-common/siglist.c38
-rw-r--r--stdio-common/snprintf.c8
-rw-r--r--stdio-common/sprintf.c12
-rw-r--r--stdio-common/sscanf.c12
-rw-r--r--stdio-common/tempname.c59
-rw-r--r--stdio-common/test-vfprintf.c8
-rw-r--r--stdio-common/tfformat.c18
-rw-r--r--stdio-common/tmpfile.c66
-rw-r--r--stdio-common/tmpfile64.c3
-rw-r--r--stdio-common/tst-fgets.c20
-rw-r--r--stdio-common/tst-fmemopen2.c68
-rw-r--r--stdio-common/tst-fwrite.c70
-rw-r--r--stdio-common/tst-printf.c11
-rw-r--r--stdio-common/tst-printf.sh14
-rw-r--r--stdio-common/tst-put-error.c33
-rw-r--r--stdio-common/tst-sprintf.c21
-rw-r--r--stdio-common/tst-sprintf2.c82
-rw-r--r--stdio-common/tstdiomisc.c12
-rw-r--r--stdio-common/tstscanf.c4
-rw-r--r--stdio-common/vfprintf.c113
-rw-r--r--stdio-common/vfscanf.c183
-rw-r--r--stdio-common/vprintf.c9
52 files changed, 1835 insertions, 265 deletions
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index 3a66f1d021..7bd368bdca 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1991-2006, 2007 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
@@ -21,7 +21,7 @@
 #
 subdir	:= stdio-common
 
-headers	:= printf.h stdio_ext.h
+headers	:= stdio_ext.h printf.h bits/printf-ldbl.h
 
 routines	:=							      \
 	ctermid cuserid							      \
@@ -33,14 +33,14 @@ routines	:=							      \
 	perror psignal							      \
 	tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname		      \
 	getline getw putw						      \
-	remove rename							      \
+	remove rename renameat						      \
 	flockfile ftrylockfile funlockfile
 
 install-others = $(inst_includedir)/bits/stdio_lim.h
 
 include ../Makeconfig
 
-aux	:= errlist siglist printf-parsemb printf-parsewc
+aux	:= errlist siglist printf-parsemb printf-parsewc fxprintf
 distribute := _itoa.h _itowa.h _i18n_number.h \
 	      printf-parse.h stdio_lim.h.in tst-unbputc.sh tst-printf.sh
 
@@ -53,7 +53,8 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
 	 scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \
 	 tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
 	 tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \
-	 tst-popen tst-unlockedio
+	 tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
+	 tst-fwrite bug16 bug17 tst-sprintf2
 
 test-srcs = tst-unbputc tst-printf
 
diff --git a/stdio-common/Versions b/stdio-common/Versions
index 1dbce1a124..2f64429346 100644
--- a/stdio-common/Versions
+++ b/stdio-common/Versions
@@ -37,7 +37,7 @@ libc {
     tempnam; tmpfile; tmpnam; tmpnam_r;
 
     # v*
-    vfprintf; vfscanf; vprintf; 
+    vfprintf; vfscanf; vprintf;
   }
   GLIBC_2.1 {
     # p*
@@ -46,6 +46,9 @@ libc {
     # t*
     tmpfile; tmpfile64;
   }
+  GLIBC_2.4 {
+    renameat;
+  }
   GLIBC_PRIVATE {
     # global variables
     _itoa_lower_digits;
diff --git a/stdio-common/_itoa.c b/stdio-common/_itoa.c
index f61b23fceb..285fde2ab9 100644
--- a/stdio-common/_itoa.c
+++ b/stdio-common/_itoa.c
@@ -1,5 +1,5 @@
 /* Internal function for converting integers to ASCII.
-   Copyright (C) 1994, 1995, 1996, 1999, 2000, 2002, 2003, 2004
+   Copyright (C) 1994, 1995, 1996, 1999, 2000, 2002, 2003, 2004, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Torbjorn Granlund <tege@matematik.su.se>
@@ -269,6 +269,7 @@ _itoa (value, buflim, base, upper_case)
 
     default:
       {
+	char *bufend = buflim;
 #if BITS_PER_MP_LIMB == 64
 	mp_limb_t base_multiplier = brec->base_multiplier;
 	if (brec->flag)
@@ -454,6 +455,8 @@ _itoa (value, buflim, base, upper_case)
 	  }
 	while (n != 0);
 #endif
+	if (buflim == bufend)
+	  *--buflim = '0';
       }
       break;
     }
diff --git a/stdio-common/asprintf.c b/stdio-common/asprintf.c
index 2c466d28d5..66e766ebfb 100644
--- a/stdio-common/asprintf.c
+++ b/stdio-common/asprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1997, 1998, 2002, 2004
+/* Copyright (C) 1991, 1995, 1997, 1998, 2002, 2004, 2006
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -20,7 +20,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 
-#include <libio/libioP.h>
+#include <libioP.h>
 #define vasprintf(s, f, a) _IO_vasprintf (s, f, a)
 #undef __asprintf
 
@@ -28,7 +28,7 @@
    allocated with malloc and stored in *STRING_PTR.  */
 /* VARARGS2 */
 int
-__asprintf (char **string_ptr, const char *format, ...)
+___asprintf (char **string_ptr, const char *format, ...)
 {
   va_list arg;
   int done;
@@ -39,5 +39,7 @@ __asprintf (char **string_ptr, const char *format, ...)
 
   return done;
 }
-INTDEF(__asprintf)
-weak_alias (__asprintf, asprintf)
+INTDEF2(___asprintf, __asprintf)
+
+ldbl_strong_alias (___asprintf, __asprintf)
+ldbl_weak_alias (___asprintf, asprintf)
diff --git a/stdio-common/bits/printf-ldbl.h b/stdio-common/bits/printf-ldbl.h
new file mode 100644
index 0000000000..cbdc3f1cbc
--- /dev/null
+++ b/stdio-common/bits/printf-ldbl.h
@@ -0,0 +1,24 @@
+/* -mlong-double-64 compatibility mode for <printf.h> functions.
+   Copyright (C) 2006 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _PRINTF_H
+# error "Never include <bits/printf-ldbl.h> directly; use <printf.h> instead."
+#endif
+
+__LDBL_REDIR_DECL (printf_size)
diff --git a/stdio-common/bug16.c b/stdio-common/bug16.c
new file mode 100644
index 0000000000..84269f3b6d
--- /dev/null
+++ b/stdio-common/bug16.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <string.h>
+
+struct
+{
+  long double val;
+  const char str[4][7];
+} tests[] =
+{
+  { 0x0.FFFFp+0L, { "0X1P+0", "0X2P-1", "0X4P-2", "0X8P-3" } },
+  { 0x0.FFFFp+1L, { "0X1P+1", "0X2P+0", "0X4P-1", "0X8P-2" } },
+  { 0x0.FFFFp+2L, { "0X1P+2", "0X2P+1", "0X4P+0", "0X8P-1" } },
+  { 0x0.FFFFp+3L, { "0X1P+3", "0X2P+2", "0X4P+1", "0X8P+0" } }
+};
+
+static int
+do_test (void)
+{
+  char buf[100];
+  int ret = 0;
+
+  for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
+    {  
+      snprintf (buf, sizeof (buf), "%.0LA", tests[i].val);
+
+      size_t j;
+      for (j = 0; j < 4; ++j)
+	if (strcmp (buf, tests[i].str[j]) == 0)
+	  break;
+
+      if (j == 4)
+	{
+	  printf ("%zd: got \"%s\", expected \"%s\" or equivalent\n",
+		  i, buf, tests[i].str[0]);
+	  ret = 1;
+	}
+    }
+
+  return ret;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdio-common/bug17.c b/stdio-common/bug17.c
new file mode 100644
index 0000000000..2ef398674b
--- /dev/null
+++ b/stdio-common/bug17.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <string.h>
+
+static int
+do_test (void)
+{
+  static const char expect[] = "0, 0, 0";
+  char buf[100];
+  int status = 0;
+
+  static const char fmt1[] = "%0d, %0ld, %0lld";
+  snprintf (buf, sizeof (buf), fmt1, 0, 0L, 0LL);
+  if (strcmp (buf, expect) != 0)
+    {
+      printf ("\"%s\": got \"%s\", expected \"%s\"\n", fmt1, buf, expect);
+      status = 1;
+    }
+
+  static const char fmt2[] = "%0u, %0lu, %0llu";
+  snprintf (buf, sizeof (buf), fmt2, 0u, 0uL, 0uLL);
+  if (strcmp (buf, expect) != 0)
+    {
+      printf ("\"%s\": got \"%s\", expected \"%s\"\n", fmt2, buf, expect);
+      status = 1;
+    }
+
+  return status;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdio-common/ctermid.c b/stdio-common/ctermid.c
new file mode 100644
index 0000000000..e4d94eada2
--- /dev/null
+++ b/stdio-common/ctermid.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <stdio.h>
+
+
+/* Return the name of the controlling terminal.
+   If S is not NULL, the name is copied into it (it should be at
+   least L_ctermid bytes long), otherwise a static buffer is used.  */
+char *
+ctermid (s)
+     char *s;
+{
+  __set_errno (ENOSYS);
+  return NULL;
+}
+
+
+stub_warning (ctermid)
+#include <stub-tag.h>
diff --git a/stdio-common/cuserid.c b/stdio-common/cuserid.c
new file mode 100644
index 0000000000..826972f4de
--- /dev/null
+++ b/stdio-common/cuserid.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdio.h>
+#include <errno.h>
+
+/* Return the username of the caller.
+   If S is not NULL, it points to a buffer of at least L_cuserid bytes
+   into which the name is copied; otherwise, a static buffer is used.  */
+char *
+cuserid (s)
+     char *s;
+{
+  __set_errno (ENOSYS);
+  return NULL;
+}
+
+
+stub_warning (cuserid)
+#include <stub-tag.h>
diff --git a/stdio-common/dprintf.c b/stdio-common/dprintf.c
index b362e5fa71..6d00e10a63 100644
--- a/stdio-common/dprintf.c
+++ b/stdio-common/dprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,95,97,98,2002,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991,95,97,98,2002,2004,2006 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
@@ -19,13 +19,13 @@
 #include <stdarg.h>
 #include <stdio.h>
 
-#include <libio/libioP.h>
+#include <libioP.h>
 #define vdprintf(d, f, a) _IO_vdprintf (d, f, a)
 
 /* Write formatted output to D, according to the format string FORMAT.  */
 /* VARARGS2 */
 int
-dprintf (int d, const char *format, ...)
+__dprintf (int d, const char *format, ...)
 {
   va_list arg;
   int done;
@@ -36,4 +36,5 @@ dprintf (int d, const char *format, ...)
 
   return done;
 }
-libc_hidden_def (dprintf)
+ldbl_hidden_def (__dprintf, dprintf)
+ldbl_strong_alias (__dprintf, dprintf)
diff --git a/stdio-common/errlist.c b/stdio-common/errlist.c
new file mode 100644
index 0000000000..6a834fc329
--- /dev/null
+++ b/stdio-common/errlist.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991, 1994, 1997, 2005 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stddef.h>
+
+
+const char *const _sys_errlist[] =
+  {
+    "Error 0",			/* 0 */
+    "Argument out of function's domain", /* 1 = EDOM */
+    "Result out of range",	/* 2 = ERANGE */
+    "Operation not implemented", /* 3 = ENOSYS */
+    "Invalid argument",		/* 4 = EINVAL */
+    "Illegal seek",		/* 5 = ESPIPE */
+    "Bad file descriptor",	/* 6 = EBADF */
+    "Cannot allocate memory",	/* 7 = ENOMEM */
+    "Permission denied",	/* 8 = EACCES */
+    "Too many open files in system", /* 9 = ENFILE */
+    "Too many open files",	/* 10 = EMFILE */
+  };
+
+const int _sys_nerr = sizeof (_sys_errlist) / sizeof (_sys_errlist[0]);
diff --git a/stdio-common/flockfile.c b/stdio-common/flockfile.c
new file mode 100644
index 0000000000..571930ee54
--- /dev/null
+++ b/stdio-common/flockfile.c
@@ -0,0 +1,30 @@
+/* Lock I/O stream.  Singlethreaded version.
+   Copyright (C) 1996, 1997, 2000, 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdio.h>
+
+#undef _IO_flockfile
+
+void
+__flockfile (FILE *stream)
+{
+  /* Do nothing.  Using this version does not do any locking.  */
+}
+weak_alias (__flockfile, flockfile);
+weak_alias (__flockfile, _IO_flockfile)
diff --git a/stdio-common/fprintf.c b/stdio-common/fprintf.c
index 0b99fc8994..689e80f466 100644
--- a/stdio-common/fprintf.c
+++ b/stdio-common/fprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,97,2002,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1997, 2002, 2004, 2006 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
@@ -18,12 +18,13 @@
 
 #include <stdarg.h>
 #include <stdio.h>
+#include <libioP.h>
 
 
 /* Write formatted output to STREAM from the format string FORMAT.  */
 /* VARARGS2 */
 int
-fprintf (FILE *stream, const char *format, ...)
+__fprintf (FILE *stream, const char *format, ...)
 {
   va_list arg;
   int done;
@@ -34,9 +35,10 @@ fprintf (FILE *stream, const char *format, ...)
 
   return done;
 }
-libc_hidden_def (fprintf)
+ldbl_hidden_def (__fprintf, fprintf)
+ldbl_strong_alias (__fprintf, fprintf)
 
 /* We define the function with the real name here.  But deep down in
    libio the original function _IO_fprintf is also needed.  So make
    an alias.  */
-weak_alias (fprintf, _IO_fprintf)
+ldbl_weak_alias (__fprintf, _IO_fprintf)
diff --git a/stdio-common/fscanf.c b/stdio-common/fscanf.c
index 58a66eaf30..a6b60162cf 100644
--- a/stdio-common/fscanf.c
+++ b/stdio-common/fscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1997, 2006 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
@@ -16,13 +16,14 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <libioP.h>
 #include <stdarg.h>
 #include <stdio.h>
 
 /* Read formatted input from STREAM according to the format string FORMAT.  */
 /* VARARGS2 */
 int
-fscanf (FILE *stream, const char *format, ...)
+__fscanf (FILE *stream, const char *format, ...)
 {
   va_list arg;
   int done;
@@ -33,3 +34,4 @@ fscanf (FILE *stream, const char *format, ...)
 
   return done;
 }
+ldbl_strong_alias (__fscanf, fscanf)
diff --git a/stdio-common/ftrylockfile.c b/stdio-common/ftrylockfile.c
new file mode 100644
index 0000000000..7bd3e9b53b
--- /dev/null
+++ b/stdio-common/ftrylockfile.c
@@ -0,0 +1,31 @@
+/* Try locking I/O stream.  Singlethreaded version.
+   Copyright (C) 1996, 1997, 2000, 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdio.h>
+
+#undef _IO_ftrylockfile
+
+int
+__ftrylockfile (FILE *stream)
+{
+  /* Do nothing.  Using this version does not do any locking.  */
+  return 1;
+}
+weak_alias (__ftrylockfile, ftrylockfile);
+weak_alias (__ftrylockfile, _IO_ftrylockfile)
diff --git a/stdio-common/funlockfile.c b/stdio-common/funlockfile.c
new file mode 100644
index 0000000000..902d29478d
--- /dev/null
+++ b/stdio-common/funlockfile.c
@@ -0,0 +1,30 @@
+/* Unlock I/O stream.  Singlethreaded version.
+   Copyright (C) 1996, 1997, 2000, 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdio.h>
+
+#undef _IO_funlockfile
+
+void
+__funlockfile (FILE *stream)
+{
+  /* Do nothing.  Using this version does not do any locking.  */
+}
+weak_alias (__funlockfile, _IO_funlockfile)
+weak_alias (__funlockfile, funlockfile);
diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c
new file mode 100644
index 0000000000..f6ba0ca558
--- /dev/null
+++ b/stdio-common/fxprintf.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.org>.
+
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <wchar.h>
+#include <string.h>
+#include <libioP.h>
+
+
+int
+__fxprintf (FILE *fp, const char *fmt, ...)
+{
+  if (fp == NULL)
+    fp = stderr;
+
+  va_list ap;
+  va_start (ap, fmt);
+
+  int res;
+  if (_IO_fwide (fp, 0) > 0)
+    {
+      size_t len = strlen (fmt) + 1;
+      wchar_t wfmt[len];
+      for (size_t i = 0; i < len; ++i)
+	{
+	  assert (isascii (fmt[i]));
+	  wfmt[i] = fmt[i];
+	}
+      res = __vfwprintf (fp, wfmt, ap);
+    }
+  else
+    res = INTUSE(_IO_vfprintf) (fp, fmt, ap);
+
+  va_end (ap);
+
+  return res;
+}
diff --git a/stdio-common/perror.c b/stdio-common/perror.c
index f0751375b5..3ee61520f4 100644
--- a/stdio-common/perror.c
+++ b/stdio-common/perror.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1993,1997,1998,2000-2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1993,1997,1998,2000-2005 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
@@ -37,10 +37,7 @@ perror_internal (FILE *fp, const char *s, int errnum)
 
   errstring = __strerror_r (errnum, buf, sizeof buf);
 
-  if (_IO_fwide (fp, 0) > 0)
-    (void) __fwprintf (fp, L"%s%s%s\n", s, colon, errstring);
-  else
-    (void) fprintf (fp, "%s%s%s\n", s, colon, errstring);
+  (void) __fxprintf (fp, "%s%s%s\n", s, colon, errstring);
 }
 
 
diff --git a/stdio-common/printf-parsemb.c b/stdio-common/printf-parsemb.c
index c55b97060c..2f21fc6365 100644
--- a/stdio-common/printf-parsemb.c
+++ b/stdio-common/printf-parsemb.c
@@ -1,5 +1,5 @@
 /* Helper functions for parsing printf format strings.
-   Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2000,2002,2003,2004,2006 Free Software Foundation, Inc.
    This file is part of th GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -64,7 +64,8 @@ __find_specmb (const UCHAR_T *format, mbstate_t *ps)
 
       /* Remove any hints of a wrong encoding.  */
       ps->__count = 0;
-      if (! isascii (*format) && (len = __mbrlen (format, MB_CUR_MAX, ps)) > 0)
+      if (! isascii (*format)
+	  && (len = __mbrlen ((const CHAR_T *) format, MB_CUR_MAX, ps)) > 0)
 	format += len;
       else
 	++format;
diff --git a/stdio-common/printf-prs.c b/stdio-common/printf-prs.c
index f3b27d6712..015b01f1ed 100644
--- a/stdio-common/printf-prs.c
+++ b/stdio-common/printf-prs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1995, 1996, 1999, 2000, 2002, 2003, 2004
+/* Copyright (C) 1991, 1992, 1995, 1996, 1999, 2000, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -67,15 +67,16 @@ parse_printf_format (fmt, n, argtypes)
   size_t max_ref_arg;		/* Highest index used in a positional arg.  */
   struct printf_spec spec;
   mbstate_t mbstate;
+  const unsigned char *f = (const unsigned char *) fmt;
 
   nargs = 0;
   max_ref_arg = 0;
 
   /* Search for format specifications.  */
-  for (fmt = __find_specmb (fmt, &mbstate); *fmt != '\0'; fmt = spec.next_fmt)
+  for (f = __find_specmb (f, &mbstate); *f != '\0'; f = spec.next_fmt)
     {
       /* Parse this spec.  */
-      nargs += __parse_one_specmb (fmt, nargs, &spec, &max_ref_arg, &mbstate);
+      nargs += __parse_one_specmb (f, nargs, &spec, &max_ref_arg, &mbstate);
 
       /* If the width is determined by an argument this is an int.  */
       if (spec.width_arg != -1 && (size_t) spec.width_arg < n)
diff --git a/stdio-common/printf.c b/stdio-common/printf.c
index e28c5837e5..4c8f3a2a0c 100644
--- a/stdio-common/printf.c
+++ b/stdio-common/printf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2006
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -17,6 +17,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <libioP.h>
 #include <stdarg.h>
 #include <stdio.h>
 
@@ -25,7 +26,7 @@
 /* Write formatted output to stdout from the format string FORMAT.  */
 /* VARARGS1 */
 int
-printf (const char *format, ...)
+__printf (const char *format, ...)
 {
   va_list arg;
   int done;
@@ -38,5 +39,6 @@ printf (const char *format, ...)
 }
 
 #undef _IO_printf
+ldbl_strong_alias (__printf, printf);
 /* This is for libg++.  */
-strong_alias (printf, _IO_printf);
+ldbl_strong_alias (__printf, _IO_printf);
diff --git a/stdio-common/printf.h b/stdio-common/printf.h
index c16569b59b..360cdcce1d 100644
--- a/stdio-common/printf.h
+++ b/stdio-common/printf.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-1993,1995-1999,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1993,1995-1999,2000,2001,2006
+	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
@@ -139,6 +140,9 @@ extern int printf_size_info (__const struct printf_info *__restrict
 			     __info, size_t __n, int *__restrict __argtypes)
      __THROW;
 
+#ifdef __LDBL_COMPAT
+# include <bits/printf-ldbl.h>
+#endif
 
 __END_DECLS
 
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index ed225e05a6..c7a381a69d 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -1,5 +1,5 @@
 /* Floating point output for `printf'.
-   Copyright (C) 1995-1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 1995-2003, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
@@ -71,7 +71,11 @@
     {									      \
       register const int outc = (ch);					      \
       if (putc (outc, fp) == EOF)					      \
-	return -1;							      \
+	{								      \
+	  if (buffer_malloced)						      \
+	    free (wbuffer);						      \
+	  return -1;							      \
+	}								      \
       ++done;								      \
     } while (0)
 
@@ -82,7 +86,11 @@
       if (len > 20)							      \
 	{								      \
 	  if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
-	    return -1;							      \
+	    {								      \
+	      if (buffer_malloced)					      \
+		free (wbuffer);						      \
+	      return -1;						      \
+	    }								      \
 	  ptr += outlen;						      \
 	  done += outlen;						      \
 	}								      \
@@ -101,7 +109,11 @@
   do									      \
     {									      \
       if (PAD (fp, ch, len) != len)					      \
-	return -1;							      \
+	{								      \
+	  if (buffer_malloced)						      \
+	    free (wbuffer);						      \
+	  return -1;							      \
+	}								      \
       done += len;							      \
     }									      \
   while (0)
@@ -138,9 +150,9 @@ static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
 
 
 int
-__printf_fp (FILE *fp,
-	     const struct printf_info *info,
-	     const void *const *args)
+___printf_fp (FILE *fp,
+	      const struct printf_info *info,
+	      const void *const *args)
 {
   /* The floating-point value to output.  */
   union
@@ -199,6 +211,11 @@ __printf_fp (FILE *fp,
   /* Nonzero if this is output on a wide character stream.  */
   int wide = info->wide;
 
+  /* Buffer in which we produce the output.  */
+  wchar_t *wbuffer = NULL;
+  /* Flag whether wbuffer is malloc'ed or not.  */
+  int buffer_malloced = 0;
+
   auto wchar_t hack_digit (void);
 
   wchar_t hack_digit (void)
@@ -775,7 +792,7 @@ __printf_fp (FILE *fp,
   else
     {
       /* This is a special case.  We don't need a factor because the
-	 numbers are in the range of 0.0 <= fp < 8.0.  We simply
+	 numbers are in the range of 1.0 <= |fp| < 8.0.  We simply
 	 shift it to the right place and divide it by 1.0 to get the
 	 leading digit.	 (Of course this division is not really made.)	*/
       assert (0 <= exponent && exponent < 3 &&
@@ -789,17 +806,18 @@ __printf_fp (FILE *fp,
 
   {
     int width = info->width;
-    wchar_t *wbuffer, *wstartp, *wcp;
-    int buffer_malloced;
+    wchar_t *wstartp, *wcp;
     int chars_needed;
     int expscale;
     int intdig_max, intdig_no = 0;
-    int fracdig_min, fracdig_max, fracdig_no = 0;
+    int fracdig_min;
+    int fracdig_max;
     int dig_max;
     int significant;
     int ngroups = 0;
+    char spec = _tolower (info->spec);
 
-    if (_tolower (info->spec) == 'e')
+    if (spec == 'e')
       {
 	type = info->spec;
 	intdig_max = 1;
@@ -809,7 +827,7 @@ __printf_fp (FILE *fp,
 	dig_max = INT_MAX;		/* Unlimited.  */
 	significant = 1;		/* Does not matter here.  */
       }
-    else if (_tolower (info->spec) == 'f')
+    else if (spec == 'f')
       {
 	type = 'f';
 	fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
@@ -906,7 +924,9 @@ __printf_fp (FILE *fp,
       }
 
     /* Generate the needed number of fractional digits.	 */
-    while (fracdig_no < fracdig_min
+    int fracdig_no = 0;
+    int added_zeros = 0;
+    while (fracdig_no < fracdig_min + added_zeros
 	   || (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
       {
 	++fracdig_no;
@@ -917,7 +937,7 @@ __printf_fp (FILE *fp,
 	  {
 	    ++fracdig_max;
 	    if (fracdig_min > 0)
-	      ++fracdig_min;
+	      ++added_zeros;
 	  }
       }
 
@@ -954,11 +974,23 @@ __printf_fp (FILE *fp,
 	  {
 	    /* Process fractional digits.  Terminate if not rounded or
 	       radix character is reached.  */
+	    int removed = 0;
 	    while (*--wtp != decimalwc && *wtp == L'9')
-	      *wtp = '0';
+	      {
+		*wtp = L'0';
+		++removed;
+	      }
+	    if (removed == fracdig_min && added_zeros > 0)
+	      --added_zeros;
 	    if (*wtp != decimalwc)
 	      /* Round up.  */
 	      (*wtp)++;
+	    else if (__builtin_expect (spec == 'g' && type == 'f' && info->alt,
+				       0))
+	      /* This is a special case: the rounded number is 1.0,
+		 the format is 'g' or 'G', and the alternative format
+		 is selected.  This means the result must be "1.".  */
+	      --added_zeros;
 	  }
 
 	if (fracdig_no == 0 || *wtp == decimalwc)
@@ -980,6 +1012,12 @@ __printf_fp (FILE *fp,
 		  {
 		    *wstartp = '1';
 		    exponent += expsign == 0 ? 1 : -1;
+
+		    /* The above exponent adjustment could lead to 1.0e-00,
+		       e.g. for 0.999999999.  Make sure exponent 0 always
+		       uses + sign.  */
+		    if (exponent == 0)
+		      expsign = 0;
 		  }
 		else if (intdig_no == dig_max)
 		  {
@@ -1025,7 +1063,7 @@ __printf_fp (FILE *fp,
 
   do_expo:
     /* Now remove unnecessary '0' at the end of the string.  */
-    while (fracdig_no > fracdig_min && *(wcp - 1) == L'0')
+    while (fracdig_no > fracdig_min + added_zeros && *(wcp - 1) == L'0')
       {
 	--wcp;
 	--fracdig_no;
@@ -1043,26 +1081,46 @@ __printf_fp (FILE *fp,
     /* Write the exponent if it is needed.  */
     if (type != 'f')
       {
-	*wcp++ = (wchar_t) type;
-	*wcp++ = expsign ? L'-' : L'+';
+	if (__builtin_expect (expsign != 0 && exponent == 4 && spec == 'g', 0))
+	  {
+	    /* This is another special case.  The exponent of the number is
+	       really smaller than -4, which requires the 'e'/'E' format.
+	       But after rounding the number has an exponent of -4.  */
+	    assert (wcp >= wstartp + 1);
+	    assert (wstartp[0] == L'1');
+	    __wmemcpy (wstartp, L"0.0001", 6);
+	    wstartp[1] = decimalwc;
+	    if (wcp >= wstartp + 2)
+	      {
+		wmemset (wstartp + 6, L'0', wcp - (wstartp + 2));
+		wcp += 4;
+	      }
+	    else
+	      wcp += 5;
+	  }
+	else
+	  {
+	    *wcp++ = (wchar_t) type;
+	    *wcp++ = expsign ? L'-' : L'+';
 
-	/* Find the magnitude of the exponent.	*/
-	expscale = 10;
-	while (expscale <= exponent)
-	  expscale *= 10;
+	    /* Find the magnitude of the exponent.	*/
+	    expscale = 10;
+	    while (expscale <= exponent)
+	      expscale *= 10;
 
-	if (exponent < 10)
-	  /* Exponent always has at least two digits.  */
-	  *wcp++ = L'0';
-	else
-	  do
-	    {
-	      expscale /= 10;
-	      *wcp++ = L'0' + (exponent / expscale);
-	      exponent %= expscale;
-	    }
-	  while (expscale > 10);
-	*wcp++ = L'0' + exponent;
+	    if (exponent < 10)
+	      /* Exponent always has at least two digits.  */
+	      *wcp++ = L'0';
+	    else
+	      do
+		{
+		  expscale /= 10;
+		  *wcp++ = L'0' + (exponent / expscale);
+		  exponent %= expscale;
+		}
+	      while (expscale > 10);
+	    *wcp++ = L'0' + exponent;
+	  }
       }
 
     /* Compute number of characters which must be filled with the padding
@@ -1108,8 +1166,12 @@ __printf_fp (FILE *fp,
 	      buffer = (char *) malloc (2 + chars_needed + decimal_len
 					+ ngroups * thousands_sep_len);
 	      if (buffer == NULL)
-		/* Signal an error to the caller.  */
-		return -1;
+		{
+		  /* Signal an error to the caller.  */
+		  if (buffer_malloced)
+		    free (wbuffer);
+		  return -1;
+		}
 	    }
 	  else
 	    buffer = (char *) alloca (2 + chars_needed + decimal_len
@@ -1153,7 +1215,8 @@ __printf_fp (FILE *fp,
   }
   return done;
 }
-libc_hidden_def (__printf_fp)
+ldbl_hidden_def (___printf_fp, __printf_fp)
+ldbl_strong_alias (___printf_fp, __printf_fp)
 
 /* Return the number of extra grouping characters that will be inserted
    into a number with INTDIG_MAX integer digits.  */
diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c
new file mode 100644
index 0000000000..4e30d94c61
--- /dev/null
+++ b/stdio-common/printf_fphex.c
@@ -0,0 +1,493 @@
+/* Print floating point number in hexadecimal notation according to ISO C99.
+   Copyright (C) 1997-2002,2004,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <ctype.h>
+#include <ieee754.h>
+#include <math.h>
+#include <printf.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#include "_itoa.h"
+#include "_itowa.h"
+#include <locale/localeinfo.h>
+
+/* #define NDEBUG 1*/		/* Undefine this for debugging assertions.  */
+#include <assert.h>
+
+/* This defines make it possible to use the same code for GNU C library and
+   the GNU I/O library.	 */
+#ifdef USE_IN_LIBIO
+# include <libioP.h>
+# define PUT(f, s, n) _IO_sputn (f, s, n)
+# define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : INTUSE(_IO_padn) (f, c, n))
+/* We use this file GNU C library and GNU I/O library.	So make
+   names equal.	 */
+# undef putc
+# define putc(c, f) (wide \
+		     ? (int)_IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f))
+# define size_t     _IO_size_t
+# define FILE	     _IO_FILE
+#else	/* ! USE_IN_LIBIO */
+# define PUT(f, s, n) fwrite (s, 1, n, f)
+# define PAD(f, c, n) __printf_pad (f, c, n)
+ssize_t __printf_pad (FILE *, char pad, int n) __THROW; /* In vfprintf.c.  */
+#endif	/* USE_IN_LIBIO */
+
+/* Macros for doing the actual output.  */
+
+#define outchar(ch)							      \
+  do									      \
+    {									      \
+      register const int outc = (ch);					      \
+      if (putc (outc, fp) == EOF)					      \
+	return -1;							      \
+      ++done;								      \
+    } while (0)
+
+#define PRINT(ptr, wptr, len)						      \
+  do									      \
+    {									      \
+      register size_t outlen = (len);					      \
+      if (wide)								      \
+	while (outlen-- > 0)						      \
+	  outchar (*wptr++);						      \
+      else								      \
+	while (outlen-- > 0)						      \
+	  outchar (*ptr++);						      \
+    } while (0)
+
+#define PADN(ch, len)							      \
+  do									      \
+    {									      \
+      if (PAD (fp, ch, len) != len)					      \
+	return -1;							      \
+      done += len;							      \
+    }									      \
+  while (0)
+
+#ifndef MIN
+# define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+
+int
+__printf_fphex (FILE *fp,
+		const struct printf_info *info,
+		const void *const *args)
+{
+  /* The floating-point value to output.  */
+  union
+    {
+      union ieee754_double dbl;
+      union ieee854_long_double ldbl;
+    }
+  fpnum;
+
+  /* Locale-dependent representation of decimal point.	*/
+  const char *decimal;
+  wchar_t decimalwc;
+
+  /* "NaN" or "Inf" for the special cases.  */
+  const char *special = NULL;
+  const wchar_t *wspecial = NULL;
+
+  /* Buffer for the generated number string for the mantissa.  The
+     maximal size for the mantissa is 128 bits.  */
+  char numbuf[32];
+  char *numstr;
+  char *numend;
+  wchar_t wnumbuf[32];
+  wchar_t *wnumstr;
+  wchar_t *wnumend;
+  int negative;
+
+  /* The maximal exponent of two in decimal notation has 5 digits.  */
+  char expbuf[5];
+  char *expstr;
+  wchar_t wexpbuf[5];
+  wchar_t *wexpstr;
+  int expnegative;
+  int exponent;
+
+  /* Non-zero is mantissa is zero.  */
+  int zero_mantissa;
+
+  /* The leading digit before the decimal point.  */
+  char leading;
+
+  /* Precision.  */
+  int precision = info->prec;
+
+  /* Width.  */
+  int width = info->width;
+
+  /* Number of characters written.  */
+  int done = 0;
+
+  /* Nonzero if this is output on a wide character stream.  */
+  int wide = info->wide;
+
+
+  /* Figure out the decimal point character.  */
+  if (info->extra == 0)
+    {
+      decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+      decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
+    }
+  else
+    {
+      decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
+      decimalwc = _NL_CURRENT_WORD (LC_MONETARY,
+				    _NL_MONETARY_DECIMAL_POINT_WC);
+    }
+  /* The decimal point character must never be zero.  */
+  assert (*decimal != '\0' && decimalwc != L'\0');
+
+
+  /* Fetch the argument value.	*/
+#ifndef __NO_LONG_DOUBLE_MATH
+  if (info->is_long_double && sizeof (long double) > sizeof (double))
+    {
+      fpnum.ldbl.d = *(const long double *) args[0];
+
+      /* Check for special values: not a number or infinity.  */
+      if (__isnanl (fpnum.ldbl.d))
+	{
+	  if (isupper (info->spec))
+	    {
+	      special = "NAN";
+	      wspecial = L"NAN";
+	    }
+	  else
+	    {
+	      special = "nan";
+	      wspecial = L"nan";
+	    }
+	  negative = 0;
+	}
+      else
+	{
+	  if (__isinfl (fpnum.ldbl.d))
+	    {
+	      if (isupper (info->spec))
+		{
+		  special = "INF";
+		  wspecial = L"INF";
+		}
+	      else
+		{
+		  special = "inf";
+		  wspecial = L"inf";
+		}
+	    }
+
+	  negative = signbit (fpnum.ldbl.d);
+	}
+    }
+  else
+#endif	/* no long double */
+    {
+      fpnum.dbl.d = *(const double *) args[0];
+
+      /* Check for special values: not a number or infinity.  */
+      if (__isnan (fpnum.dbl.d))
+	{
+	  if (isupper (info->spec))
+	    {
+	      special = "NAN";
+	      wspecial = L"NAN";
+	    }
+	  else
+	    {
+	      special = "nan";
+	      wspecial = L"nan";
+	    }
+	  negative = 0;
+	}
+      else
+	{
+	  if (__isinf (fpnum.dbl.d))
+	    {
+	      if (isupper (info->spec))
+		{
+		  special = "INF";
+		  wspecial = L"INF";
+		}
+	      else
+		{
+		  special = "inf";
+		  wspecial = L"inf";
+		}
+	    }
+
+	  negative = signbit (fpnum.dbl.d);
+	}
+    }
+
+  if (special)
+    {
+      int width = info->width;
+
+      if (negative || info->showsign || info->space)
+	--width;
+      width -= 3;
+
+      if (!info->left && width > 0)
+	PADN (' ', width);
+
+      if (negative)
+	outchar ('-');
+      else if (info->showsign)
+	outchar ('+');
+      else if (info->space)
+	outchar (' ');
+
+      PRINT (special, wspecial, 3);
+
+      if (info->left && width > 0)
+	PADN (' ', width);
+
+      return done;
+    }
+
+  if (info->is_long_double == 0 || sizeof (double) == sizeof (long double))
+    {
+      /* We have 52 bits of mantissa plus one implicit digit.  Since
+	 52 bits are representable without rest using hexadecimal
+	 digits we use only the implicit digits for the number before
+	 the decimal point.  */
+      unsigned long long int num;
+
+      num = (((unsigned long long int) fpnum.dbl.ieee.mantissa0) << 32
+	     | fpnum.dbl.ieee.mantissa1);
+
+      zero_mantissa = num == 0;
+
+      if (sizeof (unsigned long int) > 6)
+	{
+	  wnumstr = _itowa_word (num, wnumbuf + (sizeof wnumbuf) / sizeof (wchar_t), 16,
+				 info->spec == 'A');
+	  numstr = _itoa_word (num, numbuf + sizeof numbuf, 16,
+			       info->spec == 'A');
+	}
+      else
+	{
+	  wnumstr = _itowa (num, wnumbuf + sizeof wnumbuf / sizeof (wchar_t), 16,
+			    info->spec == 'A');
+	  numstr = _itoa (num, numbuf + sizeof numbuf, 16,
+			  info->spec == 'A');
+	}
+
+      /* Fill with zeroes.  */
+      while (wnumstr > wnumbuf + (sizeof wnumbuf - 52) / sizeof (wchar_t))
+	{
+	  *--wnumstr = L'0';
+	  *--numstr = '0';
+	}
+
+      leading = fpnum.dbl.ieee.exponent == 0 ? '0' : '1';
+
+      exponent = fpnum.dbl.ieee.exponent;
+
+      if (exponent == 0)
+	{
+	  if (zero_mantissa)
+	    expnegative = 0;
+	  else
+	    {
+	      /* This is a denormalized number.  */
+	      expnegative = 1;
+	      exponent = IEEE754_DOUBLE_BIAS - 1;
+	    }
+	}
+      else if (exponent >= IEEE754_DOUBLE_BIAS)
+	{
+	  expnegative = 0;
+	  exponent -= IEEE754_DOUBLE_BIAS;
+	}
+      else
+	{
+	  expnegative = 1;
+	  exponent = -(exponent - IEEE754_DOUBLE_BIAS);
+	}
+    }
+#ifdef PRINT_FPHEX_LONG_DOUBLE
+  else
+    PRINT_FPHEX_LONG_DOUBLE;
+#endif
+
+  /* Look for trailing zeroes.  */
+  if (! zero_mantissa)
+    {
+      wnumend = &wnumbuf[sizeof wnumbuf / sizeof wnumbuf[0]];
+      numend = &numbuf[sizeof numbuf / sizeof numbuf[0]];
+      while (wnumend[-1] == L'0')
+	{
+	  --wnumend;
+	  --numend;
+	}
+
+      if (precision == -1)
+	precision = numend - numstr;
+      else if (precision < numend - numstr
+	       && (numstr[precision] > '8'
+		   || (('A' < '0' || 'a' < '0')
+		       && numstr[precision] < '0')
+		   || (numstr[precision] == '8'
+		       && (precision + 1 < numend - numstr
+			   /* Round to even.  */
+			   || (precision > 0
+			       && ((numstr[precision - 1] & 1)
+				   ^ (isdigit (numstr[precision - 1]) == 0)))
+			   || (precision == 0
+			       && ((leading & 1)
+				   ^ (isdigit (leading) == 0)))))))
+	{
+	  /* Round up.  */
+	  int cnt = precision;
+	  while (--cnt >= 0)
+	    {
+	      char ch = numstr[cnt];
+	      /* We assume that the digits and the letters are ordered
+		 like in ASCII.  This is true for the rest of GNU, too.  */
+	      if (ch == '9')
+		{
+		  wnumstr[cnt] = (wchar_t) info->spec;
+		  numstr[cnt] = info->spec;	/* This is tricky,
+		  				   think about it!  */
+		  break;
+		}
+	      else if (tolower (ch) < 'f')
+		{
+		  ++numstr[cnt];
+		  ++wnumstr[cnt];
+		  break;
+		}
+	      else
+		{
+		  numstr[cnt] = '0';
+		  wnumstr[cnt] = L'0';
+		}
+	    }
+	  if (cnt < 0)
+	    {
+	      /* The mantissa so far was fff...f  Now increment the
+		 leading digit.  Here it is again possible that we
+		 get an overflow.  */
+	      if (leading == '9')
+		leading = info->spec;
+	      else if (tolower (leading) < 'f')
+		++leading;
+	      else
+		{
+		  leading = '1';
+		  if (expnegative)
+		    {
+		      exponent -= 4;
+		      if (exponent <= 0)
+			{
+			  exponent = -exponent;
+			  expnegative = 0;
+			}
+		    }
+		  else
+		    exponent += 4;
+		}
+	    }
+	}
+    }
+  else
+    {
+      if (precision == -1)
+	precision = 0;
+      numend = numstr;
+      wnumend = wnumstr;
+    }
+
+  /* Now we can compute the exponent string.  */
+  expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0);
+  wexpstr = _itowa_word (exponent,
+			 wexpbuf + sizeof wexpbuf / sizeof (wchar_t), 10, 0);
+
+  /* Now we have all information to compute the size.  */
+  width -= ((negative || info->showsign || info->space)
+	    /* Sign.  */
+	    + 2    + 1 + 0 + precision + 1 + 1
+	    /* 0x    h   .   hhh         P   ExpoSign.  */
+	    + ((expbuf + sizeof expbuf) - expstr));
+	    /* Exponent.  */
+
+  /* Count the decimal point.
+     A special case when the mantissa or the precision is zero and the `#'
+     is not given.  In this case we must not print the decimal point.  */
+  if (precision > 0 || info->alt)
+    width -= wide ? 1 : strlen (decimal);
+
+  if (!info->left && info->pad != '0' && width > 0)
+    PADN (' ', width);
+
+  if (negative)
+    outchar ('-');
+  else if (info->showsign)
+    outchar ('+');
+  else if (info->space)
+    outchar (' ');
+
+  outchar ('0');
+  if ('X' - 'A' == 'x' - 'a')
+    outchar (info->spec + ('x' - 'a'));
+  else
+    outchar (info->spec == 'A' ? 'X' : 'x');
+
+  if (!info->left && info->pad == '0' && width > 0)
+    PADN ('0', width);
+
+  outchar (leading);
+
+  if (precision > 0 || info->alt)
+    {
+      const wchar_t *wtmp = &decimalwc;
+      PRINT (decimal, wtmp, wide ? 1 : strlen (decimal));
+    }
+
+  if (precision > 0)
+    {
+      ssize_t tofill = precision - (numend - numstr);
+      PRINT (numstr, wnumstr, MIN (numend - numstr, precision));
+      if (tofill > 0)
+	PADN ('0', tofill);
+    }
+
+  if ('P' - 'A' == 'p' - 'a')
+    outchar (info->spec + ('p' - 'a'));
+  else
+    outchar (info->spec == 'A' ? 'P' : 'p');
+
+  outchar (expnegative ? '-' : '+');
+
+  PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr);
+
+  if (info->left && info->pad != '0' && width > 0)
+    PADN (info->pad, width);
+
+  return done;
+}
diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c
index 32f262ead0..957de2f571 100644
--- a/stdio-common/printf_size.c
+++ b/stdio-common/printf_size.c
@@ -1,5 +1,5 @@
 /* Print size value using units for orders of magnitude.
-   Copyright (C) 1997-2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1997-2002, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
    Based on a proposal by Larry McVoy <lm@sgi.com>.
@@ -86,7 +86,8 @@ extern int __printf_fp (FILE *fp, const struct printf_info *info,
 
 
 int
-printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
+__printf_size (FILE *fp, const struct printf_info *info,
+	       const void *const *args)
 {
   /* Units for the both formats.  */
 #define BINARY_UNITS	" kmgtpezy"
@@ -233,6 +234,7 @@ printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
 
   return done;
 }
+ldbl_strong_alias (__printf_size, printf_size);
 
 /* This is the function used by `vfprintf' to determine number and
    type of the arguments.  */
diff --git a/stdio-common/psignal.c b/stdio-common/psignal.c
index 2e6588c692..98049a5871 100644
--- a/stdio-common/psignal.c
+++ b/stdio-common/psignal.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1995, 1996, 1997, 2001, 2002, 2004
+/* Copyright (C) 1991, 1992, 1995, 1996, 1997, 2001, 2002, 2004, 2005
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -24,10 +24,6 @@
 #include <wchar.h>
 
 
-#ifndef	HAVE_GNU_LD
-#define	_sys_siglist	sys_siglist
-#endif
-
 /* Defined in sys_siglist.c.  */
 extern const char *const _sys_siglist[];
 extern const char *const _sys_siglist_internal[] attribute_hidden;
@@ -47,29 +43,16 @@ psignal (int sig, const char *s)
     colon = ": ";
 
   if (sig >= 0 && sig < NSIG && (desc = INTUSE(_sys_siglist)[sig]) != NULL)
-    {
-      if (_IO_fwide (stderr, 0) > 0)
-	(void) __fwprintf (stderr, L"%s%s%s\n", s, colon, _(desc));
-      else
-	(void) fprintf (stderr, "%s%s%s\n", s, colon, _(desc));
-    }
+    (void) __fxprintf (NULL, "%s%s%s\n", s, colon, _(desc));
   else
     {
       char *buf;
 
       if (__asprintf (&buf, _("%s%sUnknown signal %d\n"), s, colon, sig) < 0)
-	{
-	  if (_IO_fwide (stderr, 0) > 0)
-	    (void) __fwprintf (stderr, L"%s%s%s\n", s, colon, _("Unknown signal"));
-	  else
-	    (void) fprintf (stderr, "%s%s%s\n", s, colon, _("Unknown signal"));
-	}
+	(void) __fxprintf (NULL, "%s%s%s\n", s, colon, _("Unknown signal"));
       else
 	{
-	  if (_IO_fwide (stderr, 0) > 0)
-	    (void) __fwprintf (stderr, L"%s",  buf);
-	  else
-	    (void) fputs (buf, stderr);
+	  (void) __fxprintf (NULL, "%s", buf);
 
 	  free (buf);
 	}
diff --git a/stdio-common/remove.c b/stdio-common/remove.c
new file mode 100644
index 0000000000..5dc0e9edf0
--- /dev/null
+++ b/stdio-common/remove.c
@@ -0,0 +1,33 @@
+/* ANSI C `remove' function to delete a file or directory.  Stub version.
+   Copyright (C) 1995,96,97,2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <stdio.h>
+
+int
+remove (file)
+     const char *file;
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+libc_hidden_def (remove)
+
+stub_warning (remove)
+#include <stub-tag.h>
diff --git a/stdio-common/rename.c b/stdio-common/rename.c
new file mode 100644
index 0000000000..b7d8392179
--- /dev/null
+++ b/stdio-common/rename.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdio.h>
+#include <errno.h>
+
+
+/* Rename the file OLD to NEW.  */
+int
+rename (old, new)
+     const char *old;
+     const char *new;
+{
+  if (old == NULL || new == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+
+stub_warning (rename)
+#include <stub-tag.h>
diff --git a/stdio-common/renameat.c b/stdio-common/renameat.c
new file mode 100644
index 0000000000..1261da88a4
--- /dev/null
+++ b/stdio-common/renameat.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 2005, 2006 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+
+/* Rename the file OLD relative to OLDFD to NEW relative to NEWFD.  */
+int
+renameat (oldfd, old, newfd, new)
+     int oldfd;
+     const char *old;
+     int newfd;
+     const char *new;
+{
+  if ((oldfd < 0 && oldfd != AT_FDCWD) || (newfd < 0 && newfd != AT_FDCWD))
+    {
+      __set_errno (EBADF);
+      return -1;
+    }
+
+  if (old == NULL || new == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+
+stub_warning (renameat)
+#include <stub-tag.h>
diff --git a/stdio-common/scanf.c b/stdio-common/scanf.c
index 62c9959651..d4a4daf726 100644
--- a/stdio-common/scanf.c
+++ b/stdio-common/scanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 2002, 2004
+/* Copyright (C) 1991, 1995, 1996, 1997, 2002, 2004, 2006
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -26,7 +26,7 @@
 /* Read formatted input from stdin according to the format string FORMAT.  */
 /* VARARGS1 */
 int
-scanf (const char *format, ...)
+__scanf (const char *format, ...)
 {
   va_list arg;
   int done;
@@ -37,3 +37,4 @@ scanf (const char *format, ...)
 
   return done;
 }
+ldbl_strong_alias (__scanf, scanf)
diff --git a/stdio-common/siglist.c b/stdio-common/siglist.c
new file mode 100644
index 0000000000..80847cd491
--- /dev/null
+++ b/stdio-common/siglist.c
@@ -0,0 +1,38 @@
+/* Define list of all signal numbers and their names.
+   Copyright (C) 1997, 1998, 1999, 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stddef.h>
+#include <signal.h>
+#include <libintl.h>
+
+const char *const _sys_siglist[NSIG] =
+{
+#define init_sig(sig, abbrev, desc)   [sig] = desc,
+#include <siglist.h>
+#undef init_sig
+};
+strong_alias (_sys_siglist, _sys_siglist_internal)
+
+
+const char *const _sys_sigabbrev[NSIG] =
+{
+#define init_sig(sig, abbrev, desc)   [sig] = abbrev,
+#include <siglist.h>
+#undef init_sig
+};
diff --git a/stdio-common/snprintf.c b/stdio-common/snprintf.c
index ce392f0096..00d2082350 100644
--- a/stdio-common/snprintf.c
+++ b/stdio-common/snprintf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991, 1995, 1997, 1998, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1997, 1998, 2004, 2006
+   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
@@ -18,8 +19,7 @@
 
 #include <stdarg.h>
 #include <stdio.h>
-
-#include <libio/libioP.h>
+#include <libioP.h>
 #define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
 
 /* Write formatted output into S, according to the format
@@ -37,4 +37,4 @@ __snprintf (char *s, size_t maxlen, const char *format, ...)
 
   return done;
 }
-weak_alias (__snprintf, snprintf)
+ldbl_weak_alias (__snprintf, snprintf)
diff --git a/stdio-common/sprintf.c b/stdio-common/sprintf.c
index 249fcb0dde..7f564d5635 100644
--- a/stdio-common/sprintf.c
+++ b/stdio-common/sprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1997, 1998, 2002, 2004
+/* Copyright (C) 1991, 1995, 1997, 1998, 2002, 2004, 2006
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -19,13 +19,13 @@
 
 #include <stdarg.h>
 #include <stdio.h>
-#include <libio/iolibio.h>
+#include <libioP.h>
 #define vsprintf(s, f, a) INTUSE(_IO_vsprintf) (s, f, a)
 
 /* Write formatted output into S, according to the format string FORMAT.  */
 /* VARARGS2 */
 int
-sprintf (char *s, const char *format, ...)
+__sprintf (char *s, const char *format, ...)
 {
   va_list arg;
   int done;
@@ -36,6 +36,6 @@ sprintf (char *s, const char *format, ...)
 
   return done;
 }
-libc_hidden_def (sprintf)
-
-strong_alias(sprintf, _IO_sprintf)
+ldbl_hidden_def (__sprintf, sprintf)
+ldbl_strong_alias (__sprintf, sprintf)
+ldbl_strong_alias (__sprintf, _IO_sprintf)
diff --git a/stdio-common/sscanf.c b/stdio-common/sscanf.c
index b36976710b..384a6977dc 100644
--- a/stdio-common/sscanf.c
+++ b/stdio-common/sscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1998, 2002, 2003, 2004
+/* Copyright (C) 1991, 1995, 1996, 1998, 2002, 2003, 2004, 2006
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -19,13 +19,13 @@
 
 #include <stdarg.h>
 #include <stdio.h>
-#include <libio/iolibio.h>
+#include <libioP.h>
 #define __vsscanf(s, f, a) _IO_vsscanf (s, f, a)
 
 /* Read formatted input from S, according to the format string FORMAT.  */
 /* VARARGS2 */
 int
-sscanf (const char *s, const char *format, ...)
+__sscanf (const char *s, const char *format, ...)
 {
   va_list arg;
   int done;
@@ -36,8 +36,8 @@ sscanf (const char *s, const char *format, ...)
 
   return done;
 }
-libc_hidden_def (sscanf)
-
+ldbl_hidden_def (__sscanf, sscanf)
+ldbl_strong_alias (__sscanf, sscanf)
 #undef _IO_sscanf
 /* This is for libg++.  */
-strong_alias (sscanf, _IO_sscanf)
+ldbl_strong_alias (__sscanf, _IO_sscanf)
diff --git a/stdio-common/tempname.c b/stdio-common/tempname.c
new file mode 100644
index 0000000000..60c94d6409
--- /dev/null
+++ b/stdio-common/tempname.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1991, 92, 93, 95-98, 99 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define __need_size_t
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+
+/* Perform the "SVID path search malarkey" on DIR and PFX.  Write a
+   template suitable for use in __gen_tempname into TMPL, bounded
+   by TMPL_LEN. */
+int
+__path_search (tmpl, tmpl_len, dir, pfx, try_tmpdir)
+     char *tmpl;
+     size_t tmpl_len;
+     const char *dir;
+     const char *pfx;
+     int try_tmpdir;
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__path_search)
+
+/* Generate a (hopefully) unique temporary filename
+   in DIR (if applicable), using template TMPL.
+   KIND determines what to do with that name.  It may be one of:
+     __GT_FILE:		create a file and return a read-write fd.
+     __GT_BIGFILE:	same, but use open64() (or equivalent).
+     __GT_DIR:		create a directory.
+     __GT_NOCREATE:	just find a name not currently in use.
+ */
+
+int
+__gen_tempname (tmpl, kind)
+     char *tmpl;
+     int kind;
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+stub_warning (__gen_tempname)
+#include <stub-tag.h>
diff --git a/stdio-common/test-vfprintf.c b/stdio-common/test-vfprintf.c
index a683eac779..342ac471da 100644
--- a/stdio-common/test-vfprintf.c
+++ b/stdio-common/test-vfprintf.c
@@ -1,5 +1,5 @@
 /* Tests of *printf for very large strings.
-   Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -94,6 +94,7 @@ main (void)
       fprintf (fp, "%.*s", 30000, large);
       large[20000] = '\0';
       fprintf (fp, large);
+      fprintf (fp, "%-1.300000000s", "hello");
 
       if (fflush (fp) != 0 || ferror (fp) != 0 || fclose (fp) != 0)
 	{
@@ -108,11 +109,12 @@ main (void)
 		  setlocale (LC_ALL, NULL));
 	  exit (1);
 	}
-      else if (st.st_size != 99999)
+      else if (st.st_size != 50000 + 30000 + 19999 + 5)
 	{
 	  printf ("file size incorrect for locale %s: %jd instead of %jd\n",
 		  setlocale (LC_ALL, NULL),
-		  (intmax_t) st.st_size, (intmax_t) 99999);
+		  (intmax_t) st.st_size,
+		  (intmax_t) 50000 + 30000 + 19999 + 5);
 	  res = 1;
 	}
       else
diff --git a/stdio-common/tfformat.c b/stdio-common/tfformat.c
index ea7365b2c9..d67b3b504d 100644
--- a/stdio-common/tfformat.c
+++ b/stdio-common/tfformat.c
@@ -4012,6 +4012,17 @@ sprint_double_type sprint_doubles[] =
   {__LINE__, 16,			"0x1.0p+4", "%.1a"},
   {__LINE__, 16,			"0x1.00000000000000000000p+4", "%.20a"},
   {__LINE__, 4444.88888888,		"4445", "%2.F"},
+  {__LINE__, 0.956,			"1", "%.0g"},
+  {__LINE__, 1.0956,			"1.", "%#.0g"},
+  {__LINE__, 0.956,			"1.", "%#.0g"},
+  {__LINE__, 0.0956,			"0.1", "%#.0g"},
+  {__LINE__, 0.00956,			"0.01", "%#.0g"},
+  {__LINE__, 0.000956,			"0.001", "%#.0g"},
+  {__LINE__, 0.000098,			"0.0001", "%#.0g"},
+  {__LINE__, 0.0000996,			"0.00010", "%#.2g"},
+  {__LINE__, 9.999999999999999e-05,	"0.0001", "%g"},
+  {__LINE__, 1.0,			"1.000000e+00", "%e"},
+  {__LINE__, .9999999999999999,		"1.000000e+00", "%e"},
 
   {0 }
 
@@ -4023,13 +4034,8 @@ sprint_double_type sprint_doubles[] =
 
 int required_precision = 13;
 
-#if defined(__STDC__) || defined(__cplusplus)
 static int
 matches (register char *result, register const char *desired)
-#else
-int matches(result, desired)
-     register char *result; register const char *desired;
-#endif
 {
     int digits_seen = 0;
     for (;; result++, desired++) {
@@ -4080,7 +4086,7 @@ int main(int argc, char *argv[])
 
   /* And one special test.  */
   {
-    const char ref[] = "1.7763568394002504646778106689453125e-15";
+    static const char ref[] = "1.7763568394002504646778106689453125e-15";
     int i;
     d = 1.0;
     for (i = 1; i < 50; ++i)
diff --git a/stdio-common/tmpfile.c b/stdio-common/tmpfile.c
new file mode 100644
index 0000000000..41f12bc8ba
--- /dev/null
+++ b/stdio-common/tmpfile.c
@@ -0,0 +1,66 @@
+/* Open a stdio stream on an anonymous temporary file.  Generic/POSIX version.
+   Copyright (C) 1991,93,1996-2000,2002,2003 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef USE_IN_LIBIO
+# include <iolibio.h>
+# define __fdopen INTUSE(_IO_fdopen)
+# ifndef tmpfile
+#  define tmpfile __new_tmpfile
+# endif
+#endif
+
+#ifndef GEN_THIS
+# define GEN_THIS __GT_FILE
+#endif
+
+/* This returns a new stream opened on a temporary file (generated
+   by tmpnam).  The file is opened with mode "w+b" (binary read/write).
+   If we couldn't generate a unique filename or the file couldn't
+   be opened, NULL is returned.  */
+FILE *
+tmpfile (void)
+{
+  char buf[FILENAME_MAX];
+  int fd;
+  FILE *f;
+
+  if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
+    return NULL;
+  fd = __gen_tempname (buf, GEN_THIS);
+  if (fd < 0)
+    return NULL;
+
+  /* Note that this relies on the Unix semantics that
+     a file is not really removed until it is closed.  */
+  (void) __unlink (buf);
+
+  if ((f = __fdopen (fd, "w+b")) == NULL)
+    __close (fd);
+
+  return f;
+}
+
+#if defined USE_IN_LIBIO && GEN_THIS == __GT_FILE /* Not for tmpfile64.  */
+# undef tmpfile
+# include <shlib-compat.h>
+versioned_symbol (libc, __new_tmpfile, tmpfile, GLIBC_2_1);
+#endif
diff --git a/stdio-common/tmpfile64.c b/stdio-common/tmpfile64.c
new file mode 100644
index 0000000000..b265aeee56
--- /dev/null
+++ b/stdio-common/tmpfile64.c
@@ -0,0 +1,3 @@
+#define GEN_THIS	__GT_BIGFILE
+#define tmpfile		tmpfile64
+#include <tmpfile.c>
diff --git a/stdio-common/tst-fgets.c b/stdio-common/tst-fgets.c
new file mode 100644
index 0000000000..0aa9030e3a
--- /dev/null
+++ b/stdio-common/tst-fgets.c
@@ -0,0 +1,20 @@
+/* Derived from the test case in
+   http://sourceware.org/bugzilla/show_bug.cgi?id=713.  */
+#include <stdio.h>
+
+static int
+do_test (void)
+{
+  FILE *fp = fmemopen ((char *) "hello", 5, "r");
+  char buf[2];
+  char *bp = fgets (buf, sizeof (buf), fp);
+  printf ("fgets: %s\n", bp == buf ? "OK" : "ERROR");
+  int res = bp != buf;
+  bp = fgets_unlocked (buf, sizeof (buf), fp);
+  printf ("fgets_unlocked: %s\n", bp == buf ? "OK" : "ERROR");
+  res |= bp != buf;
+  return res;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdio-common/tst-fmemopen2.c b/stdio-common/tst-fmemopen2.c
new file mode 100644
index 0000000000..81beddddef
--- /dev/null
+++ b/stdio-common/tst-fmemopen2.c
@@ -0,0 +1,68 @@
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+
+
+static int
+do_test (void)
+{
+  int result = 0;
+  char buf[100];
+  FILE *fp = fmemopen (buf, sizeof (buf), "w");
+  if (fp == NULL)
+    {
+      puts ("fmemopen failed");
+      return 0;
+    }
+  static const char str[] = "hello world";
+#define nstr (sizeof (str) - 1)
+  fputs (str, fp);
+  off_t o = ftello (fp);
+  if (o != nstr)
+    {
+      printf ("first ftello returned %ld, expected %zu\n", o, nstr);
+      result = 1;
+    }
+  rewind (fp);
+  o = ftello (fp);
+  if (o != 0)
+    {
+      printf ("second ftello returned %ld, expected %zu\n", o, (off_t) 0);
+      result = 1;
+    }
+  if (fseeko (fp, 0, SEEK_END) != 0)
+    {
+      puts ("fseeko failed");
+      return 1;
+    }
+  o = ftello (fp);
+  if (o != nstr)
+    {
+      printf ("third ftello returned %ld, expected %zu\n", o, nstr);
+      result = 1;
+    }
+  rewind (fp);
+  static const char str2[] = "just hello";
+#define nstr2 (sizeof (str2) - 1)
+  assert (nstr2 < nstr);
+  fputs (str2, fp);
+  o = ftello (fp);
+  if (o != nstr2)
+    {
+      printf ("fourth ftello returned %ld, expected %zu\n", o, nstr2);
+      result = 1;
+    }
+  fclose (fp);
+  static const char str3[] = "just hellod";
+  if (strcmp (buf, str3) != 0)
+    {
+      printf ("final string is \"%s\", expected \"%s\"\n",
+              buf, str3);
+      result = 1;
+    }
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdio-common/tst-fwrite.c b/stdio-common/tst-fwrite.c
new file mode 100644
index 0000000000..2986c8932a
--- /dev/null
+++ b/stdio-common/tst-fwrite.c
@@ -0,0 +1,70 @@
+/* Derived from the test case in
+   http://sourceware.org/bugzilla/show_bug.cgi?id=1078.  */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define OUT_SIZE 10000
+
+
+static int fd;
+
+static void prepare (void);
+#define PREPARE(argc, argv) prepare ()
+
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+
+#include "../test-skeleton.c"
+
+
+static void
+prepare (void)
+{
+  fd = create_temp_file ("tst-fwrite.", NULL);
+  if (fd == -1)
+    {
+      puts ("cannot create temporary file");
+      exit (1);
+    }
+}
+
+
+static int
+do_test (void)
+{
+  FILE* f = fdopen (fd, "w+");
+  if (f == NULL) {
+    puts ("cannot create stream");
+    return 1;
+  }
+  puts ("Opened temp file");
+
+  if (fwrite ("a", 1, 1, f) != 1)
+    {
+      puts ("1st fwrite failed");
+      return 1;
+    }
+  puts ("Wrote a byte");
+  fflush (f);
+
+  char buffer[10000];
+  size_t i = fread (buffer, 1, sizeof (buffer), f);
+  printf ("Read %zu bytes\n", i);
+
+  for (i = 0; i < OUT_SIZE; i++)
+    {
+      if (fwrite ("n", 1, 1, f) != 1)
+	{
+	  printf ("fwrite in loop round %zu failed\n", i);
+	  return 1;
+	}
+
+      if ((i + 1) % 1000 == 0)
+	printf ("wrote %zu bytes ...\n", i + 1);
+    }
+
+  printf ("Wrote %i bytes [done]\n", OUT_SIZE);
+
+  return 0;
+}
diff --git a/stdio-common/tst-printf.c b/stdio-common/tst-printf.c
index a9db7ad2de..06fa38ab55 100644
--- a/stdio-common/tst-printf.c
+++ b/stdio-common/tst-printf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,92,93,95,96,97,98,99, 2000, 2002
+/* Copyright (C) 1991,92,93,95,96,97,98,99, 2000, 2002, 2006
      Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -273,6 +273,15 @@ I am ready for my first lesson today.";
 
   printf ("printf (\"%%hhu\", %u) = %hhu\n", UCHAR_MAX + 2, UCHAR_MAX + 2);
   printf ("printf (\"%%hu\", %u) = %hu\n", USHRT_MAX + 2, USHRT_MAX + 2);
+  printf ("printf (\"%%hhi\", %i) = %hhi\n", UCHAR_MAX + 2, UCHAR_MAX + 2);
+  printf ("printf (\"%%hi\", %i) = %hi\n", USHRT_MAX + 2, USHRT_MAX + 2);
+
+  printf ("printf (\"%%1$hhu\", %2$u) = %1$hhu\n",
+	  UCHAR_MAX + 2, UCHAR_MAX + 2);
+  printf ("printf (\"%%1$hu\", %2$u) = %1$hu\n", USHRT_MAX + 2, USHRT_MAX + 2);
+  printf ("printf (\"%%1$hhi\", %2$i) = %1$hhi\n",
+	  UCHAR_MAX + 2, UCHAR_MAX + 2);
+  printf ("printf (\"%%1$hi\", %2$i) = %1$hi\n", USHRT_MAX + 2, USHRT_MAX + 2);
 
   puts ("--- Should be no further output. ---");
   rfg1 ();
diff --git a/stdio-common/tst-printf.sh b/stdio-common/tst-printf.sh
index 3655558d16..f3091d2f96 100644
--- a/stdio-common/tst-printf.sh
+++ b/stdio-common/tst-printf.sh
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Testing of printf.
-# Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2002, 2006 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 #
 
@@ -136,6 +136,12 @@ Test ok.
 sprintf (buf, "%07Lo", 040000000000ll) = 40000000000
 printf ("%hhu", 257) = 1
 printf ("%hu", 65537) = 1
+printf ("%hhi", 257) = 1
+printf ("%hi", 65537) = 1
+printf ("%1$hhu", 257) = 1
+printf ("%1$hu", 65537) = 1
+printf ("%1$hhi", 257) = 1
+printf ("%1$hi", 65537) = 1
 --- Should be no further output. ---
 EOF
 cmp - ${common_objpfx}stdio-common/tst-printf.out > /dev/null 2>&1 ||
@@ -246,6 +252,12 @@ Test ok.
 sprintf (buf, "%07Lo", 040000000000ll) = 40000000000
 printf ("%hhu", 257) = 1
 printf ("%hu", 65537) = 1
+printf ("%hhi", 257) = 1
+printf ("%hi", 65537) = 1
+printf ("%1$hhu", 257) = 1
+printf ("%1$hu", 65537) = 1
+printf ("%1$hhi", 257) = 1
+printf ("%1$hi", 65537) = 1
 --- Should be no further output. ---
 EOF
 cmp - ${common_objpfx}stdio-common/tst-printf.out > /dev/null 2>&1 ||
diff --git a/stdio-common/tst-put-error.c b/stdio-common/tst-put-error.c
new file mode 100644
index 0000000000..115dbd509a
--- /dev/null
+++ b/stdio-common/tst-put-error.c
@@ -0,0 +1,33 @@
+#include <errno.h>
+#include <error.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+static int
+do_test (void)
+{
+  char tmpl[] = "/tmp/tst-put-error.XXXXXX";
+  int fd = mkstemp (tmpl);
+  if (fd == -1)
+    error (EXIT_FAILURE, errno, "cannot create temporary file");
+  FILE *fp = fdopen (fd, "w");
+  if (fp == NULL)
+    error (EXIT_FAILURE, errno, "fdopen");
+  setlinebuf (fp);
+  close (fd);
+  unlink (tmpl);
+  int n = fprintf (fp, "hello world\n");
+  printf ("fprintf = %d\n", n);
+  if (n >= 0)
+    error (EXIT_FAILURE, 0, "first fprintf succeeded");
+  n = fprintf (fp, "hello world\n");
+  printf ("fprintf = %d\n", n);
+  if (n >= 0)
+    error (EXIT_FAILURE, 0, "second fprintf succeeded");
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdio-common/tst-sprintf.c b/stdio-common/tst-sprintf.c
index c61d3b50e4..c04fef18f4 100644
--- a/stdio-common/tst-sprintf.c
+++ b/stdio-common/tst-sprintf.c
@@ -37,5 +37,26 @@ main (void)
       free (dst);
     }
 
+  if (sprintf (buf, "%1$d%3$.*2$s%4$d", 7, 67108863, "x", 8) != 3
+      || strcmp (buf, "7x8") != 0)
+    {
+      printf ("sprintf (buf, \"%%1$d%%3$.*2$s%%4$d\", 7, 67108863, \"x\", 8) produced `%s' output", buf);
+      result = 1;
+    }
+
+  if (sprintf (buf, "%67108863.16\"%d", 7) != 14
+      || strcmp (buf, "%67108863.16\"7") != 0)
+    {
+      printf ("sprintf (buf, \"%%67108863.16\\\"%%d\", 7) produced `%s' output", buf);
+      result = 1;
+    }
+
+  if (sprintf (buf, "%*\"%d", 0x3ffffff, 7) != 11
+      || strcmp (buf, "%67108863\"7") != 0)
+    {
+      printf ("sprintf (buf, \"%%*\\\"%%d\", 0x3ffffff, 7) produced `%s' output", buf);
+      result = 1;
+    }
+
   return result;
 }
diff --git a/stdio-common/tst-sprintf2.c b/stdio-common/tst-sprintf2.c
new file mode 100644
index 0000000000..debb68e21f
--- /dev/null
+++ b/stdio-common/tst-sprintf2.c
@@ -0,0 +1,82 @@
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+int
+main (void)
+{
+  volatile union { long double l; long long x[2]; } u, v;
+  char buf[64];
+  int result = 0;
+
+#if LDBL_MANT_DIG == 106 || LDBL_MANT_DIG == 113
+# define COMPARE_LDBL(u, v) \
+  ((u).l == (v).l && (u).x[0] == (v).x[0] && (u).x[1] == (v).x[1])
+#else
+# define COMPARE_LDBL(u, v) ((u).l == (v).l)
+#endif
+
+#define TEST(val) \
+  do									   \
+    {									   \
+      u.l = (val);							   \
+      snprintf (buf, sizeof buf, "%LaL", u.l);				   \
+      if (strcmp (buf, #val) != 0)					   \
+	{								   \
+	  printf ("Error on line %d: %s != %s\n", __LINE__, buf, #val);	   \
+	  result = 1;							   \
+	}								   \
+      if (sscanf (#val, "%La", &v.l) != 1 || !COMPARE_LDBL (u, v))	   \
+	{								   \
+	  printf ("Error sscanf on line %d: %La != %La\n", __LINE__,	   \
+		  u.l, v.l);						   \
+	  result = 1;							   \
+	}								   \
+      /* printf ("%s %La %016Lx %016Lx\n", #val, u.l, u.x[0], u.x[1]); */  \
+    }									   \
+  while (0)
+
+#if LDBL_MANT_DIG >= 106
+# if LDBL_MANT_DIG == 106
+  TEST (0x0.ffffffffffffp-1022L);
+  TEST (0x0.ffffffffffff1p-1022L);
+  TEST (0x0.fffffffffffffp-1022L);
+# endif
+  TEST (0x1p-1022L);
+  TEST (0x1.0000000000001p-1022L);
+  TEST (0x1.00000000001e7p-1022L);
+  TEST (0x1.fffffffffffffp-1022L);
+  TEST (0x1p-1021L);
+  TEST (0x1.00000000000008p-1021L);
+  TEST (0x1.0000000000001p-1021L);
+  TEST (0x1.00000000000018p-1021L);
+  TEST (0x1.0000000000000f8p-1017L);
+  TEST (0x1.0000000000001p-1017L);
+  TEST (0x1.000000000000108p-1017L);
+  TEST (0x1.000000000000dcf8p-1013L);
+  TEST (0x1.000000000000ddp-1013L);
+  TEST (0x1.000000000000dd08p-1013L);
+  TEST (0x1.ffffffffffffffffffffffffffp-1L);
+  TEST (0x1.ffffffffffffffffffffffffff8p-1L);
+  TEST (0x1p+0L);
+  TEST (0x1.000000000000000000000000008p+0L);
+  TEST (0x1.00000000000000000000000001p+0L);
+  TEST (0x1.000000000000000000000000018p+0L);
+  TEST (0x1.23456789abcdef123456789abc8p+0L);
+  TEST (0x1.23456789abcde7123456789abc8p+0L);
+  TEST (0x1.23456789abcdef123456789abc8p+64L);
+  TEST (0x1.23456789abcde7123456789abc8p+64L);
+  TEST (0x1.123456789abcdef123456789p-969L);
+# if LDBL_MANT_DIG == 106
+  TEST (-0x1.2d71957cc1263bbbeb1d365f1e8p-969L);
+  TEST (0x1.23456789abcdef0123456789abp-970L);
+  TEST (0x1.579bde02468acp-1001L);
+  TEST (0x0.abcdef0123456p-1022L);
+  TEST (0x1.abcdef0123456p-1022L);
+  TEST (0x1.abcdef012345678p-1014L);
+  TEST (0x1.abcdef0123456f8p-1014L);
+# endif
+#endif
+  return result;
+}
diff --git a/stdio-common/tstdiomisc.c b/stdio-common/tstdiomisc.c
index 452a21f9cb..db038fa2b0 100644
--- a/stdio-common/tstdiomisc.c
+++ b/stdio-common/tstdiomisc.c
@@ -46,6 +46,9 @@ t2 (void)
   return result;
 }
 
+volatile double nanval;
+
+
 static int
 F (void)
 {
@@ -53,8 +56,9 @@ F (void)
   wchar_t wbuf[10];
   int result;
 
-  snprintf (buf, sizeof buf, "%f %F", DBL_MAX * DBL_MAX - DBL_MAX * DBL_MAX,
-	    DBL_MAX * DBL_MAX - DBL_MAX * DBL_MAX);
+  nanval = NAN;
+
+  snprintf (buf, sizeof buf, "%f %F", nanval, nanval);
   result = strcmp (buf, "nan NAN") != 0;
   printf ("expected \"nan NAN\", got \"%s\"\n", buf);
 
@@ -62,9 +66,7 @@ F (void)
   result |= strcmp (buf, "inf INF") != 0;
   printf ("expected \"inf INF\", got \"%s\"\n", buf);
 
-  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%f %F",
-	    DBL_MAX * DBL_MAX - DBL_MAX * DBL_MAX,
-	    DBL_MAX * DBL_MAX - DBL_MAX * DBL_MAX);
+  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%f %F", nanval, nanval);
   result |= wcscmp (wbuf, L"nan NAN") != 0;
   printf ("expected L\"nan NAN\", got L\"%S\"\n", wbuf);
 
diff --git a/stdio-common/tstscanf.c b/stdio-common/tstscanf.c
index 44ddf49e15..123d733e3f 100644
--- a/stdio-common/tstscanf.c
+++ b/stdio-common/tstscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,92,96,97,98,99,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,1996-2001,2007 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
@@ -272,7 +272,7 @@ main (int argc, char **argv)
     res = sscanf ("0x1234", "%lf", &d);
     printf ("res = %d, d = %f\n", res, d);
 
-    if (res != 0 || d != 123456.789)
+    if (res != 1 || d != 4660)
       {
 	fputs ("test failed!\n", stdout);
 	result = 1;
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 832a6ed547..bf5227873b 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007
+   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
@@ -64,7 +65,7 @@
 #define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED)
 
 #ifndef COMPILE_WPRINTF
-# define vfprintf	_IO_vfprintf
+# define vfprintf	_IO_vfprintf_internal
 # define CHAR_T		char
 # define UCHAR_T	unsigned char
 # define INT_T		int
@@ -257,7 +258,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 
 #define NOT_IN_JUMP_RANGE(Ch) ((Ch) < L_(' ') || (Ch) > L_('z'))
 #define CHAR_CLASS(Ch) (jump_table[(INT_T) (Ch) - L_(' ')])
-#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined SHARED
+#ifdef SHARED
   /* 'int' is enough and it saves some space on 64 bit systems.  */
 # define JUMP_TABLE_TYPE const int
 # define JUMP(ChExpr, table)						      \
@@ -529,14 +530,24 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    {								      \
 	      if (is_long_num)						      \
 		signed_number = va_arg (ap, long int);			      \
-	      else  /* `char' and `short int' will be promoted to `int'.  */  \
+	      else if (is_char)						      \
+	        signed_number = (signed char) va_arg (ap, unsigned int);      \
+	      else if (!is_short)					      \
 		signed_number = va_arg (ap, int);			      \
+	      else							      \
+		signed_number = (short int) va_arg (ap, unsigned int);	      \
 	    }								      \
 	  else								      \
 	    if (is_long_num)						      \
 	      signed_number = args_value[fspec->data_arg].pa_long_int;	      \
-	    else  /* `char' and `short int' will be promoted to `int'.  */    \
+	    else if (is_char)						      \
+	      signed_number = (signed char)				      \
+		args_value[fspec->data_arg].pa_u_int;			      \
+	    else if (!is_short)						      \
 	      signed_number = args_value[fspec->data_arg].pa_int;	      \
+	    else							      \
+	      signed_number = (short int)				      \
+		args_value[fspec->data_arg].pa_u_int;			      \
 									      \
 	  is_negative = signed_number < 0;				      \
 	  number.word = is_negative ? (- signed_number) : signed_number;      \
@@ -758,6 +769,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 									      \
 	if (fspec == NULL)						      \
 	  {								      \
+	    if (__ldbl_is_dbl)						      \
+	      is_long_double = 0;					      \
+									      \
 	    struct printf_info info = { .prec = prec,			      \
 					.width = width,			      \
 					.spec = spec,			      \
@@ -785,6 +799,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	else								      \
 	  {								      \
 	    ptr = (const void *) &args_value[fspec->data_arg];		      \
+	    if (__ldbl_is_dbl)						      \
+	      {								      \
+		fspec->data_arg_type = PA_DOUBLE;			      \
+		fspec->info.is_long_double = 0;				      \
+	      }								      \
 									      \
 	    function_done = __printf_fp (s, &fspec->info, &ptr);	      \
 	  }								      \
@@ -808,6 +827,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 									      \
 	if (fspec == NULL)						      \
 	  {								      \
+	    if (__ldbl_is_dbl)						      \
+	      is_long_double = 0;					      \
+									      \
 	    struct printf_info info = { .prec = prec,			      \
 					.width = width,			      \
 					.spec = spec,			      \
@@ -834,6 +856,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	else								      \
 	  {								      \
 	    ptr = (const void *) &args_value[fspec->data_arg];		      \
+	    if (__ldbl_is_dbl)						      \
+	      fspec->info.is_long_double = 0;				      \
 									      \
 	    function_done = __printf_fphex (s, &fspec->info, &ptr);	      \
 	  }								      \
@@ -1001,10 +1025,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    const char *mbs = (const char *) string;			      \
 	    mbstate_t mbstate;						      \
 									      \
-	    len = prec != -1 ? (size_t) prec : strlen (mbs);		      \
+	    len = prec != -1 ? __strnlen (mbs, (size_t) prec) : strlen (mbs); \
 									      \
 	    /* Allocate dynamically an array which definitely is long	      \
-	       enough for the wide character version.  */		      \
+	       enough for the wide character version.  Each byte in the	      \
+	       multi-byte string can produce at most one wide character.  */  \
 	    if (__libc_use_alloca (len * sizeof (wchar_t)))		      \
 	      string = (CHAR_T *) alloca (len * sizeof (wchar_t));	      \
 	    else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t)))    \
@@ -1135,19 +1160,26 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 		else							      \
 		  {							      \
 		    /* In case we have a multibyte character set the	      \
-		       situation is more compilcated.  We must not copy	      \
+		       situation is more complicated.  We must not copy	      \
 		       bytes at the end which form an incomplete character. */\
-		    wchar_t ignore[prec];				      \
+		    size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;\
+		    wchar_t ignore[ignore_size];			      \
 		    const char *str2 = string;				      \
-		    mbstate_t ps;					      \
+		    const char *strend = string + prec;			      \
+		    if (strend < string)				      \
+		      strend = (const char *) UINTPTR_MAX;		      \
 									      \
+		    mbstate_t ps;					      \
 		    memset (&ps, '\0', sizeof (ps));			      \
-		    if (__mbsnrtowcs (ignore, &str2, prec, prec, &ps)	      \
-			== (size_t) -1)					      \
-		      {							      \
-			done = -1;					      \
-			goto all_done;					      \
-		      }							      \
+									      \
+		    while (str2 != NULL && str2 < strend)		      \
+		      if (__mbsnrtowcs (ignore, &str2, strend - str2,	      \
+					ignore_size, &ps) == (size_t) -1)     \
+			{						      \
+			  done = -1;					      \
+			  goto all_done;				      \
+			}						      \
+									      \
 		    if (str2 == NULL)					      \
 		      len = strlen (string);				      \
 		    else						      \
@@ -1283,7 +1315,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
   /* Process whole format string.  */
   do
     {
-#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined SHARED
+#ifdef SHARED
 # define REF(Name) &&do_##Name - &&do_form_unknown
 #else
 # define REF(Name) &&do_##Name
@@ -1594,6 +1626,8 @@ do_positional:
     /* Just a counter.  */
     size_t cnt;
 
+    free (workstart);
+    workstart = NULL;
 
     if (grouping == (const char *) -1)
       {
@@ -1704,7 +1738,15 @@ do_positional:
 	T (PA_INT|PA_FLAG_LONG_LONG, pa_long_long_int, long long int);
 	T (PA_FLOAT, pa_double, double);	/* Promoted.  */
 	T (PA_DOUBLE, pa_double, double);
-	T (PA_DOUBLE|PA_FLAG_LONG_DOUBLE, pa_long_double, long double);
+	case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:
+	  if (__ldbl_is_dbl)
+	    {
+	      args_value[cnt].pa_double = va_arg (ap_save, double);
+	      args_type[cnt] &= ~PA_FLAG_LONG_DOUBLE;
+	    }
+	  else
+	    args_value[cnt].pa_long_double = va_arg (ap_save, long double);
+	  break;
 	T (PA_STRING, pa_string, const char *);
 	T (PA_WSTRING, pa_wstring, const wchar_t *);
 	T (PA_POINTER, pa_pointer, void *);
@@ -1726,7 +1768,7 @@ do_positional:
     for (; (size_t) nspecs_done < nspecs; ++nspecs_done)
       {
 #undef REF
-#if defined HAVE_SUBTRACT_LOCAL_LABELS && defined SHARED
+#ifdef SHARED
 # define REF(Name) &&do2_##Name - &&do_form_unknown
 #else
 # define REF(Name) &&do2_##Name
@@ -1760,7 +1802,9 @@ do_positional:
 	int use_outdigits = specs[nspecs_done].info.i18n;
 	char pad = specs[nspecs_done].info.pad;
 	CHAR_T spec = specs[nspecs_done].info.spec;
-	CHAR_T *workstart = NULL;
+
+	workstart = NULL;
+	workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
 
 	/* Fill in last information.  */
 	if (specs[nspecs_done].width_arg != -1)
@@ -1856,8 +1900,7 @@ do_positional:
 	    break;
 	  }
 
-	if (__builtin_expect (workstart != NULL, 0))
-	  free (workstart);
+	free (workstart);
 	workstart = NULL;
 
 	/* Write the following constant string.  */
@@ -1885,7 +1928,7 @@ printf_unknown (FILE *s, const struct printf_info *info,
 
 {
   int done = 0;
-  CHAR_T work_buffer[MAX (info->width, info->spec) + 32];
+  CHAR_T work_buffer[MAX (sizeof (info->width), sizeof (info->prec)) * 3];
   CHAR_T *const workend
     = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
   register CHAR_T *w;
@@ -2154,25 +2197,11 @@ buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format,
 }
 
 #undef vfprintf
-#ifdef strong_alias
-/* This is for glibc.  */
-# ifdef COMPILE_WPRINTF
+#ifdef COMPILE_WPRINTF
 strong_alias (_IO_vfwprintf, __vfwprintf);
-weak_alias (_IO_vfwprintf, vfwprintf);
-# else
-strong_alias (_IO_vfprintf, vfprintf);
-libc_hidden_def (vfprintf)
-INTDEF(_IO_vfprintf)
-# endif
+ldbl_weak_alias (_IO_vfwprintf, vfwprintf);
 #else
-# if defined __ELF__ || defined __GNU_LIBRARY__
-#  include <gnu-stabs.h>
-#  ifdef weak_alias
-#   ifdef COMPILE_WPRINTF
-weak_alias (_IO_vfwprintf, vfwprintf);
-#   else
-weak_alias (_IO_vfprintf, vfprintf);
-#   endif
-#  endif
-# endif
+ldbl_strong_alias (_IO_vfprintf_internal, vfprintf);
+ldbl_hidden_def (_IO_vfprintf_internal, vfprintf)
+ldbl_strong_alias (_IO_vfprintf_internal, _IO_vfprintf);
 #endif
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
index c641d2d371..6671602291 100644
--- a/stdio-common/vfscanf.c
+++ b/stdio-common/vfscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2006, 2007 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
@@ -144,11 +144,6 @@
 			  if (done == 0) done = EOF;			      \
 			  goto errout;					      \
 			} while (0)
-#define memory_error() do {						      \
-			  __set_errno (ENOMEM);				      \
-			  done = EOF;					      \
-			  goto errout;					      \
-			} while (0)
 #define ARGCHECK(s, format)						      \
   do									      \
     {									      \
@@ -178,18 +173,12 @@
    Return the number of assignments made, or -1 for an input error.  */
 #ifdef COMPILE_WSCANF
 int
-_IO_vfwscanf (s, format, argptr, errp)
-     _IO_FILE *s;
-     const wchar_t *format;
-     _IO_va_list argptr;
-     int *errp;
+_IO_vfwscanf (_IO_FILE *s, const wchar_t *format, _IO_va_list argptr,
+	      int *errp)
 #else
 int
-_IO_vfscanf (s, format, argptr, errp)
-     _IO_FILE *s;
-     const char *format;
-     _IO_va_list argptr;
-     int *errp;
+_IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+		      int *errp)
 #endif
 {
   va_list arg;
@@ -360,7 +349,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	      do
 		{
 		  c = inchar ();
-		  if (c == EOF)
+		  if (__builtin_expect (c == EOF, 0))
 		    input_error ();
 		  else if (c != (unsigned char) *f++)
 		    {
@@ -388,7 +377,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	  c = inchar ();
 
 	  /* Characters other than format specs must just match.  */
-	  if (c == EOF)
+	  if (__builtin_expect (c == EOF, 0))
 	    input_error ();
 
 	  /* We saw white space char as the last character in the format
@@ -396,12 +385,12 @@ _IO_vfscanf (s, format, argptr, errp)
 	  if (skip_space)
 	    {
 	      while (ISSPACE (c))
-		if (inchar () == EOF)
+		if (__builtin_expect (inchar () == EOF, 0))
 		  input_error ();
 	      skip_space = 0;
 	    }
 
-	  if (c != fc)
+	  if (__builtin_expect (c != fc, 0))
 	    {
 	      ungetc (c, s);
 	      conv_error ();
@@ -537,7 +526,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	}
 
       /* End of the format string?  */
-      if (*f == L_('\0'))
+      if (__builtin_expect (*f == L_('\0'), 0))
 	conv_error ();
 
       /* Find the conversion specifier.  */
@@ -549,7 +538,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	  int save_errno = errno;
 	  errno = 0;
 	  do
-	    if (inchar () == EOF && errno == EINTR)
+	    if (__builtin_expect (inchar () == EOF && errno == EINTR, 0))
 	      input_error ();
 	  while (ISSPACE (c));
 	  errno = save_errno;
@@ -561,9 +550,9 @@ _IO_vfscanf (s, format, argptr, errp)
 	{
 	case L_('%'):	/* Must match a literal '%'.  */
 	  c = inchar ();
-	  if (c == EOF)
+	  if (__builtin_expect (c == EOF, 0))
 	    input_error ();
-	  if (c != fc)
+	  if (__builtin_expect (c != fc, 0))
 	    {
 	      ungetc_not_eof (c, s);
 	      conv_error ();
@@ -629,7 +618,7 @@ _IO_vfscanf (s, format, argptr, errp)
 		}
 
 	      c = inchar ();
-	      if (c == EOF)
+	      if (__builtin_expect (c == EOF, 0))
 		input_error ();
 
 	      if (width == -1)
@@ -645,7 +634,7 @@ _IO_vfscanf (s, format, argptr, errp)
 		  size_t n;
 
 		  n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
-		  if (n == (size_t) -1)
+		  if (__builtin_expect (n == (size_t) -1, 0))
 		    /* No valid wide character.  */
 		    input_error ();
 
@@ -680,7 +669,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	    }
 
 	  c = inchar ();
-	  if (c == EOF)
+	  if (__builtin_expect (c == EOF, 0))
 	    input_error ();
 
 #ifdef COMPILE_WSCANF
@@ -718,14 +707,14 @@ _IO_vfscanf (s, format, argptr, errp)
 		      {
 			/* Possibly correct character, just not enough
 			   input.  */
-			if (inchar () == EOF)
+			if (__builtin_expect (inchar () == EOF, 0))
 			  encode_error ();
 
 			buf[0] = c;
 			continue;
 		      }
 
-		    if (n != 1)
+		    if (__builtin_expect (n != 1, 0))
 		      encode_error ();
 
 		    /* We have a match.  */
@@ -769,7 +758,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	      STRING_ARG (str, char);
 
 	      c = inchar ();
-	      if (c == EOF)
+	      if (__builtin_expect (c == EOF, 0))
 		input_error ();
 
 #ifdef COMPILE_WSCANF
@@ -832,7 +821,7 @@ _IO_vfscanf (s, format, argptr, errp)
 
 		    n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
 				   &state);
-		    if (n == (size_t) -1)
+		    if (__builtin_expect (n == (size_t) -1, 0))
 		      encode_error ();
 
 		    assert (n <= MB_CUR_MAX);
@@ -940,7 +929,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	    STRING_ARG (wstr, wchar_t);
 
 	    c = inchar ();
-	    if (c == EOF)
+	    if (__builtin_expect (c == EOF,  0))
 	      input_error ();
 
 #ifndef COMPILE_WSCANF
@@ -1015,14 +1004,14 @@ _IO_vfscanf (s, format, argptr, errp)
 			{
 			  /* Possibly correct character, just not enough
 			     input.  */
-			  if (inchar () == EOF)
+			  if (__builtin_expect (inchar () == EOF, 0))
 			    encode_error ();
 
 			  buf[0] = c;
 			  continue;
 			}
 
-		      if (n != 1)
+		      if (__builtin_expect (n != 1, 0))
 			encode_error ();
 
 		      /* We have a match.  */
@@ -1117,7 +1106,7 @@ _IO_vfscanf (s, format, argptr, errp)
 
 	number:
 	  c = inchar ();
-	  if (c == EOF)
+	  if (__builtin_expect (c == EOF, 0))
 	    input_error ();
 
 	  /* Check for a sign.  */
@@ -1156,7 +1145,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	  if (base == 0)
 	    base = 10;
 
-	  if (base == 10 && (flags & I18N) != 0)
+	  if (base == 10 && __builtin_expect ((flags & I18N) != 0, 0))
 	    {
 	      int from_level;
 	      int to_level;
@@ -1516,12 +1505,14 @@ _IO_vfscanf (s, format, argptr, errp)
 	    {
 	      /* There was no number.  If we are supposed to read a pointer
 		 we must recognize "(nil)" as well.  */
-	      if (wpsize == 0 && read_pointer && (width < 0 || width >= 0)
-		  && c == '('
-		  && TOLOWER (inchar ()) == L_('n')
-		  && TOLOWER (inchar ()) == L_('i')
-		  && TOLOWER (inchar ()) == L_('l')
-		  && inchar () == L_(')'))
+	      if (__builtin_expect (wpsize == 0
+				    && read_pointer
+				    && (width < 0 || width >= 0)
+				    && c == '('
+				    && TOLOWER (inchar ()) == L_('n')
+				    && TOLOWER (inchar ()) == L_('i')
+				    && TOLOWER (inchar ()) == L_('l')
+				    && inchar () == L_(')'), 1))
 		/* We must produce the value of a NULL pointer.  A single
 		   '0' digit is enough.  */
 		ADDW (L_('0'));
@@ -1554,7 +1545,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	      else
 		num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
 	    }
-	  if (wp == tw)
+	  if (__builtin_expect (wp == tw, 0))
 	    conv_error ();
 
 	  if (!(flags & SUPPRESS))
@@ -1599,21 +1590,23 @@ _IO_vfscanf (s, format, argptr, errp)
 	case L_('a'):
 	case L_('A'):
 	  c = inchar ();
-	  if (c == EOF)
+	  if (__builtin_expect (c == EOF, 0))
 	    input_error ();
 
+	  got_dot = got_e = 0;
+
 	  /* Check for a sign.  */
 	  if (c == L_('-') || c == L_('+'))
 	    {
 	      negative = c == L_('-');
-	      if (width == 0 || inchar () == EOF)
+	      if (__builtin_expect (width == 0 || inchar () == EOF, 0))
 		/* EOF is only an input error before we read any chars.  */
 		conv_error ();
 	      if (! ISDIGIT (c) && TOLOWER (c) != L_('i')
 		  && TOLOWER (c) != L_('n'))
 		{
 #ifdef COMPILE_WSCANF
-		  if (c != decimal)
+		  if (__builtin_expect (c != decimal, 0))
 		    {
 		      /* This is no valid number.  */
 		      ungetc (c, s);
@@ -1629,17 +1622,16 @@ _IO_vfscanf (s, format, argptr, errp)
 		  const char *cmpp = decimal;
 		  int avail = width > 0 ? width : INT_MAX;
 
-		  while ((unsigned char) *cmpp == c && avail > 0)
+		  while ((unsigned char) *cmpp == c && avail-- > 0)
 		    if (*++cmpp == '\0')
 		      break;
 		    else
 		      {
 			if (inchar () == EOF)
 			  break;
-			--avail;
 		      }
 
-		  if (*cmpp != '\0')
+		  if (__builtin_expect (*cmpp != '\0', 0))
 		    {
 		      /* This is no valid number.  */
 		      while (1)
@@ -1652,6 +1644,17 @@ _IO_vfscanf (s, format, argptr, errp)
 
 		      conv_error ();
 		    }
+		  else
+		    {
+                     /* Add all the characters.  */
+                     for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
+                       ADDW ((unsigned char) *cmpp);
+                     if (width > 0)
+                       width = avail;
+                     got_dot = 1;
+
+		      c = inchar ();
+		    }
 		  if (width > 0)
 		    width = avail;
 #endif
@@ -1667,12 +1670,16 @@ _IO_vfscanf (s, format, argptr, errp)
 	    {
 	      /* Maybe "nan".  */
 	      ADDW (c);
-	      if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('a'))
+	      if (__builtin_expect (width == 0
+				    || inchar () == EOF
+				    || TOLOWER (c) != L_('a'), 0))
 		conv_error ();
 	      if (width > 0)
 		--width;
 	      ADDW (c);
-	      if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
+	      if (__builtin_expect (width == 0
+				    || inchar () == EOF
+				    || TOLOWER (c) != L_('n'), 0))
 		conv_error ();
 	      if (width > 0)
 		--width;
@@ -1684,12 +1691,16 @@ _IO_vfscanf (s, format, argptr, errp)
 	    {
 	      /* Maybe "inf" or "infinity".  */
 	      ADDW (c);
-	      if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
+	      if (__builtin_expect (width == 0
+				    || inchar () == EOF
+				    || TOLOWER (c) != L_('n'), 0))
 		conv_error ();
 	      if (width > 0)
 		--width;
 	      ADDW (c);
-	      if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('f'))
+	      if (__builtin_expect (width == 0
+				    || inchar () == EOF
+				    || TOLOWER (c) != L_('f'), 0))
 		conv_error ();
 	      if (width > 0)
 		--width;
@@ -1703,26 +1714,30 @@ _IO_vfscanf (s, format, argptr, errp)
 			--width;
 		      /* Now we have to read the rest as well.  */
 		      ADDW (c);
-		      if (width == 0 || inchar () == EOF
-			  || TOLOWER (c) != L_('n'))
+		      if (__builtin_expect (width == 0
+					    || inchar () == EOF
+					    || TOLOWER (c) != L_('n'), 0))
 			conv_error ();
 		      if (width > 0)
 			--width;
 		      ADDW (c);
-		      if (width == 0 || inchar () == EOF
-			  || TOLOWER (c) != L_('i'))
+		      if (__builtin_expect (width == 0
+					    || inchar () == EOF
+					    || TOLOWER (c) != L_('i'), 0))
 			conv_error ();
 		      if (width > 0)
 			--width;
 		      ADDW (c);
-		      if (width == 0 || inchar () == EOF
-			  || TOLOWER (c) != L_('t'))
+		      if (__builtin_expect (width == 0
+					    || inchar () == EOF
+					    || TOLOWER (c) != L_('t'), 0))
 			conv_error ();
 		      if (width > 0)
 			--width;
 		      ADDW (c);
-		      if (width == 0 || inchar () == EOF
-			  || TOLOWER (c) != L_('y'))
+		      if (__builtin_expect (width == 0
+					    || inchar () == EOF
+					    || TOLOWER (c) != L_('y'), 0))
 			conv_error ();
 		      if (width > 0)
 			--width;
@@ -1759,7 +1774,6 @@ _IO_vfscanf (s, format, argptr, errp)
 		}
 	    }
 
-	  got_dot = got_e = 0;
 	  do
 	    {
 	      if (ISDIGIT (c))
@@ -1873,20 +1887,20 @@ _IO_vfscanf (s, format, argptr, errp)
 
 	  /* Have we read any character?  If we try to read a number
 	     in hexadecimal notation and we have read only the `0x'
-	     prefix or no exponent this is an error.  */
-	  if (wpsize == 0 || (is_hexa && (wpsize == 2 || ! got_e)))
+	     prefix this is an error.  */
+	  if (__builtin_expect (wpsize == 0 || (is_hexa && wpsize == 2), 0))
 	    conv_error ();
 
 	scan_float:
 	  /* Convert the number.  */
 	  ADDW (L_('\0'));
-	  if (flags & LONGDBL)
+	  if ((flags & LONGDBL) && !__ldbl_is_dbl)
 	    {
 	      long double d = __strtold_internal (wp, &tw, flags & GROUP);
 	      if (!(flags & SUPPRESS) && tw != wp)
 		*ARG (long double *) = negative ? -d : d;
 	    }
-	  else if (flags & LONG)
+	  else if (flags & (LONG | LONGDBL))
 	    {
 	      double d = __strtod_internal (wp, &tw, flags & GROUP);
 	      if (!(flags & SUPPRESS) && tw != wp)
@@ -1899,7 +1913,7 @@ _IO_vfscanf (s, format, argptr, errp)
 		*ARG (float *) = negative ? -d : d;
 	    }
 
-	  if (tw == wp)
+	  if (__builtin_expect (tw == wp, 0))
 	    conv_error ();
 
 	  if (!(flags & SUPPRESS))
@@ -1939,7 +1953,7 @@ _IO_vfscanf (s, format, argptr, errp)
 
 	  while ((fc = *f++) != L'\0' && fc != L']');
 
-	  if (fc == L'\0')
+	  if (__builtin_expect (fc == L'\0', 0))
 	    conv_error ();
 	  wp = (wchar_t *) f - 1;
 #else
@@ -1975,7 +1989,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	      /* Add the character to the flag map.  */
 	      wp[fc] = 1;
 
-	  if (fc == '\0')
+	  if (__builtin_expect (fc == '\0', 0))
 	    conv_error();
 #endif
 
@@ -1983,7 +1997,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	    {
 	      size_t now = read_in;
 #ifdef COMPILE_WSCANF
-	      if (inchar () == WEOF)
+	      if (__builtin_expect (inchar () == WEOF, 0))
 		input_error ();
 
 	      do
@@ -2088,7 +2102,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	      size_t cnt = 0;
 	      mbstate_t cstate;
 
-	      if (inchar () == EOF)
+	      if (__builtin_expect (inchar () == EOF, 0))
 		input_error ();
 
 	      memset (&cstate, '\0', sizeof (cstate));
@@ -2165,13 +2179,13 @@ _IO_vfscanf (s, format, argptr, errp)
 		}
 	      while (inchar () != EOF);
 
-	      if (cnt != 0)
+	      if (__builtin_expect (cnt != 0, 0))
 		/* We stopped in the middle of recognizing another
 		   character.  That's a problem.  */
 		encode_error ();
 #endif
 
-	      if (now == read_in)
+	      if (__builtin_expect (now == read_in, 0))
 		/* We haven't succesfully read any character.  */
 		conv_error ();
 
@@ -2196,7 +2210,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	    {
 	      size_t now = read_in;
 
-	      if (inchar () == EOF)
+	      if (__builtin_expect (inchar () == EOF, 0))
 		input_error ();
 
 #ifdef COMPILE_WSCANF
@@ -2298,7 +2312,7 @@ _IO_vfscanf (s, format, argptr, errp)
 		    }
 
 		  n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
-		  if (n == (size_t) -1)
+		  if (__builtin_expect (n == (size_t) -1, 0))
 		    encode_error ();
 
 		  assert (n <= MB_CUR_MAX);
@@ -2355,7 +2369,7 @@ _IO_vfscanf (s, format, argptr, errp)
 	      while (--width > 0 && inchar () != EOF);
 #endif
 
-	      if (now == read_in)
+	      if (__builtin_expect (now == read_in, 0))
 		/* We haven't succesfully read any character.  */
 		conv_error ();
 
@@ -2449,18 +2463,15 @@ __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
 {
   return _IO_vfwscanf (s, format, argptr, NULL);
 }
+ldbl_weak_alias (__vfwscanf, vfwscanf)
 #else
 int
-__vfscanf (FILE *s, const char *format, va_list argptr)
+___vfscanf (FILE *s, const char *format, va_list argptr)
 {
-  return INTUSE(_IO_vfscanf) (s, format, argptr, NULL);
+  return _IO_vfscanf_internal (s, format, argptr, NULL);
 }
-libc_hidden_def (__vfscanf)
-#endif
-
-#ifdef COMPILE_WSCANF
-weak_alias (__vfwscanf, vfwscanf)
-#else
-weak_alias (__vfscanf, vfscanf)
-INTDEF(_IO_vfscanf)
+ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf)
+ldbl_strong_alias (___vfscanf, __vfscanf)
+ldbl_hidden_def (___vfscanf, __vfscanf)
+ldbl_weak_alias (___vfscanf, vfscanf)
 #endif
diff --git a/stdio-common/vprintf.c b/stdio-common/vprintf.c
index a8c4a53cd8..5c9cac494a 100644
--- a/stdio-common/vprintf.c
+++ b/stdio-common/vprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993, 1995, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1995, 1997, 2006 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
@@ -19,15 +19,16 @@
 #include <stdarg.h>
 #undef	__OPTIMIZE__	/* Avoid inline `vprintf' function.  */
 #include <stdio.h>
+#include <libioP.h>
 
 #undef	vprintf
 
 /* Write formatted output to stdout according to the
    format string FORMAT, using the argument list in ARG.  */
 int
-vprintf (format, arg)
-     const char *format;
-     __gnuc_va_list arg;
+__vprintf (const char *format, __gnuc_va_list arg)
 {
   return vfprintf (stdout, format, arg);
 }
+
+ldbl_strong_alias (__vprintf, vprintf)