guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] GNU Guile branch, master, updated. release_1-9-0-41-gc4b


From: Ludovic Courtès
Subject: [Guile-commits] GNU Guile branch, master, updated. release_1-9-0-41-gc4b681f
Date: Sun, 05 Jul 2009 22:35:56 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=c4b681fdacc57de0b2a9584c1f6a195cf2629b32

The branch, master has been updated
       via  c4b681fdacc57de0b2a9584c1f6a195cf2629b32 (commit)
      from  5374ec9c281c2e77c283f60afd55e47d86e3b898 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c4b681fdacc57de0b2a9584c1f6a195cf2629b32
Author: Ludovic Courtès <address@hidden>
Date:   Sun Jul 5 23:57:37 2009 +0200

    Use Gnulib's `vsnprintf' module.
    
    * m4/gnulib-cache.m4: Use `vsnprintf', needed by `deprecation.c'.

-----------------------------------------------------------------------

Summary of changes:
 lib/Makefile.am                 |  191 ++-
 lib/{time_r.c => asnprintf.c}   |   38 +-
 lib/errno.in.h                  |  160 ++
 lib/float+.h                    |  148 ++
 lib/float.in.h                  |   62 +
 lib/{mbrlen.c => getpagesize.c} |   29 +-
 lib/memchr.c                    |  172 ++
 lib/memchr.valgrind             |   14 +
 lib/printf-args.c               |  187 ++
 lib/printf-args.h               |  154 ++
 lib/printf-parse.c              |  627 +++++
 lib/printf-parse.h              |  179 ++
 lib/size_max.h                  |   31 +
 lib/stdio-write.c               |  148 ++
 lib/stdio.in.h                  |  542 ++++
 lib/vasnprintf.c                | 5487 +++++++++++++++++++++++++++++++++++++++
 lib/vasnprintf.h                |   81 +
 lib/vsnprintf.c                 |   71 +
 lib/xsize.h                     |  108 +
 m4/errno_h.m4                   |  115 +
 m4/float_h.m4                   |   19 +
 m4/getpagesize.m4               |   29 +
 m4/gnulib-cache.m4              |    3 +-
 m4/gnulib-comp.m4               |   45 +
 m4/intmax_t.m4                  |   61 +
 m4/inttypes_h.m4                |   26 +
 m4/lib-link.m4                  |    7 +-
 m4/mbrtowc.m4                   |    3 +-
 m4/memchr.m4                    |   86 +
 m4/mmap-anon.m4                 |   59 +
 m4/printf.m4                    | 1416 ++++++++++
 m4/size_max.m4                  |   75 +
 m4/stdint_h.m4                  |   26 +
 m4/stdio_h.m4                   |  136 +
 m4/vasnprintf.m4                |  276 ++
 m4/vsnprintf.m4                 |   40 +
 m4/wchar_t.m4                   |   20 +
 m4/xsize.m4                     |   13 +
 38 files changed, 10843 insertions(+), 41 deletions(-)
 copy lib/{time_r.c => asnprintf.c} (57%)
 create mode 100644 lib/errno.in.h
 create mode 100644 lib/float+.h
 create mode 100644 lib/float.in.h
 copy lib/{mbrlen.c => getpagesize.c} (57%)
 create mode 100644 lib/memchr.c
 create mode 100644 lib/memchr.valgrind
 create mode 100644 lib/printf-args.c
 create mode 100644 lib/printf-args.h
 create mode 100644 lib/printf-parse.c
 create mode 100644 lib/printf-parse.h
 create mode 100644 lib/size_max.h
 create mode 100644 lib/stdio-write.c
 create mode 100644 lib/stdio.in.h
 create mode 100644 lib/vasnprintf.c
 create mode 100644 lib/vasnprintf.h
 create mode 100644 lib/vsnprintf.c
 create mode 100644 lib/xsize.h
 create mode 100644 m4/errno_h.m4
 create mode 100644 m4/float_h.m4
 create mode 100644 m4/getpagesize.m4
 create mode 100644 m4/intmax_t.m4
 create mode 100644 m4/inttypes_h.m4
 create mode 100644 m4/memchr.m4
 create mode 100644 m4/mmap-anon.m4
 create mode 100644 m4/printf.m4
 create mode 100644 m4/size_max.m4
 create mode 100644 m4/stdint_h.m4
 create mode 100644 m4/stdio_h.m4
 create mode 100644 m4/vasnprintf.m4
 create mode 100644 m4/vsnprintf.m4
 create mode 100644 m4/wchar_t.m4
 create mode 100644 m4/xsize.m4

diff --git a/lib/Makefile.am b/lib/Makefile.am
index f488fa1..197320e 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -9,7 +9,7 @@
 # the same distribution terms as the rest of that program.
 #
 # Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib 
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl 
--libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap 
canonicalize-lgpl count-one-bits environ extensions flock fpieee full-read 
full-write havelib iconv_open-utf lib-symbol-visibility libunistring putenv 
stdlib strcase strftime striconveh string
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib 
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl 
--libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap 
canonicalize-lgpl count-one-bits environ extensions flock fpieee full-read 
full-write havelib iconv_open-utf lib-symbol-visibility libunistring putenv 
stdlib strcase strftime striconveh string vsnprintf
 
 AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects
 
@@ -167,6 +167,54 @@ EXTRA_DIST += count-one-bits.h
 
 ## end   gnulib module count-one-bits
 
+## begin gnulib module errno
+
+BUILT_SOURCES += $(ERRNO_H)
+
+# We need the following in order to create <errno.h> when the system
+# doesn't have one that is POSIX compliant.
+errno.h: errno.in.h
+       rm -f address@hidden $@
+       { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+         sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+             -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+             -e 's|@''NEXT_ERRNO_H''@|$(NEXT_ERRNO_H)|g' \
+             -e 's|@''EMULTIHOP_HIDDEN''@|$(EMULTIHOP_HIDDEN)|g' \
+             -e 's|@''EMULTIHOP_VALUE''@|$(EMULTIHOP_VALUE)|g' \
+             -e 's|@''ENOLINK_HIDDEN''@|$(ENOLINK_HIDDEN)|g' \
+             -e 's|@''ENOLINK_VALUE''@|$(ENOLINK_VALUE)|g' \
+             -e 's|@''EOVERFLOW_HIDDEN''@|$(EOVERFLOW_HIDDEN)|g' \
+             -e 's|@''EOVERFLOW_VALUE''@|$(EOVERFLOW_VALUE)|g' \
+             < $(srcdir)/errno.in.h; \
+       } > address@hidden
+       mv address@hidden $@
+MOSTLYCLEANFILES += errno.h errno.h-t
+
+EXTRA_DIST += errno.in.h
+
+## end   gnulib module errno
+
+## begin gnulib module float
+
+BUILT_SOURCES += $(FLOAT_H)
+
+# We need the following in order to create <float.h> when the system
+# doesn't have one that works with the given compiler.
+float.h: float.in.h
+       rm -f address@hidden $@
+       { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+         sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+             -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+             -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \
+             < $(srcdir)/float.in.h; \
+       } > address@hidden
+       mv address@hidden $@
+MOSTLYCLEANFILES += float.h float.h-t
+
+EXTRA_DIST += float.in.h
+
+## end   gnulib module float
+
 ## begin gnulib module flock
 
 
@@ -188,6 +236,15 @@ libgnu_la_SOURCES += full-write.h full-write.c
 
 ## end   gnulib module full-write
 
+## begin gnulib module getpagesize
+
+
+EXTRA_DIST += getpagesize.c
+
+EXTRA_libgnu_la_SOURCES += getpagesize.c
+
+## end   gnulib module getpagesize
+
 ## begin gnulib module gperf
 
 GPERF = gperf
@@ -390,6 +447,15 @@ EXTRA_libgnu_la_SOURCES += mbsinit.c
 
 ## end   gnulib module mbsinit
 
+## begin gnulib module memchr
+
+
+EXTRA_DIST += memchr.c memchr.valgrind
+
+EXTRA_libgnu_la_SOURCES += memchr.c
+
+## end   gnulib module memchr
+
 ## begin gnulib module pathmax
 
 
@@ -433,6 +499,12 @@ EXTRA_libgnu_la_SOURCES += safe-write.c
 
 ## end   gnulib module safe-write
 
+## begin gnulib module size_max
+
+libgnu_la_SOURCES += size_max.h
+
+## end   gnulib module size_max
+
 ## begin gnulib module stdbool
 
 BUILT_SOURCES += $(STDBOOL_H)
@@ -493,6 +565,99 @@ EXTRA_DIST += stdint.in.h
 
 ## end   gnulib module stdint
 
+## begin gnulib module stdio
+
+BUILT_SOURCES += stdio.h
+
+# We need the following in order to create <stdio.h> when the system
+# doesn't have one that works with the given compiler.
+stdio.h: stdio.in.h
+       rm -f address@hidden $@
+       { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+         sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+             -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+             -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \
+             -e 's|@''GNULIB_FPRINTF''@|$(GNULIB_FPRINTF)|g' \
+             -e 's|@''GNULIB_FPRINTF_POSIX''@|$(GNULIB_FPRINTF_POSIX)|g' \
+             -e 's|@''GNULIB_PRINTF''@|$(GNULIB_PRINTF)|g' \
+             -e 's|@''GNULIB_PRINTF_POSIX''@|$(GNULIB_PRINTF_POSIX)|g' \
+             -e 's|@''GNULIB_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \
+             -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|g' \
+             -e 's|@''GNULIB_VFPRINTF''@|$(GNULIB_VFPRINTF)|g' \
+             -e 's|@''GNULIB_VFPRINTF_POSIX''@|$(GNULIB_VFPRINTF_POSIX)|g' \
+             -e 's|@''GNULIB_VPRINTF''@|$(GNULIB_VPRINTF)|g' \
+             -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \
+             -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \
+             -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \
+             -e 's|@''GNULIB_DPRINTF''@|$(GNULIB_DPRINTF)|g' \
+             -e 's|@''GNULIB_VDPRINTF''@|$(GNULIB_VDPRINTF)|g' \
+             -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \
+             -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \
+             -e 
's|@''GNULIB_OBSTACK_PRINTF_POSIX''@|$(GNULIB_OBSTACK_PRINTF_POSIX)|g' \
+             -e 's|@''GNULIB_FOPEN''@|$(GNULIB_FOPEN)|g' \
+             -e 's|@''GNULIB_FREOPEN''@|$(GNULIB_FREOPEN)|g' \
+             -e 's|@''GNULIB_FSEEK''@|$(GNULIB_FSEEK)|g' \
+             -e 's|@''GNULIB_FSEEKO''@|$(GNULIB_FSEEKO)|g' \
+             -e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \
+             -e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \
+             -e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \
+             -e 's|@''GNULIB_FPURGE''@|$(GNULIB_FPURGE)|g' \
+             -e 's|@''GNULIB_FCLOSE''@|$(GNULIB_FCLOSE)|g' \
+             -e 's|@''GNULIB_FPUTC''@|$(GNULIB_FPUTC)|g' \
+             -e 's|@''GNULIB_PUTC''@|$(GNULIB_PUTC)|g' \
+             -e 's|@''GNULIB_PUTCHAR''@|$(GNULIB_PUTCHAR)|g' \
+             -e 's|@''GNULIB_FPUTS''@|$(GNULIB_FPUTS)|g' \
+             -e 's|@''GNULIB_PUTS''@|$(GNULIB_PUTS)|g' \
+             -e 's|@''GNULIB_FWRITE''@|$(GNULIB_FWRITE)|g' \
+             -e 's|@''GNULIB_GETDELIM''@|$(GNULIB_GETDELIM)|g' \
+             -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \
+             -e 's|@''GNULIB_PERROR''@|$(GNULIB_PERROR)|g' \
+             -e 's|@''GNULIB_STDIO_H_SIGPIPE''@|$(GNULIB_STDIO_H_SIGPIPE)|g' \
+             -e 
's|@''REPLACE_STDIO_WRITE_FUNCS''@|$(REPLACE_STDIO_WRITE_FUNCS)|g' \
+             -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \
+             -e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \
+             -e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \
+             -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \
+             -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \
+             -e 's|@''HAVE_DECL_SNPRINTF''@|$(HAVE_DECL_SNPRINTF)|g' \
+             -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \
+             -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \
+             -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \
+             -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \
+             -e 's|@''HAVE_DPRINTF''@|$(HAVE_DPRINTF)|g' \
+             -e 's|@''REPLACE_DPRINTF''@|$(REPLACE_DPRINTF)|g' \
+             -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \
+             -e 's|@''REPLACE_VDPRINTF''@|$(REPLACE_VDPRINTF)|g' \
+             -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \
+             -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \
+             -e 
's|@''HAVE_DECL_OBSTACK_PRINTF''@|$(HAVE_DECL_OBSTACK_PRINTF)|g' \
+             -e 's|@''REPLACE_OBSTACK_PRINTF''@|$(REPLACE_OBSTACK_PRINTF)|g' \
+             -e 's|@''REPLACE_FOPEN''@|$(REPLACE_FOPEN)|g' \
+             -e 's|@''REPLACE_FREOPEN''@|$(REPLACE_FREOPEN)|g' \
+             -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \
+             -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \
+             -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \
+             -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \
+             -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \
+             -e 's|@''REPLACE_FPURGE''@|$(REPLACE_FPURGE)|g' \
+             -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \
+             -e 's|@''REPLACE_FCLOSE''@|$(REPLACE_FCLOSE)|g' \
+             -e 's|@''HAVE_DECL_GETDELIM''@|$(HAVE_DECL_GETDELIM)|g' \
+             -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \
+             -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \
+             -e 's|@''REPLACE_PERROR''@|$(REPLACE_PERROR)|g' \
+             -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
+             < $(srcdir)/stdio.in.h; \
+       } > address@hidden
+       mv address@hidden $@
+MOSTLYCLEANFILES += stdio.h stdio.h-t
+
+EXTRA_DIST += stdio-write.c stdio.in.h
+
+EXTRA_libgnu_la_SOURCES += stdio-write.c
+
+## end   gnulib module stdio
+
 ## begin gnulib module stdlib
 
 BUILT_SOURCES += stdlib.h
@@ -868,12 +1033,30 @@ EXTRA_DIST += unitypes.h
 
 ## end   gnulib module unitypes
 
+## begin gnulib module vasnprintf
+
+
+EXTRA_DIST += asnprintf.c float+.h printf-args.c printf-args.h printf-parse.c 
printf-parse.h vasnprintf.c vasnprintf.h
+
+EXTRA_libgnu_la_SOURCES += asnprintf.c printf-args.c printf-parse.c 
vasnprintf.c
+
+## end   gnulib module vasnprintf
+
 ## begin gnulib module verify
 
 libgnu_la_SOURCES += verify.h
 
 ## end   gnulib module verify
 
+## begin gnulib module vsnprintf
+
+
+EXTRA_DIST += vsnprintf.c
+
+EXTRA_libgnu_la_SOURCES += vsnprintf.c
+
+## end   gnulib module vsnprintf
+
 ## begin gnulib module wchar
 
 BUILT_SOURCES += $(WCHAR_H)
@@ -941,6 +1124,12 @@ EXTRA_libgnu_la_SOURCES += write.c
 
 ## end   gnulib module write
 
+## begin gnulib module xsize
+
+libgnu_la_SOURCES += xsize.h
+
+## end   gnulib module xsize
+
 
 mostlyclean-local: mostlyclean-generic
        @for dir in '' $(MOSTLYCLEANDIRS); do \
diff --git a/lib/time_r.c b/lib/asnprintf.c
similarity index 57%
copy from lib/time_r.c
copy to lib/asnprintf.c
index 90dcf00..3b374a2 100644
--- a/lib/time_r.c
+++ b/lib/asnprintf.c
@@ -1,6 +1,5 @@
-/* Reentrant time functions like localtime_r.
-
-   Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
+/* Formatted output to strings.
+   Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
@@ -16,32 +15,21 @@
    with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-/* Written by Paul Eggert.  */
-
 #include <config.h>
 
-#include <time.h>
-
-#include <string.h>
-
-static struct tm *
-copy_tm_result (struct tm *dest, struct tm const *src)
-{
-  if (! src)
-    return 0;
-  *dest = *src;
-  return dest;
-}
+/* Specification.  */
+#include "vasnprintf.h"
 
+#include <stdarg.h>
 
-struct tm *
-gmtime_r (time_t const * restrict t, struct tm * restrict tp)
+char *
+asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
 {
-  return copy_tm_result (tp, gmtime (t));
-}
+  va_list args;
+  char *result;
 
-struct tm *
-localtime_r (time_t const * restrict t, struct tm * restrict tp)
-{
-  return copy_tm_result (tp, localtime (t));
+  va_start (args, format);
+  result = vasnprintf (resultbuf, lengthp, format, args);
+  va_end (args);
+  return result;
 }
diff --git a/lib/errno.in.h b/lib/errno.in.h
new file mode 100644
index 0000000..a9b81d5
--- /dev/null
+++ b/lib/errno.in.h
@@ -0,0 +1,160 @@
+/* A POSIX-like <errno.h>.
+
+   Copyright (C) 2008-2009 Free Software Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _GL_ERRNO_H
+
+#if __GNUC__ >= 3
address@hidden@
+#endif
+
+/* The include_next requires a split double-inclusion guard.  */
address@hidden@ @NEXT_ERRNO_H@
+
+#ifndef _GL_ERRNO_H
+#define _GL_ERRNO_H
+
+
+/* On native Windows platforms, many macros are not defined.  */
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+/* POSIX says that EAGAIN and EWOULDBLOCK may have the same value.  */
+#  define EWOULDBLOCK     EAGAIN
+
+/* Values >= 100 seem safe to use.  */
+#  define ETXTBSY   100
+#  define GNULIB_defined_ETXTBSY 1
+
+/* These are intentionally the same values as the WSA* error numbers, defined
+   in <winsock2.h>.  */
+#  define EINPROGRESS     10036
+#  define EALREADY        10037
+#  define ENOTSOCK        10038
+#  define EDESTADDRREQ    10039
+#  define EMSGSIZE        10040
+#  define EPROTOTYPE      10041
+#  define ENOPROTOOPT     10042
+#  define EPROTONOSUPPORT 10043
+#  define ESOCKTNOSUPPORT 10044  /* not required by POSIX */
+#  define EOPNOTSUPP      10045
+#  define EPFNOSUPPORT    10046  /* not required by POSIX */
+#  define EAFNOSUPPORT    10047
+#  define EADDRINUSE      10048
+#  define EADDRNOTAVAIL   10049
+#  define ENETDOWN        10050
+#  define ENETUNREACH     10051
+#  define ENETRESET       10052
+#  define ECONNABORTED    10053
+#  define ECONNRESET      10054
+#  define ENOBUFS         10055
+#  define EISCONN         10056
+#  define ENOTCONN        10057
+#  define ESHUTDOWN       10058  /* not required by POSIX */
+#  define ETOOMANYREFS    10059  /* not required by POSIX */
+#  define ETIMEDOUT       10060
+#  define ECONNREFUSED    10061
+#  define ELOOP           10062
+#  define EHOSTDOWN       10064  /* not required by POSIX */
+#  define EHOSTUNREACH    10065
+#  define EPROCLIM        10067  /* not required by POSIX */
+#  define EUSERS          10068  /* not required by POSIX */
+#  define EDQUOT          10069
+#  define ESTALE          10070
+#  define EREMOTE         10071  /* not required by POSIX */
+#  define GNULIB_defined_ESOCK 1
+
+# endif
+
+
+/* On OSF/1 5.1, when _XOPEN_SOURCE_EXTENDED is not defined, the macros
+   EMULTIHOP, ENOLINK, EOVERFLOW are not defined.  */
+# if @EMULTIHOP_HIDDEN@
+#  define EMULTIHOP @EMULTIHOP_VALUE@
+#  define GNULIB_defined_EMULTIHOP 1
+# endif
+# if @ENOLINK_HIDDEN@
+#  define ENOLINK   @ENOLINK_VALUE@
+#  define GNULIB_defined_ENOLINK 1
+# endif
+# if @EOVERFLOW_HIDDEN@
+#  define EOVERFLOW @EOVERFLOW_VALUE@
+#  define GNULIB_defined_EOVERFLOW 1
+# endif
+
+
+/* On OpenBSD 4.0 and on native Windows, the macros ENOMSG, EIDRM, ENOLINK,
+   EPROTO, EMULTIHOP, EBADMSG, EOVERFLOW, ENOTSUP, ECANCELED are not defined.
+   Define them here.  Values >= 2000 seem safe to use: Solaris ESTALE = 151,
+   HP-UX EWOULDBLOCK = 246, IRIX EDQUOT = 1133.
+
+   Note: When one of these systems defines some of these macros some day,
+   binaries will have to be recompiled so that they recognizes the new
+   errno values from the system.  */
+
+# ifndef ENOMSG
+#  define ENOMSG    2000
+#  define GNULIB_defined_ENOMSG 1
+# endif
+
+# ifndef EIDRM
+#  define EIDRM     2001
+#  define GNULIB_defined_EIDRM 1
+# endif
+
+# ifndef ENOLINK
+#  define ENOLINK   2002
+#  define GNULIB_defined_ENOLINK 1
+# endif
+
+# ifndef EPROTO
+#  define EPROTO    2003
+#  define GNULIB_defined_EPROTO 1
+# endif
+
+# ifndef EMULTIHOP
+#  define EMULTIHOP 2004
+#  define GNULIB_defined_EMULTIHOP 1
+# endif
+
+# ifndef EBADMSG
+#  define EBADMSG   2005
+#  define GNULIB_defined_EBADMSG 1
+# endif
+
+# ifndef EOVERFLOW
+#  define EOVERFLOW 2006
+#  define GNULIB_defined_EOVERFLOW 1
+# endif
+
+# ifndef ENOTSUP
+#  define ENOTSUP   2007
+#  define GNULIB_defined_ENOTSUP 1
+# endif
+
+# ifndef ESTALE
+#  define ESTALE    2009
+#  define GNULIB_defined_ESTALE 1
+# endif
+
+# ifndef ECANCELED
+#  define ECANCELED 2008
+#  define GNULIB_defined_ECANCELED 1
+# endif
+
+
+#endif /* _GL_ERRNO_H */
+#endif /* _GL_ERRNO_H */
diff --git a/lib/float+.h b/lib/float+.h
new file mode 100644
index 0000000..2288e3d
--- /dev/null
+++ b/lib/float+.h
@@ -0,0 +1,148 @@
+/* Supplemental information about the floating-point formats.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   Written by Bruno Haible <address@hidden>, 2007.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _FLOATPLUS_H
+#define _FLOATPLUS_H
+
+#include <float.h>
+#include <limits.h>
+
+/* Number of bits in the mantissa of a floating-point number, including the
+   "hidden bit".  */
+#if FLT_RADIX == 2
+# define FLT_MANT_BIT FLT_MANT_DIG
+# define DBL_MANT_BIT DBL_MANT_DIG
+# define LDBL_MANT_BIT LDBL_MANT_DIG
+#elif FLT_RADIX == 4
+# define FLT_MANT_BIT (FLT_MANT_DIG * 2)
+# define DBL_MANT_BIT (DBL_MANT_DIG * 2)
+# define LDBL_MANT_BIT (LDBL_MANT_DIG * 2)
+#elif FLT_RADIX == 16
+# define FLT_MANT_BIT (FLT_MANT_DIG * 4)
+# define DBL_MANT_BIT (DBL_MANT_DIG * 4)
+# define LDBL_MANT_BIT (LDBL_MANT_DIG * 4)
+#endif
+
+/* Bit mask that can be used to mask the exponent, as an unsigned number.  */
+#define FLT_EXP_MASK ((FLT_MAX_EXP - FLT_MIN_EXP) | 7)
+#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
+#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7)
+
+/* Number of bits used for the exponent of a floating-point number, including
+   the exponent's sign.  */
+#define FLT_EXP_BIT \
+  (FLT_EXP_MASK < 0x100 ? 8 : \
+   FLT_EXP_MASK < 0x200 ? 9 : \
+   FLT_EXP_MASK < 0x400 ? 10 : \
+   FLT_EXP_MASK < 0x800 ? 11 : \
+   FLT_EXP_MASK < 0x1000 ? 12 : \
+   FLT_EXP_MASK < 0x2000 ? 13 : \
+   FLT_EXP_MASK < 0x4000 ? 14 : \
+   FLT_EXP_MASK < 0x8000 ? 15 : \
+   FLT_EXP_MASK < 0x10000 ? 16 : \
+   FLT_EXP_MASK < 0x20000 ? 17 : \
+   FLT_EXP_MASK < 0x40000 ? 18 : \
+   FLT_EXP_MASK < 0x80000 ? 19 : \
+   FLT_EXP_MASK < 0x100000 ? 20 : \
+   FLT_EXP_MASK < 0x200000 ? 21 : \
+   FLT_EXP_MASK < 0x400000 ? 22 : \
+   FLT_EXP_MASK < 0x800000 ? 23 : \
+   FLT_EXP_MASK < 0x1000000 ? 24 : \
+   FLT_EXP_MASK < 0x2000000 ? 25 : \
+   FLT_EXP_MASK < 0x4000000 ? 26 : \
+   FLT_EXP_MASK < 0x8000000 ? 27 : \
+   FLT_EXP_MASK < 0x10000000 ? 28 : \
+   FLT_EXP_MASK < 0x20000000 ? 29 : \
+   FLT_EXP_MASK < 0x40000000 ? 30 : \
+   FLT_EXP_MASK <= 0x7fffffff ? 31 : \
+   32)
+#define DBL_EXP_BIT \
+  (DBL_EXP_MASK < 0x100 ? 8 : \
+   DBL_EXP_MASK < 0x200 ? 9 : \
+   DBL_EXP_MASK < 0x400 ? 10 : \
+   DBL_EXP_MASK < 0x800 ? 11 : \
+   DBL_EXP_MASK < 0x1000 ? 12 : \
+   DBL_EXP_MASK < 0x2000 ? 13 : \
+   DBL_EXP_MASK < 0x4000 ? 14 : \
+   DBL_EXP_MASK < 0x8000 ? 15 : \
+   DBL_EXP_MASK < 0x10000 ? 16 : \
+   DBL_EXP_MASK < 0x20000 ? 17 : \
+   DBL_EXP_MASK < 0x40000 ? 18 : \
+   DBL_EXP_MASK < 0x80000 ? 19 : \
+   DBL_EXP_MASK < 0x100000 ? 20 : \
+   DBL_EXP_MASK < 0x200000 ? 21 : \
+   DBL_EXP_MASK < 0x400000 ? 22 : \
+   DBL_EXP_MASK < 0x800000 ? 23 : \
+   DBL_EXP_MASK < 0x1000000 ? 24 : \
+   DBL_EXP_MASK < 0x2000000 ? 25 : \
+   DBL_EXP_MASK < 0x4000000 ? 26 : \
+   DBL_EXP_MASK < 0x8000000 ? 27 : \
+   DBL_EXP_MASK < 0x10000000 ? 28 : \
+   DBL_EXP_MASK < 0x20000000 ? 29 : \
+   DBL_EXP_MASK < 0x40000000 ? 30 : \
+   DBL_EXP_MASK <= 0x7fffffff ? 31 : \
+   32)
+#define LDBL_EXP_BIT \
+  (LDBL_EXP_MASK < 0x100 ? 8 : \
+   LDBL_EXP_MASK < 0x200 ? 9 : \
+   LDBL_EXP_MASK < 0x400 ? 10 : \
+   LDBL_EXP_MASK < 0x800 ? 11 : \
+   LDBL_EXP_MASK < 0x1000 ? 12 : \
+   LDBL_EXP_MASK < 0x2000 ? 13 : \
+   LDBL_EXP_MASK < 0x4000 ? 14 : \
+   LDBL_EXP_MASK < 0x8000 ? 15 : \
+   LDBL_EXP_MASK < 0x10000 ? 16 : \
+   LDBL_EXP_MASK < 0x20000 ? 17 : \
+   LDBL_EXP_MASK < 0x40000 ? 18 : \
+   LDBL_EXP_MASK < 0x80000 ? 19 : \
+   LDBL_EXP_MASK < 0x100000 ? 20 : \
+   LDBL_EXP_MASK < 0x200000 ? 21 : \
+   LDBL_EXP_MASK < 0x400000 ? 22 : \
+   LDBL_EXP_MASK < 0x800000 ? 23 : \
+   LDBL_EXP_MASK < 0x1000000 ? 24 : \
+   LDBL_EXP_MASK < 0x2000000 ? 25 : \
+   LDBL_EXP_MASK < 0x4000000 ? 26 : \
+   LDBL_EXP_MASK < 0x8000000 ? 27 : \
+   LDBL_EXP_MASK < 0x10000000 ? 28 : \
+   LDBL_EXP_MASK < 0x20000000 ? 29 : \
+   LDBL_EXP_MASK < 0x40000000 ? 30 : \
+   LDBL_EXP_MASK <= 0x7fffffff ? 31 : \
+   32)
+
+/* Number of bits used for a floating-point number: the mantissa (not
+   counting the "hidden bit", since it may or may not be explicit), the
+   exponent, and the sign.  */
+#define FLT_TOTAL_BIT ((FLT_MANT_BIT - 1) + FLT_EXP_BIT + 1)
+#define DBL_TOTAL_BIT ((DBL_MANT_BIT - 1) + DBL_EXP_BIT + 1)
+#define LDBL_TOTAL_BIT ((LDBL_MANT_BIT - 1) + LDBL_EXP_BIT + 1)
+
+/* Number of bytes used for a floating-point number.
+   This can be smaller than the 'sizeof'.  For example, on i386 systems,
+   'long double' most often have LDBL_MANT_BIT = 64, LDBL_EXP_BIT = 16, hence
+   LDBL_TOTAL_BIT = 80 bits, i.e. 10 bytes of consecutive memory, but
+   sizeof (long double) = 12 or = 16.  */
+#define SIZEOF_FLT ((FLT_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
+#define SIZEOF_DBL ((DBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
+#define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
+
+/* Verify that SIZEOF_FLT <= sizeof (float) etc.  */
+typedef int verify_sizeof_flt[2 * (SIZEOF_FLT <= sizeof (float)) - 1];
+typedef int verify_sizeof_dbl[2 * (SIZEOF_DBL <= sizeof (double)) - 1];
+typedef int verify_sizeof_ldbl[2 * (SIZEOF_LDBL <= sizeof (long double)) - 1];
+
+#endif /* _FLOATPLUS_H */
diff --git a/lib/float.in.h b/lib/float.in.h
new file mode 100644
index 0000000..63d55f8
--- /dev/null
+++ b/lib/float.in.h
@@ -0,0 +1,62 @@
+/* A correct <float.h>.
+
+   Copyright (C) 2007-2008 Free Software Foundation, Inc.
+
+   This program 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 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_FLOAT_H
+
+#if __GNUC__ >= 3
address@hidden@
+#endif
+
+/* The include_next requires a split double-inclusion guard.  */
address@hidden@ @NEXT_FLOAT_H@
+
+#ifndef _GL_FLOAT_H
+#define _GL_FLOAT_H
+
+/* 'long double' properties.  */
+#if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__)
+/* Number of mantissa units, in base FLT_RADIX.  */
+# undef LDBL_MANT_DIG
+# define LDBL_MANT_DIG   64
+/* Number of decimal digits that is sufficient for representing a number.  */
+# undef LDBL_DIG
+# define LDBL_DIG        18
+/* x-1 where x is the smallest representable number > 1.  */
+# undef LDBL_EPSILON
+# define LDBL_EPSILON    1.0842021724855044340E-19L
+/* Minimum e such that FLT_RADIX^(e-1) is a normalized number.  */
+# undef LDBL_MIN_EXP
+# define LDBL_MIN_EXP    (-16381)
+/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number.  */
+# undef LDBL_MAX_EXP
+# define LDBL_MAX_EXP    16384
+/* Minimum positive normalized number.  */
+# undef LDBL_MIN
+# define LDBL_MIN        3.3621031431120935063E-4932L
+/* Maximum representable finite number.  */
+# undef LDBL_MAX
+# define LDBL_MAX        1.1897314953572317650E+4932L
+/* Minimum e such that 10^e is in the range of normalized numbers.  */
+# undef LDBL_MIN_10_EXP
+# define LDBL_MIN_10_EXP (-4931)
+/* Maximum e such that 10^e is in the range of representable finite numbers.  
*/
+# undef LDBL_MAX_10_EXP
+# define LDBL_MAX_10_EXP 4932
+#endif
+
+#endif /* _GL_FLOAT_H */
+#endif /* _GL_FLOAT_H */
diff --git a/lib/mbrlen.c b/lib/getpagesize.c
similarity index 57%
copy from lib/mbrlen.c
copy to lib/getpagesize.c
index 94c66d6..82238df 100644
--- a/lib/mbrlen.c
+++ b/lib/getpagesize.c
@@ -1,6 +1,6 @@
-/* Recognize multibyte character.
-   Copyright (C) 1999-2000, 2008 Free Software Foundation, Inc.
-   Written by Bruno Haible <address@hidden>, 2008.
+/* getpagesize emulation for systems where it cannot be done in a C macro.
+
+   Copyright (C) 2007 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
@@ -15,18 +15,25 @@
    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+/* Written by Bruno Haible and Martin Lambers.  */
+
 #include <config.h>
 
-/* Specification.  */
-#include <wchar.h>
+/* Specification. */
+#include <unistd.h>
 
+/* This implementation is only for native Win32 systems.  */
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
 
-static mbstate_t internal_state;
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
 
-size_t
-mbrlen (const char *s, size_t n, mbstate_t *ps)
+int
+getpagesize (void)
 {
-  if (ps == NULL)
-    ps = &internal_state;
-  return mbrtowc (NULL, s, n, ps);
+  SYSTEM_INFO system_info;
+  GetSystemInfo (&system_info);
+  return system_info.dwPageSize;
 }
+
+#endif
diff --git a/lib/memchr.c b/lib/memchr.c
new file mode 100644
index 0000000..3ea1d5b
--- /dev/null
+++ b/lib/memchr.c
@@ -0,0 +1,172 @@
+/* Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2006, 2008
+   Free Software Foundation, Inc.
+
+   Based on strlen implementation by Torbjorn Granlund (address@hidden),
+   with help from Dan Sahlin (address@hidden) and
+   commentary by Jim Blandy (address@hidden);
+   adaptation to memchr suggested by Dick Karpinski (address@hidden),
+   and implemented by Roland McGrath (address@hidden).
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to address@hidden
+
+This program 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 3 of the License, or any
+later version.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <stddef.h>
+
+#if defined _LIBC
+# include <memcopy.h>
+#else
+# define reg_char char
+#endif
+
+#include <limits.h>
+
+#if HAVE_BP_SYM_H || defined _LIBC
+# include <bp-sym.h>
+#else
+# define BP_SYM(sym) sym
+#endif
+
+#undef __memchr
+#ifdef _LIBC
+# undef memchr
+#endif
+
+#ifndef weak_alias
+# define __memchr memchr
+#endif
+
+/* Search no more than N bytes of S for C.  */
+void *
+__memchr (void const *s, int c_in, size_t n)
+{
+  /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
+     long instead of a 64-bit uintmax_t tends to give better
+     performance.  On 64-bit hardware, unsigned long is generally 64
+     bits already.  Change this typedef to experiment with
+     performance.  */
+  typedef unsigned long int longword;
+
+  const unsigned char *char_ptr;
+  const longword *longword_ptr;
+  longword repeated_one;
+  longword repeated_c;
+  unsigned reg_char c;
+
+  c = (unsigned char) c_in;
+
+  /* Handle the first few bytes by reading one byte at a time.
+     Do this until CHAR_PTR is aligned on a longword boundary.  */
+  for (char_ptr = (const unsigned char *) s;
+       n > 0 && (size_t) char_ptr % sizeof (longword) != 0;
+       --n, ++char_ptr)
+    if (*char_ptr == c)
+      return (void *) char_ptr;
+
+  longword_ptr = (const longword *) char_ptr;
+
+  /* All these elucidatory comments refer to 4-byte longwords,
+     but the theory applies equally well to any size longwords.  */
+
+  /* Compute auxiliary longword values:
+     repeated_one is a value which has a 1 in every byte.
+     repeated_c has c in every byte.  */
+  repeated_one = 0x01010101;
+  repeated_c = c | (c << 8);
+  repeated_c |= repeated_c << 16;
+  if (0xffffffffU < (longword) -1)
+    {
+      repeated_one |= repeated_one << 31 << 1;
+      repeated_c |= repeated_c << 31 << 1;
+      if (8 < sizeof (longword))
+       {
+         size_t i;
+
+         for (i = 64; i < sizeof (longword) * 8; i *= 2)
+           {
+             repeated_one |= repeated_one << i;
+             repeated_c |= repeated_c << i;
+           }
+       }
+    }
+
+  /* Instead of the traditional loop which tests each byte, we will test a
+     longword at a time.  The tricky part is testing if *any of the four*
+     bytes in the longword in question are equal to c.  We first use an xor
+     with repeated_c.  This reduces the task to testing whether *any of the
+     four* bytes in longword1 is zero.
+
+     We compute tmp =
+       ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
+     That is, we perform the following operations:
+       1. Subtract repeated_one.
+       2. & ~longword1.
+       3. & a mask consisting of 0x80 in every byte.
+     Consider what happens in each byte:
+       - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
+         and step 3 transforms it into 0x80.  A carry can also be propagated
+         to more significant bytes.
+       - If a byte of longword1 is nonzero, let its lowest 1 bit be at
+         position k (0 <= k <= 7); so the lowest k bits are 0.  After step 1,
+         the byte ends in a single bit of value 0 and k bits of value 1.
+         After step 2, the result is just k bits of value 1: 2^k - 1.  After
+         step 3, the result is 0.  And no carry is produced.
+     So, if longword1 has only non-zero bytes, tmp is zero.
+     Whereas if longword1 has a zero byte, call j the position of the least
+     significant zero byte.  Then the result has a zero at positions 0, ...,
+     j-1 and a 0x80 at position j.  We cannot predict the result at the more
+     significant bytes (positions j+1..3), but it does not matter since we
+     already have a non-zero bit at position 8*j+7.
+
+     So, the test whether any byte in longword1 is zero is equivalent to
+     testing whether tmp is nonzero.  */
+
+  while (n >= sizeof (longword))
+    {
+      longword longword1 = *longword_ptr ^ repeated_c;
+
+      if ((((longword1 - repeated_one) & ~longword1)
+          & (repeated_one << 7)) != 0)
+       break;
+      longword_ptr++;
+      n -= sizeof (longword);
+    }
+
+  char_ptr = (const unsigned char *) longword_ptr;
+
+  /* At this point, we know that either n < sizeof (longword), or one of the
+     sizeof (longword) bytes starting at char_ptr is == c.  On little-endian
+     machines, we could determine the first such byte without any further
+     memory accesses, just by looking at the tmp result from the last loop
+     iteration.  But this does not work on big-endian machines.  Choose code
+     that works in both cases.  */
+
+  for (; n > 0; --n, ++char_ptr)
+    {
+      if (*char_ptr == c)
+       return (void *) char_ptr;
+    }
+
+  return NULL;
+}
+#ifdef weak_alias
+weak_alias (__memchr, BP_SYM (memchr))
+#endif
diff --git a/lib/memchr.valgrind b/lib/memchr.valgrind
new file mode 100644
index 0000000..60f247e
--- /dev/null
+++ b/lib/memchr.valgrind
@@ -0,0 +1,14 @@
+# Suppress a valgrind message about use of uninitialized memory in memchr().
+# POSIX states that when the character is found, memchr must not read extra
+# bytes in an overestimated length (for example, where memchr is used to
+# implement strnlen).  However, we use a safe word read to provide a speedup.
+{
+    memchr-value4
+    Memcheck:Value4
+    fun:rpl_memchr
+}
+{
+    memchr-value8
+    Memcheck:Value8
+    fun:rpl_memchr
+}
diff --git a/lib/printf-args.c b/lib/printf-args.c
new file mode 100644
index 0000000..c31d204
--- /dev/null
+++ b/lib/printf-args.c
@@ -0,0 +1,187 @@
+/* Decomposed printf argument list.
+   Copyright (C) 1999, 2002-2003, 2005-2007 Free Software Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* This file can be parametrized with the following macros:
+     ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.
+     PRINTF_FETCHARGS   Name of the function to be defined.
+     STATIC             Set to 'static' to declare the function static.  */
+
+#ifndef PRINTF_FETCHARGS
+# include <config.h>
+#endif
+
+/* Specification.  */
+#ifndef PRINTF_FETCHARGS
+# include "printf-args.h"
+#endif
+
+#ifdef STATIC
+STATIC
+#endif
+int
+PRINTF_FETCHARGS (va_list args, arguments *a)
+{
+  size_t i;
+  argument *ap;
+
+  for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++)
+    switch (ap->type)
+      {
+      case TYPE_SCHAR:
+       ap->a.a_schar = va_arg (args, /*signed char*/ int);
+       break;
+      case TYPE_UCHAR:
+       ap->a.a_uchar = va_arg (args, /*unsigned char*/ int);
+       break;
+      case TYPE_SHORT:
+       ap->a.a_short = va_arg (args, /*short*/ int);
+       break;
+      case TYPE_USHORT:
+       ap->a.a_ushort = va_arg (args, /*unsigned short*/ int);
+       break;
+      case TYPE_INT:
+       ap->a.a_int = va_arg (args, int);
+       break;
+      case TYPE_UINT:
+       ap->a.a_uint = va_arg (args, unsigned int);
+       break;
+      case TYPE_LONGINT:
+       ap->a.a_longint = va_arg (args, long int);
+       break;
+      case TYPE_ULONGINT:
+       ap->a.a_ulongint = va_arg (args, unsigned long int);
+       break;
+#if HAVE_LONG_LONG_INT
+      case TYPE_LONGLONGINT:
+       ap->a.a_longlongint = va_arg (args, long long int);
+       break;
+      case TYPE_ULONGLONGINT:
+       ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
+       break;
+#endif
+      case TYPE_DOUBLE:
+       ap->a.a_double = va_arg (args, double);
+       break;
+      case TYPE_LONGDOUBLE:
+       ap->a.a_longdouble = va_arg (args, long double);
+       break;
+      case TYPE_CHAR:
+       ap->a.a_char = va_arg (args, int);
+       break;
+#if HAVE_WINT_T
+      case TYPE_WIDE_CHAR:
+       /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by
+          default argument promotions", this is not the case in mingw32,
+          where wint_t is 'unsigned short'.  */
+       ap->a.a_wide_char =
+         (sizeof (wint_t) < sizeof (int)
+          ? va_arg (args, int)
+          : va_arg (args, wint_t));
+       break;
+#endif
+      case TYPE_STRING:
+       ap->a.a_string = va_arg (args, const char *);
+       /* A null pointer is an invalid argument for "%s", but in practice
+          it occurs quite frequently in printf statements that produce
+          debug output.  Use a fallback in this case.  */
+       if (ap->a.a_string == NULL)
+         ap->a.a_string = "(NULL)";
+       break;
+#if HAVE_WCHAR_T
+      case TYPE_WIDE_STRING:
+       ap->a.a_wide_string = va_arg (args, const wchar_t *);
+       /* A null pointer is an invalid argument for "%ls", but in practice
+          it occurs quite frequently in printf statements that produce
+          debug output.  Use a fallback in this case.  */
+       if (ap->a.a_wide_string == NULL)
+         {
+           static const wchar_t wide_null_string[] =
+             {
+               (wchar_t)'(',
+               (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L',
+               (wchar_t)')',
+               (wchar_t)0
+             };
+           ap->a.a_wide_string = wide_null_string;
+         }
+       break;
+#endif
+      case TYPE_POINTER:
+       ap->a.a_pointer = va_arg (args, void *);
+       break;
+      case TYPE_COUNT_SCHAR_POINTER:
+       ap->a.a_count_schar_pointer = va_arg (args, signed char *);
+       break;
+      case TYPE_COUNT_SHORT_POINTER:
+       ap->a.a_count_short_pointer = va_arg (args, short *);
+       break;
+      case TYPE_COUNT_INT_POINTER:
+       ap->a.a_count_int_pointer = va_arg (args, int *);
+       break;
+      case TYPE_COUNT_LONGINT_POINTER:
+       ap->a.a_count_longint_pointer = va_arg (args, long int *);
+       break;
+#if HAVE_LONG_LONG_INT
+      case TYPE_COUNT_LONGLONGINT_POINTER:
+       ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
+       break;
+#endif
+#if ENABLE_UNISTDIO
+      /* The unistdio extensions.  */
+      case TYPE_U8_STRING:
+       ap->a.a_u8_string = va_arg (args, const uint8_t *);
+       /* A null pointer is an invalid argument for "%U", but in practice
+          it occurs quite frequently in printf statements that produce
+          debug output.  Use a fallback in this case.  */
+       if (ap->a.a_u8_string == NULL)
+         {
+           static const uint8_t u8_null_string[] =
+             { '(', 'N', 'U', 'L', 'L', ')', 0 };
+           ap->a.a_u8_string = u8_null_string;
+         }
+       break;
+      case TYPE_U16_STRING:
+       ap->a.a_u16_string = va_arg (args, const uint16_t *);
+       /* A null pointer is an invalid argument for "%lU", but in practice
+          it occurs quite frequently in printf statements that produce
+          debug output.  Use a fallback in this case.  */
+       if (ap->a.a_u16_string == NULL)
+         {
+           static const uint16_t u16_null_string[] =
+             { '(', 'N', 'U', 'L', 'L', ')', 0 };
+           ap->a.a_u16_string = u16_null_string;
+         }
+       break;
+      case TYPE_U32_STRING:
+       ap->a.a_u32_string = va_arg (args, const uint32_t *);
+       /* A null pointer is an invalid argument for "%llU", but in practice
+          it occurs quite frequently in printf statements that produce
+          debug output.  Use a fallback in this case.  */
+       if (ap->a.a_u32_string == NULL)
+         {
+           static const uint32_t u32_null_string[] =
+             { '(', 'N', 'U', 'L', 'L', ')', 0 };
+           ap->a.a_u32_string = u32_null_string;
+         }
+       break;
+#endif
+      default:
+       /* Unknown type.  */
+       return -1;
+      }
+  return 0;
+}
diff --git a/lib/printf-args.h b/lib/printf-args.h
new file mode 100644
index 0000000..4c68f11
--- /dev/null
+++ b/lib/printf-args.h
@@ -0,0 +1,154 @@
+/* Decomposed printf argument list.
+   Copyright (C) 1999, 2002-2003, 2006-2007 Free Software Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _PRINTF_ARGS_H
+#define _PRINTF_ARGS_H
+
+/* This file can be parametrized with the following macros:
+     ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.
+     PRINTF_FETCHARGS   Name of the function to be declared.
+     STATIC             Set to 'static' to declare the function static.  */
+
+/* Default parameters.  */
+#ifndef PRINTF_FETCHARGS
+# define PRINTF_FETCHARGS printf_fetchargs
+#endif
+
+/* Get size_t.  */
+#include <stddef.h>
+
+/* Get wchar_t.  */
+#if HAVE_WCHAR_T
+# include <stddef.h>
+#endif
+
+/* Get wint_t.  */
+#if HAVE_WINT_T
+# include <wchar.h>
+#endif
+
+/* Get va_list.  */
+#include <stdarg.h>
+
+
+/* Argument types */
+typedef enum
+{
+  TYPE_NONE,
+  TYPE_SCHAR,
+  TYPE_UCHAR,
+  TYPE_SHORT,
+  TYPE_USHORT,
+  TYPE_INT,
+  TYPE_UINT,
+  TYPE_LONGINT,
+  TYPE_ULONGINT,
+#if HAVE_LONG_LONG_INT
+  TYPE_LONGLONGINT,
+  TYPE_ULONGLONGINT,
+#endif
+  TYPE_DOUBLE,
+  TYPE_LONGDOUBLE,
+  TYPE_CHAR,
+#if HAVE_WINT_T
+  TYPE_WIDE_CHAR,
+#endif
+  TYPE_STRING,
+#if HAVE_WCHAR_T
+  TYPE_WIDE_STRING,
+#endif
+  TYPE_POINTER,
+  TYPE_COUNT_SCHAR_POINTER,
+  TYPE_COUNT_SHORT_POINTER,
+  TYPE_COUNT_INT_POINTER,
+  TYPE_COUNT_LONGINT_POINTER
+#if HAVE_LONG_LONG_INT
+, TYPE_COUNT_LONGLONGINT_POINTER
+#endif
+#if ENABLE_UNISTDIO
+  /* The unistdio extensions.  */
+, TYPE_U8_STRING
+, TYPE_U16_STRING
+, TYPE_U32_STRING
+#endif
+} arg_type;
+
+/* Polymorphic argument */
+typedef struct
+{
+  arg_type type;
+  union
+  {
+    signed char                        a_schar;
+    unsigned char              a_uchar;
+    short                      a_short;
+    unsigned short             a_ushort;
+    int                                a_int;
+    unsigned int               a_uint;
+    long int                   a_longint;
+    unsigned long int          a_ulongint;
+#if HAVE_LONG_LONG_INT
+    long long int              a_longlongint;
+    unsigned long long int     a_ulonglongint;
+#endif
+    float                      a_float;
+    double                     a_double;
+    long double                        a_longdouble;
+    int                                a_char;
+#if HAVE_WINT_T
+    wint_t                     a_wide_char;
+#endif
+    const char*                        a_string;
+#if HAVE_WCHAR_T
+    const wchar_t*             a_wide_string;
+#endif
+    void*                      a_pointer;
+    signed char *              a_count_schar_pointer;
+    short *                    a_count_short_pointer;
+    int *                      a_count_int_pointer;
+    long int *                 a_count_longint_pointer;
+#if HAVE_LONG_LONG_INT
+    long long int *            a_count_longlongint_pointer;
+#endif
+#if ENABLE_UNISTDIO
+    /* The unistdio extensions.  */
+    const uint8_t *            a_u8_string;
+    const uint16_t *           a_u16_string;
+    const uint32_t *           a_u32_string;
+#endif
+  }
+  a;
+}
+argument;
+
+typedef struct
+{
+  size_t count;
+  argument *arg;
+}
+arguments;
+
+
+/* Fetch the arguments, putting them into a. */
+#ifdef STATIC
+STATIC
+#else
+extern
+#endif
+int PRINTF_FETCHARGS (va_list args, arguments *a);
+
+#endif /* _PRINTF_ARGS_H */
diff --git a/lib/printf-parse.c b/lib/printf-parse.c
new file mode 100644
index 0000000..85c454b
--- /dev/null
+++ b/lib/printf-parse.c
@@ -0,0 +1,627 @@
+/* Formatted output to strings.
+   Copyright (C) 1999-2000, 2002-2003, 2006-2008 Free Software Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* This file can be parametrized with the following macros:
+     CHAR_T             The element type of the format string.
+     CHAR_T_ONLY_ASCII  Set to 1 to enable verification that all characters
+                        in the format string are ASCII.
+     DIRECTIVE          Structure denoting a format directive.
+                        Depends on CHAR_T.
+     DIRECTIVES         Structure denoting the set of format directives of a
+                        format string.  Depends on CHAR_T.
+     PRINTF_PARSE       Function that parses a format string.
+                        Depends on CHAR_T.
+     STATIC             Set to 'static' to declare the function static.
+     ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.  */
+
+#ifndef PRINTF_PARSE
+# include <config.h>
+#endif
+
+/* Specification.  */
+#ifndef PRINTF_PARSE
+# include "printf-parse.h"
+#endif
+
+/* Default parameters.  */
+#ifndef PRINTF_PARSE
+# define PRINTF_PARSE printf_parse
+# define CHAR_T char
+# define DIRECTIVE char_directive
+# define DIRECTIVES char_directives
+#endif
+
+/* Get size_t, NULL.  */
+#include <stddef.h>
+
+/* Get intmax_t.  */
+#if defined IN_LIBINTL || defined IN_LIBASPRINTF
+# if HAVE_STDINT_H_WITH_UINTMAX
+#  include <stdint.h>
+# endif
+# if HAVE_INTTYPES_H_WITH_UINTMAX
+#  include <inttypes.h>
+# endif
+#else
+# include <stdint.h>
+#endif
+
+/* malloc(), realloc(), free().  */
+#include <stdlib.h>
+
+/* errno.  */
+#include <errno.h>
+
+/* Checked size_t computations.  */
+#include "xsize.h"
+
+#if CHAR_T_ONLY_ASCII
+/* c_isascii().  */
+# include "c-ctype.h"
+#endif
+
+#ifdef STATIC
+STATIC
+#endif
+int
+PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
+{
+  const CHAR_T *cp = format;           /* pointer into format */
+  size_t arg_posn = 0;         /* number of regular arguments consumed */
+  size_t d_allocated;                  /* allocated elements of d->dir */
+  size_t a_allocated;                  /* allocated elements of a->arg */
+  size_t max_width_length = 0;
+  size_t max_precision_length = 0;
+
+  d->count = 0;
+  d_allocated = 1;
+  d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
+  if (d->dir == NULL)
+    /* Out of memory.  */
+    goto out_of_memory_1;
+
+  a->count = 0;
+  a_allocated = 0;
+  a->arg = NULL;
+
+#define REGISTER_ARG(_index_,_type_) \
+  {                                                                    \
+    size_t n = (_index_);                                              \
+    if (n >= a_allocated)                                              \
+      {                                                                        
\
+       size_t memory_size;                                             \
+       argument *memory;                                               \
+                                                                       \
+       a_allocated = xtimes (a_allocated, 2);                          \
+       if (a_allocated <= n)                                           \
+         a_allocated = xsum (n, 1);                                    \
+       memory_size = xtimes (a_allocated, sizeof (argument));          \
+       if (size_overflow_p (memory_size))                              \
+         /* Overflow, would lead to out of memory.  */                 \
+         goto out_of_memory;                                           \
+       memory = (argument *) (a->arg                                   \
+                              ? realloc (a->arg, memory_size)          \
+                              : malloc (memory_size));                 \
+       if (memory == NULL)                                             \
+         /* Out of memory.  */                                         \
+         goto out_of_memory;                                           \
+       a->arg = memory;                                                \
+      }                                                                        
\
+    while (a->count <= n)                                              \
+      a->arg[a->count++].type = TYPE_NONE;                             \
+    if (a->arg[n].type == TYPE_NONE)                                   \
+      a->arg[n].type = (_type_);                                       \
+    else if (a->arg[n].type != (_type_))                               \
+      /* Ambiguous type for positional argument.  */                   \
+      goto error;                                                      \
+  }
+
+  while (*cp != '\0')
+    {
+      CHAR_T c = *cp++;
+      if (c == '%')
+       {
+         size_t arg_index = ARG_NONE;
+         DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */
+
+         /* Initialize the next directive.  */
+         dp->dir_start = cp - 1;
+         dp->flags = 0;
+         dp->width_start = NULL;
+         dp->width_end = NULL;
+         dp->width_arg_index = ARG_NONE;
+         dp->precision_start = NULL;
+         dp->precision_end = NULL;
+         dp->precision_arg_index = ARG_NONE;
+         dp->arg_index = ARG_NONE;
+
+         /* Test for positional argument.  */
+         if (*cp >= '0' && *cp <= '9')
+           {
+             const CHAR_T *np;
+
+             for (np = cp; *np >= '0' && *np <= '9'; np++)
+               ;
+             if (*np == '$')
+               {
+                 size_t n = 0;
+
+                 for (np = cp; *np >= '0' && *np <= '9'; np++)
+                   n = xsum (xtimes (n, 10), *np - '0');
+                 if (n == 0)
+                   /* Positional argument 0.  */
+                   goto error;
+                 if (size_overflow_p (n))
+                   /* n too large, would lead to out of memory later.  */
+                   goto error;
+                 arg_index = n - 1;
+                 cp = np + 1;
+               }
+           }
+
+         /* Read the flags.  */
+         for (;;)
+           {
+             if (*cp == '\'')
+               {
+                 dp->flags |= FLAG_GROUP;
+                 cp++;
+               }
+             else if (*cp == '-')
+               {
+                 dp->flags |= FLAG_LEFT;
+                 cp++;
+               }
+             else if (*cp == '+')
+               {
+                 dp->flags |= FLAG_SHOWSIGN;
+                 cp++;
+               }
+             else if (*cp == ' ')
+               {
+                 dp->flags |= FLAG_SPACE;
+                 cp++;
+               }
+             else if (*cp == '#')
+               {
+                 dp->flags |= FLAG_ALT;
+                 cp++;
+               }
+             else if (*cp == '0')
+               {
+                 dp->flags |= FLAG_ZERO;
+                 cp++;
+               }
+             else
+               break;
+           }
+
+         /* Parse the field width.  */
+         if (*cp == '*')
+           {
+             dp->width_start = cp;
+             cp++;
+             dp->width_end = cp;
+             if (max_width_length < 1)
+               max_width_length = 1;
+
+             /* Test for positional argument.  */
+             if (*cp >= '0' && *cp <= '9')
+               {
+                 const CHAR_T *np;
+
+                 for (np = cp; *np >= '0' && *np <= '9'; np++)
+                   ;
+                 if (*np == '$')
+                   {
+                     size_t n = 0;
+
+                     for (np = cp; *np >= '0' && *np <= '9'; np++)
+                       n = xsum (xtimes (n, 10), *np - '0');
+                     if (n == 0)
+                       /* Positional argument 0.  */
+                       goto error;
+                     if (size_overflow_p (n))
+                       /* n too large, would lead to out of memory later.  */
+                       goto error;
+                     dp->width_arg_index = n - 1;
+                     cp = np + 1;
+                   }
+               }
+             if (dp->width_arg_index == ARG_NONE)
+               {
+                 dp->width_arg_index = arg_posn++;
+                 if (dp->width_arg_index == ARG_NONE)
+                   /* arg_posn wrapped around.  */
+                   goto error;
+               }
+             REGISTER_ARG (dp->width_arg_index, TYPE_INT);
+           }
+         else if (*cp >= '0' && *cp <= '9')
+           {
+             size_t width_length;
+
+             dp->width_start = cp;
+             for (; *cp >= '0' && *cp <= '9'; cp++)
+               ;
+             dp->width_end = cp;
+             width_length = dp->width_end - dp->width_start;
+             if (max_width_length < width_length)
+               max_width_length = width_length;
+           }
+
+         /* Parse the precision.  */
+         if (*cp == '.')
+           {
+             cp++;
+             if (*cp == '*')
+               {
+                 dp->precision_start = cp - 1;
+                 cp++;
+                 dp->precision_end = cp;
+                 if (max_precision_length < 2)
+                   max_precision_length = 2;
+
+                 /* Test for positional argument.  */
+                 if (*cp >= '0' && *cp <= '9')
+                   {
+                     const CHAR_T *np;
+
+                     for (np = cp; *np >= '0' && *np <= '9'; np++)
+                       ;
+                     if (*np == '$')
+                       {
+                         size_t n = 0;
+
+                         for (np = cp; *np >= '0' && *np <= '9'; np++)
+                           n = xsum (xtimes (n, 10), *np - '0');
+                         if (n == 0)
+                           /* Positional argument 0.  */
+                           goto error;
+                         if (size_overflow_p (n))
+                           /* n too large, would lead to out of memory
+                              later.  */
+                           goto error;
+                         dp->precision_arg_index = n - 1;
+                         cp = np + 1;
+                       }
+                   }
+                 if (dp->precision_arg_index == ARG_NONE)
+                   {
+                     dp->precision_arg_index = arg_posn++;
+                     if (dp->precision_arg_index == ARG_NONE)
+                       /* arg_posn wrapped around.  */
+                       goto error;
+                   }
+                 REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
+               }
+             else
+               {
+                 size_t precision_length;
+
+                 dp->precision_start = cp - 1;
+                 for (; *cp >= '0' && *cp <= '9'; cp++)
+                   ;
+                 dp->precision_end = cp;
+                 precision_length = dp->precision_end - dp->precision_start;
+                 if (max_precision_length < precision_length)
+                   max_precision_length = precision_length;
+               }
+           }
+
+         {
+           arg_type type;
+
+           /* Parse argument type/size specifiers.  */
+           {
+             int flags = 0;
+
+             for (;;)
+               {
+                 if (*cp == 'h')
+                   {
+                     flags |= (1 << (flags & 1));
+                     cp++;
+                   }
+                 else if (*cp == 'L')
+                   {
+                     flags |= 4;
+                     cp++;
+                   }
+                 else if (*cp == 'l')
+                   {
+                     flags += 8;
+                     cp++;
+                   }
+                 else if (*cp == 'j')
+                   {
+                     if (sizeof (intmax_t) > sizeof (long))
+                       {
+                         /* intmax_t = long long */
+                         flags += 16;
+                       }
+                     else if (sizeof (intmax_t) > sizeof (int))
+                       {
+                         /* intmax_t = long */
+                         flags += 8;
+                       }
+                     cp++;
+                   }
+                 else if (*cp == 'z' || *cp == 'Z')
+                   {
+                     /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
+                        because the warning facility in gcc-2.95.2 understands
+                        only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784).  */
+                     if (sizeof (size_t) > sizeof (long))
+                       {
+                         /* size_t = long long */
+                         flags += 16;
+                       }
+                     else if (sizeof (size_t) > sizeof (int))
+                       {
+                         /* size_t = long */
+                         flags += 8;
+                       }
+                     cp++;
+                   }
+                 else if (*cp == 't')
+                   {
+                     if (sizeof (ptrdiff_t) > sizeof (long))
+                       {
+                         /* ptrdiff_t = long long */
+                         flags += 16;
+                       }
+                     else if (sizeof (ptrdiff_t) > sizeof (int))
+                       {
+                         /* ptrdiff_t = long */
+                         flags += 8;
+                       }
+                     cp++;
+                   }
+#if defined __APPLE__ && defined __MACH__
+                 /* On MacOS X 10.3, PRIdMAX is defined as "qd".
+                    We cannot change it to "lld" because PRIdMAX must also
+                    be understood by the system's printf routines.  */
+                 else if (*cp == 'q')
+                   {
+                     if (64 / 8 > sizeof (long))
+                       {
+                         /* int64_t = long long */
+                         flags += 16;
+                       }
+                     else
+                       {
+                         /* int64_t = long */
+                         flags += 8;
+                       }
+                     cp++;
+                   }
+#endif
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+                 /* On native Win32, PRIdMAX is defined as "I64d".
+                    We cannot change it to "lld" because PRIdMAX must also
+                    be understood by the system's printf routines.  */
+                 else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4')
+                   {
+                     if (64 / 8 > sizeof (long))
+                       {
+                         /* __int64 = long long */
+                         flags += 16;
+                       }
+                     else
+                       {
+                         /* __int64 = long */
+                         flags += 8;
+                       }
+                     cp += 3;
+                   }
+#endif
+                 else
+                   break;
+               }
+
+             /* Read the conversion character.  */
+             c = *cp++;
+             switch (c)
+               {
+               case 'd': case 'i':
+#if HAVE_LONG_LONG_INT
+                 /* If 'long long' exists and is larger than 'long':  */
+                 if (flags >= 16 || (flags & 4))
+                   type = TYPE_LONGLONGINT;
+                 else
+#endif
+                 /* If 'long long' exists and is the same as 'long', we parse
+                    "lld" into TYPE_LONGINT.  */
+                 if (flags >= 8)
+                   type = TYPE_LONGINT;
+                 else if (flags & 2)
+                   type = TYPE_SCHAR;
+                 else if (flags & 1)
+                   type = TYPE_SHORT;
+                 else
+                   type = TYPE_INT;
+                 break;
+               case 'o': case 'u': case 'x': case 'X':
+#if HAVE_LONG_LONG_INT
+                 /* If 'long long' exists and is larger than 'long':  */
+                 if (flags >= 16 || (flags & 4))
+                   type = TYPE_ULONGLONGINT;
+                 else
+#endif
+                 /* If 'unsigned long long' exists and is the same as
+                    'unsigned long', we parse "llu" into TYPE_ULONGINT.  */
+                 if (flags >= 8)
+                   type = TYPE_ULONGINT;
+                 else if (flags & 2)
+                   type = TYPE_UCHAR;
+                 else if (flags & 1)
+                   type = TYPE_USHORT;
+                 else
+                   type = TYPE_UINT;
+                 break;
+               case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
+               case 'a': case 'A':
+                 if (flags >= 16 || (flags & 4))
+                   type = TYPE_LONGDOUBLE;
+                 else
+                   type = TYPE_DOUBLE;
+                 break;
+               case 'c':
+                 if (flags >= 8)
+#if HAVE_WINT_T
+                   type = TYPE_WIDE_CHAR;
+#else
+                   goto error;
+#endif
+                 else
+                   type = TYPE_CHAR;
+                 break;
+#if HAVE_WINT_T
+               case 'C':
+                 type = TYPE_WIDE_CHAR;
+                 c = 'c';
+                 break;
+#endif
+               case 's':
+                 if (flags >= 8)
+#if HAVE_WCHAR_T
+                   type = TYPE_WIDE_STRING;
+#else
+                   goto error;
+#endif
+                 else
+                   type = TYPE_STRING;
+                 break;
+#if HAVE_WCHAR_T
+               case 'S':
+                 type = TYPE_WIDE_STRING;
+                 c = 's';
+                 break;
+#endif
+               case 'p':
+                 type = TYPE_POINTER;
+                 break;
+               case 'n':
+#if HAVE_LONG_LONG_INT
+                 /* If 'long long' exists and is larger than 'long':  */
+                 if (flags >= 16 || (flags & 4))
+                   type = TYPE_COUNT_LONGLONGINT_POINTER;
+                 else
+#endif
+                 /* If 'long long' exists and is the same as 'long', we parse
+                    "lln" into TYPE_COUNT_LONGINT_POINTER.  */
+                 if (flags >= 8)
+                   type = TYPE_COUNT_LONGINT_POINTER;
+                 else if (flags & 2)
+                   type = TYPE_COUNT_SCHAR_POINTER;
+                 else if (flags & 1)
+                   type = TYPE_COUNT_SHORT_POINTER;
+                 else
+                   type = TYPE_COUNT_INT_POINTER;
+                 break;
+#if ENABLE_UNISTDIO
+               /* The unistdio extensions.  */
+               case 'U':
+                 if (flags >= 16)
+                   type = TYPE_U32_STRING;
+                 else if (flags >= 8)
+                   type = TYPE_U16_STRING;
+                 else
+                   type = TYPE_U8_STRING;
+                 break;
+#endif
+               case '%':
+                 type = TYPE_NONE;
+                 break;
+               default:
+                 /* Unknown conversion character.  */
+                 goto error;
+               }
+           }
+
+           if (type != TYPE_NONE)
+             {
+               dp->arg_index = arg_index;
+               if (dp->arg_index == ARG_NONE)
+                 {
+                   dp->arg_index = arg_posn++;
+                   if (dp->arg_index == ARG_NONE)
+                     /* arg_posn wrapped around.  */
+                     goto error;
+                 }
+               REGISTER_ARG (dp->arg_index, type);
+             }
+           dp->conversion = c;
+           dp->dir_end = cp;
+         }
+
+         d->count++;
+         if (d->count >= d_allocated)
+           {
+             size_t memory_size;
+             DIRECTIVE *memory;
+
+             d_allocated = xtimes (d_allocated, 2);
+             memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
+             if (size_overflow_p (memory_size))
+               /* Overflow, would lead to out of memory.  */
+               goto out_of_memory;
+             memory = (DIRECTIVE *) realloc (d->dir, memory_size);
+             if (memory == NULL)
+               /* Out of memory.  */
+               goto out_of_memory;
+             d->dir = memory;
+           }
+       }
+#if CHAR_T_ONLY_ASCII
+      else if (!c_isascii (c))
+       {
+         /* Non-ASCII character.  Not supported.  */
+         goto error;
+       }
+#endif
+    }
+  d->dir[d->count].dir_start = cp;
+
+  d->max_width_length = max_width_length;
+  d->max_precision_length = max_precision_length;
+  return 0;
+
+error:
+  if (a->arg)
+    free (a->arg);
+  if (d->dir)
+    free (d->dir);
+  errno = EINVAL;
+  return -1;
+
+out_of_memory:
+  if (a->arg)
+    free (a->arg);
+  if (d->dir)
+    free (d->dir);
+out_of_memory_1:
+  errno = ENOMEM;
+  return -1;
+}
+
+#undef PRINTF_PARSE
+#undef DIRECTIVES
+#undef DIRECTIVE
+#undef CHAR_T_ONLY_ASCII
+#undef CHAR_T
diff --git a/lib/printf-parse.h b/lib/printf-parse.h
new file mode 100644
index 0000000..0a496cb
--- /dev/null
+++ b/lib/printf-parse.h
@@ -0,0 +1,179 @@
+/* Parse printf format string.
+   Copyright (C) 1999, 2002-2003, 2005, 2007 Free Software Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _PRINTF_PARSE_H
+#define _PRINTF_PARSE_H
+
+/* This file can be parametrized with the following macros:
+     ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.
+     STATIC             Set to 'static' to declare the function static.  */
+
+#include "printf-args.h"
+
+
+/* Flags */
+#define FLAG_GROUP      1      /* ' flag */
+#define FLAG_LEFT       2      /* - flag */
+#define FLAG_SHOWSIGN   4      /* + flag */
+#define FLAG_SPACE      8      /* space flag */
+#define FLAG_ALT       16      /* # flag */
+#define FLAG_ZERO      32
+
+/* arg_index value indicating that no argument is consumed.  */
+#define ARG_NONE       (~(size_t)0)
+
+/* xxx_directive: A parsed directive.
+   xxx_directives: A parsed format string.  */
+
+/* A parsed directive.  */
+typedef struct
+{
+  const char* dir_start;
+  const char* dir_end;
+  int flags;
+  const char* width_start;
+  const char* width_end;
+  size_t width_arg_index;
+  const char* precision_start;
+  const char* precision_end;
+  size_t precision_arg_index;
+  char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
+  size_t arg_index;
+}
+char_directive;
+
+/* A parsed format string.  */
+typedef struct
+{
+  size_t count;
+  char_directive *dir;
+  size_t max_width_length;
+  size_t max_precision_length;
+}
+char_directives;
+
+#if ENABLE_UNISTDIO
+
+/* A parsed directive.  */
+typedef struct
+{
+  const uint8_t* dir_start;
+  const uint8_t* dir_end;
+  int flags;
+  const uint8_t* width_start;
+  const uint8_t* width_end;
+  size_t width_arg_index;
+  const uint8_t* precision_start;
+  const uint8_t* precision_end;
+  size_t precision_arg_index;
+  uint8_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
+  size_t arg_index;
+}
+u8_directive;
+
+/* A parsed format string.  */
+typedef struct
+{
+  size_t count;
+  u8_directive *dir;
+  size_t max_width_length;
+  size_t max_precision_length;
+}
+u8_directives;
+
+/* A parsed directive.  */
+typedef struct
+{
+  const uint16_t* dir_start;
+  const uint16_t* dir_end;
+  int flags;
+  const uint16_t* width_start;
+  const uint16_t* width_end;
+  size_t width_arg_index;
+  const uint16_t* precision_start;
+  const uint16_t* precision_end;
+  size_t precision_arg_index;
+  uint16_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S 
*/
+  size_t arg_index;
+}
+u16_directive;
+
+/* A parsed format string.  */
+typedef struct
+{
+  size_t count;
+  u16_directive *dir;
+  size_t max_width_length;
+  size_t max_precision_length;
+}
+u16_directives;
+
+/* A parsed directive.  */
+typedef struct
+{
+  const uint32_t* dir_start;
+  const uint32_t* dir_end;
+  int flags;
+  const uint32_t* width_start;
+  const uint32_t* width_end;
+  size_t width_arg_index;
+  const uint32_t* precision_start;
+  const uint32_t* precision_end;
+  size_t precision_arg_index;
+  uint32_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S 
*/
+  size_t arg_index;
+}
+u32_directive;
+
+/* A parsed format string.  */
+typedef struct
+{
+  size_t count;
+  u32_directive *dir;
+  size_t max_width_length;
+  size_t max_precision_length;
+}
+u32_directives;
+
+#endif
+
+
+/* Parses the format string.  Fills in the number N of directives, and fills
+   in directives[0], ..., directives[N-1], and sets directives[N].dir_start
+   to the end of the format string.  Also fills in the arg_type fields of the
+   arguments and the needed count of arguments.  */
+#if ENABLE_UNISTDIO
+extern int
+       ulc_printf_parse (const char *format, char_directives *d, arguments *a);
+extern int
+       u8_printf_parse (const uint8_t *format, u8_directives *d, arguments *a);
+extern int
+       u16_printf_parse (const uint16_t *format, u16_directives *d,
+                        arguments *a);
+extern int
+       u32_printf_parse (const uint32_t *format, u32_directives *d,
+                        arguments *a);
+#else
+# ifdef STATIC
+STATIC
+# else
+extern
+# endif
+int printf_parse (const char *format, char_directives *d, arguments *a);
+#endif
+
+#endif /* _PRINTF_PARSE_H */
diff --git a/lib/size_max.h b/lib/size_max.h
new file mode 100644
index 0000000..419d73a
--- /dev/null
+++ b/lib/size_max.h
@@ -0,0 +1,31 @@
+/* size_max.h -- declare SIZE_MAX through system headers
+   Copyright (C) 2005-2006 Free Software Foundation, Inc.
+   Written by Simon Josefsson.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef GNULIB_SIZE_MAX_H
+#define GNULIB_SIZE_MAX_H
+
+/* Get SIZE_MAX declaration on systems like Solaris 7/8/9.  */
+# include <limits.h>
+/* Get SIZE_MAX declaration on systems like glibc 2.  */
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+/* On systems where these include files don't define it, SIZE_MAX is defined
+   in config.h.  */
+
+#endif /* GNULIB_SIZE_MAX_H */
diff --git a/lib/stdio-write.c b/lib/stdio-write.c
new file mode 100644
index 0000000..8f275ff
--- /dev/null
+++ b/lib/stdio-write.c
@@ -0,0 +1,148 @@
+/* POSIX compatible FILE stream write function.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+   Written by Bruno Haible <address@hidden>, 2008.
+
+   This program 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 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdio.h>
+
+/* Replace these functions only if module 'sigpipe' is requested.  */
+#if GNULIB_SIGPIPE
+
+/* On native Windows platforms, SIGPIPE does not exist.  When write() is
+   called on a pipe with no readers, WriteFile() fails with error
+   GetLastError() = ERROR_NO_DATA, and write() in consequence fails with
+   error EINVAL.  This write() function is at the basis of the function
+   which flushes the buffer of a FILE stream.  */
+
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+#  include <errno.h>
+#  include <signal.h>
+#  include <io.h>
+
+#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
+#  include <windows.h>
+
+#  define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \
+  if (ferror (stream))                                                       \
+    return (EXPRESSION);                                                     \
+  else                                                                       \
+    {                                                                        \
+      RETTYPE ret;                                                           \
+      SetLastError (0);                                                        
      \
+      ret = (EXPRESSION);                                                    \
+      if (FAILED && GetLastError () == ERROR_NO_DATA && ferror (stream))      \
+       {                                                                     \
+         int fd = fileno (stream);                                           \
+         if (fd >= 0                                                         \
+             && GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_PIPE)\
+           {                                                                 \
+             /* Try to raise signal SIGPIPE.  */                             \
+             raise (SIGPIPE);                                                \
+             /* If it is currently blocked or ignored, change errno from     \
+                EINVAL to EPIPE.  */                                         \
+             errno = EPIPE;                                                  \
+           }                                                                 \
+       }                                                                     \
+      return ret;                                                            \
+    }
+
+#  if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */
+int
+printf (const char *format, ...)
+{
+  int retval;
+  va_list args;
+
+  va_start (args, format);
+  retval = vfprintf (stdout, format, args);
+  va_end (args);
+
+  return retval;
+}
+#  endif
+
+#  if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */
+int
+fprintf (FILE *stream, const char *format, ...)
+{
+  int retval;
+  va_list args;
+
+  va_start (args, format);
+  retval = vfprintf (stream, format, args);
+  va_end (args);
+
+  return retval;
+}
+#  endif
+
+#  if !REPLACE_VFPRINTF_POSIX /* avoid collision with vprintf.c */
+int
+vprintf (const char *format, va_list args)
+{
+  return vfprintf (stdout, format, args);
+}
+#  endif
+
+#  if !REPLACE_VPRINTF_POSIX /* avoid collision with vfprintf.c */
+int
+vfprintf (FILE *stream, const char *format, va_list args)
+#undef vfprintf
+{
+  CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == 
EOF)
+}
+#  endif
+
+int
+putchar (int c)
+{
+  return fputc (c, stdout);
+}
+
+int
+fputc (int c, FILE *stream)
+#undef fputc
+{
+  CALL_WITH_SIGPIPE_EMULATION (int, fputc (c, stream), ret == EOF)
+}
+
+int
+fputs (const char *string, FILE *stream)
+#undef fputs
+{
+  CALL_WITH_SIGPIPE_EMULATION (int, fputs (string, stream), ret == EOF)
+}
+
+int
+puts (const char *string)
+#undef puts
+{
+  FILE *stream = stdout;
+  CALL_WITH_SIGPIPE_EMULATION (int, puts (string), ret == EOF)
+}
+
+size_t
+fwrite (const void *ptr, size_t s, size_t n, FILE *stream)
+#undef fwrite
+{
+  CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n)
+}
+
+# endif
+#endif
diff --git a/lib/stdio.in.h b/lib/stdio.in.h
new file mode 100644
index 0000000..ae681fc
--- /dev/null
+++ b/lib/stdio.in.h
@@ -0,0 +1,542 @@
+/* A GNU-like <stdio.h>.
+
+   Copyright (C) 2004, 2007-2009 Free Software Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#if __GNUC__ >= 3
address@hidden@
+#endif
+
+#if defined __need_FILE || defined __need___FILE
+/* Special invocation convention inside glibc header files.  */
+
address@hidden@ @NEXT_STDIO_H@
+
+#else
+/* Normal invocation convention.  */
+
+#ifndef _GL_STDIO_H
+
+/* The include_next requires a split double-inclusion guard.  */
address@hidden@ @NEXT_STDIO_H@
+
+#ifndef _GL_STDIO_H
+#define _GL_STDIO_H
+
+#include <stdarg.h>
+#include <stddef.h>
+
+#if (@GNULIB_FSEEKO@ && @REPLACE_FSEEKO@) \
+  || (@GNULIB_FTELLO@ && @REPLACE_FTELLO@) \
+  || (@GNULIB_GETDELIM@ && address@hidden@) \
+  || (@GNULIB_GETLINE@ && (address@hidden@ || @REPLACE_GETLINE@))
+/* Get off_t and ssize_t.  */
+# include <sys/types.h>
+#endif
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+#  define __attribute__(Spec) /* empty */
+# endif
+/* The __-protected variants of `format' and `printf' attributes
+   are accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+#  define __format__ format
+#  define __printf__ printf
+# endif
+#endif
+
+
+/* The definition of GL_LINK_WARNING is copied here.  */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if @GNULIB_FPRINTF_POSIX@
+# if @REPLACE_FPRINTF@
+#  define fprintf rpl_fprintf
+extern int fprintf (FILE *fp, const char *format, ...)
+       __attribute__ ((__format__ (__printf__, 2, 3)));
+# endif
+#elif @GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && 
@GNULIB_STDIO_H_SIGPIPE@
+# define fprintf rpl_fprintf
+extern int fprintf (FILE *fp, const char *format, ...)
+       __attribute__ ((__format__ (__printf__, 2, 3)));
+#elif defined GNULIB_POSIXCHECK
+# undef fprintf
+# define fprintf \
+    (GL_LINK_WARNING ("fprintf is not always POSIX compliant - " \
+                      "use gnulib module fprintf-posix for portable " \
+                      "POSIX compliance"), \
+     fprintf)
+#endif
+
+#if @GNULIB_VFPRINTF_POSIX@
+# if @REPLACE_VFPRINTF@
+#  define vfprintf rpl_vfprintf
+extern int vfprintf (FILE *fp, const char *format, va_list args)
+       __attribute__ ((__format__ (__printf__, 2, 0)));
+# endif
+#elif @GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && 
@GNULIB_STDIO_H_SIGPIPE@
+# define vfprintf rpl_vfprintf
+extern int vfprintf (FILE *fp, const char *format, va_list args)
+       __attribute__ ((__format__ (__printf__, 2, 0)));
+#elif defined GNULIB_POSIXCHECK
+# undef vfprintf
+# define vfprintf(s,f,a) \
+    (GL_LINK_WARNING ("vfprintf is not always POSIX compliant - " \
+                      "use gnulib module vfprintf-posix for portable " \
+                      "POSIX compliance"), \
+     vfprintf (s, f, a))
+#endif
+
+#if @GNULIB_PRINTF_POSIX@
+# if @REPLACE_PRINTF@
+/* Don't break __attribute__((format(printf,M,N))).  */
+#  define printf __printf__
+extern int printf (const char *format, ...)
+       __attribute__ ((__format__ (__printf__, 1, 2)));
+# endif
+#elif @GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && 
@GNULIB_STDIO_H_SIGPIPE@
+/* Don't break __attribute__((format(printf,M,N))).  */
+# define printf __printf__
+extern int printf (const char *format, ...)
+       __attribute__ ((__format__ (__printf__, 1, 2)));
+#elif defined GNULIB_POSIXCHECK
+# undef printf
+# define printf \
+    (GL_LINK_WARNING ("printf is not always POSIX compliant - " \
+                      "use gnulib module printf-posix for portable " \
+                      "POSIX compliance"), \
+     printf)
+/* Don't break __attribute__((format(printf,M,N))).  */
+# define format(kind,m,n) format (__##kind##__, m, n)
+# define __format__(kind,m,n) __format__ (__##kind##__, m, n)
+# define ____printf____ __printf__
+# define ____scanf____ __scanf__
+# define ____strftime____ __strftime__
+# define ____strfmon____ __strfmon__
+#endif
+
+#if @GNULIB_VPRINTF_POSIX@
+# if @REPLACE_VPRINTF@
+#  define vprintf rpl_vprintf
+extern int vprintf (const char *format, va_list args)
+       __attribute__ ((__format__ (__printf__, 1, 0)));
+# endif
+#elif @GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && 
@GNULIB_STDIO_H_SIGPIPE@
+# define vprintf rpl_vprintf
+extern int vprintf (const char *format, va_list args)
+       __attribute__ ((__format__ (__printf__, 1, 0)));
+#elif defined GNULIB_POSIXCHECK
+# undef vprintf
+# define vprintf(f,a) \
+    (GL_LINK_WARNING ("vprintf is not always POSIX compliant - " \
+                      "use gnulib module vprintf-posix for portable " \
+                      "POSIX compliance"), \
+     vprintf (f, a))
+#endif
+
+#if @GNULIB_SNPRINTF@
+# if @REPLACE_SNPRINTF@
+#  define snprintf rpl_snprintf
+# endif
+# if @REPLACE_SNPRINTF@ || address@hidden@
+extern int snprintf (char *str, size_t size, const char *format, ...)
+       __attribute__ ((__format__ (__printf__, 3, 4)));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef snprintf
+# define snprintf \
+    (GL_LINK_WARNING ("snprintf is unportable - " \
+                      "use gnulib module snprintf for portability"), \
+     snprintf)
+#endif
+
+#if @GNULIB_VSNPRINTF@
+# if @REPLACE_VSNPRINTF@
+#  define vsnprintf rpl_vsnprintf
+# endif
+# if @REPLACE_VSNPRINTF@ || address@hidden@
+extern int vsnprintf (char *str, size_t size, const char *format, va_list args)
+       __attribute__ ((__format__ (__printf__, 3, 0)));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef vsnprintf
+# define vsnprintf(b,s,f,a) \
+    (GL_LINK_WARNING ("vsnprintf is unportable - " \
+                      "use gnulib module vsnprintf for portability"), \
+     vsnprintf (b, s, f, a))
+#endif
+
+#if @GNULIB_SPRINTF_POSIX@
+# if @REPLACE_SPRINTF@
+#  define sprintf rpl_sprintf
+extern int sprintf (char *str, const char *format, ...)
+       __attribute__ ((__format__ (__printf__, 2, 3)));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef sprintf
+# define sprintf \
+    (GL_LINK_WARNING ("sprintf is not always POSIX compliant - " \
+                      "use gnulib module sprintf-posix for portable " \
+                      "POSIX compliance"), \
+     sprintf)
+#endif
+
+#if @GNULIB_VSPRINTF_POSIX@
+# if @REPLACE_VSPRINTF@
+#  define vsprintf rpl_vsprintf
+extern int vsprintf (char *str, const char *format, va_list args)
+       __attribute__ ((__format__ (__printf__, 2, 0)));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef vsprintf
+# define vsprintf(b,f,a) \
+    (GL_LINK_WARNING ("vsprintf is not always POSIX compliant - " \
+                      "use gnulib module vsprintf-posix for portable " \
+                      "POSIX compliance"), \
+     vsprintf (b, f, a))
+#endif
+
+#if @GNULIB_DPRINTF@
+# if @REPLACE_DPRINTF@
+#  define dprintf rpl_dprintf
+# endif
+# if @REPLACE_DPRINTF@ || address@hidden@
+extern int dprintf (int fd, const char *format, ...)
+       __attribute__ ((__format__ (__printf__, 2, 3)));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef dprintf
+# define dprintf(d,f,a) \
+    (GL_LINK_WARNING ("dprintf is unportable - " \
+                      "use gnulib module dprintf for portability"), \
+     dprintf (d, f, a))
+#endif
+
+#if @GNULIB_VDPRINTF@
+# if @REPLACE_VDPRINTF@
+#  define vdprintf rpl_vdprintf
+# endif
+# if @REPLACE_VDPRINTF@ || address@hidden@
+extern int vdprintf (int fd, const char *format, va_list args)
+       __attribute__ ((__format__ (__printf__, 2, 0)));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef vdprintf
+# define vdprintf(d,f,a) \
+    (GL_LINK_WARNING ("vdprintf is unportable - " \
+                      "use gnulib module vdprintf for portability"), \
+     vdprintf (d, f, a))
+#endif
+
+#if @GNULIB_VASPRINTF@
+# if @REPLACE_VASPRINTF@
+#  define asprintf rpl_asprintf
+#  define vasprintf rpl_vasprintf
+# endif
+# if @REPLACE_VASPRINTF@ || address@hidden@
+  /* Write formatted output to a string dynamically allocated with malloc().
+     If the memory allocation succeeds, store the address of the string in
+     *RESULT and return the number of resulting bytes, excluding the trailing
+     NUL.  Upon memory allocation error, or some other error, return -1.  */
+  extern int asprintf (char **result, const char *format, ...)
+    __attribute__ ((__format__ (__printf__, 2, 3)));
+  extern int vasprintf (char **result, const char *format, va_list args)
+    __attribute__ ((__format__ (__printf__, 2, 0)));
+# endif
+#endif
+
+#if @GNULIB_OBSTACK_PRINTF@
+# if @REPLACE_OBSTACK_PRINTF@
+#  define obstack_printf rpl_osbtack_printf
+#  define obstack_vprintf rpl_obstack_vprintf
+# endif
+# if @REPLACE_OBSTACK_PRINTF@ || address@hidden@
+  struct obstack;
+  /* Grow an obstack with formatted output.  Return the number of
+     bytes added to OBS.  No trailing nul byte is added, and the
+     object should be closed with obstack_finish before use.  Upon
+     memory allocation error, call obstack_alloc_failed_handler.  Upon
+     other error, return -1.  */
+  extern int obstack_printf (struct obstack *obs, const char *format, ...)
+    __attribute__ ((__format__ (__printf__, 2, 3)));
+  extern int obstack_vprintf (struct obstack *obs, const char *format,
+                             va_list args)
+    __attribute__ ((__format__ (__printf__, 2, 0)));
+# endif
+#endif
+
+#if @GNULIB_FOPEN@
+# if @REPLACE_FOPEN@
+#  undef fopen
+#  define fopen rpl_fopen
+extern FILE * fopen (const char *filename, const char *mode);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef fopen
+# define fopen(f,m) \
+   (GL_LINK_WARNING ("fopen on Win32 platforms is not POSIX compatible - " \
+                     "use gnulib module fopen for portability"), \
+    fopen (f, m))
+#endif
+
+#if @GNULIB_FREOPEN@
+# if @REPLACE_FREOPEN@
+#  undef freopen
+#  define freopen rpl_freopen
+extern FILE * freopen (const char *filename, const char *mode, FILE *stream);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef freopen
+# define freopen(f,m,s) \
+   (GL_LINK_WARNING ("freopen on Win32 platforms is not POSIX compatible - " \
+                     "use gnulib module freopen for portability"), \
+    freopen (f, m, s))
+#endif
+
+#if @GNULIB_FSEEKO@
+# if @REPLACE_FSEEKO@
+/* Provide fseek, fseeko functions that are aware of a preceding
+   fflush(), and which detect pipes.  */
+#  define fseeko rpl_fseeko
+extern int fseeko (FILE *fp, off_t offset, int whence);
+#  define fseek(fp, offset, whence) fseeko (fp, (off_t)(offset), whence)
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef fseeko
+# define fseeko(f,o,w) \
+   (GL_LINK_WARNING ("fseeko is unportable - " \
+                     "use gnulib module fseeko for portability"), \
+    fseeko (f, o, w))
+#endif
+
+#if @GNULIB_FSEEK@ && @REPLACE_FSEEK@
+extern int rpl_fseek (FILE *fp, long offset, int whence);
+# undef fseek
+# if defined GNULIB_POSIXCHECK
+#  define fseek(f,o,w) \
+     (GL_LINK_WARNING ("fseek cannot handle files larger than 4 GB " \
+                       "on 32-bit platforms - " \
+                       "use fseeko function for handling of large files"), \
+      rpl_fseek (f, o, w))
+# else
+#  define fseek rpl_fseek
+# endif
+#elif defined GNULIB_POSIXCHECK
+# ifndef fseek
+#  define fseek(f,o,w) \
+     (GL_LINK_WARNING ("fseek cannot handle files larger than 4 GB " \
+                       "on 32-bit platforms - " \
+                       "use fseeko function for handling of large files"), \
+      fseek (f, o, w))
+# endif
+#endif
+
+#if @GNULIB_FTELLO@
+# if @REPLACE_FTELLO@
+#  define ftello rpl_ftello
+extern off_t ftello (FILE *fp);
+#  define ftell(fp) ftello (fp)
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef ftello
+# define ftello(f) \
+   (GL_LINK_WARNING ("ftello is unportable - " \
+                     "use gnulib module ftello for portability"), \
+    ftello (f))
+#endif
+
+#if @GNULIB_FTELL@ && @REPLACE_FTELL@
+extern long rpl_ftell (FILE *fp);
+# undef ftell
+# if GNULIB_POSIXCHECK
+#  define ftell(f) \
+     (GL_LINK_WARNING ("ftell cannot handle files larger than 4 GB " \
+                       "on 32-bit platforms - " \
+                       "use ftello function for handling of large files"), \
+      rpl_ftell (f))
+# else
+#  define ftell rpl_ftell
+# endif
+#elif defined GNULIB_POSIXCHECK
+# ifndef ftell
+#  define ftell(f) \
+     (GL_LINK_WARNING ("ftell cannot handle files larger than 4 GB " \
+                       "on 32-bit platforms - " \
+                       "use ftello function for handling of large files"), \
+      ftell (f))
+# endif
+#endif
+
+#if @GNULIB_FFLUSH@
+# if @REPLACE_FFLUSH@
+#  define fflush rpl_fflush
+  /* Flush all pending data on STREAM according to POSIX rules.  Both
+     output and seekable input streams are supported.
+     Note! LOSS OF DATA can occur if fflush is applied on an input stream
+     that is _not_seekable_ or on an update stream that is _not_seekable_
+     and in which the most recent operation was input.  Seekability can
+     be tested with lseek(fileno(fp),0,SEEK_CUR).  */
+  extern int fflush (FILE *gl_stream);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef fflush
+# define fflush(f) \
+   (GL_LINK_WARNING ("fflush is not always POSIX compliant - " \
+                     "use gnulib module fflush for portable " \
+                     "POSIX compliance"), \
+    fflush (f))
+#endif
+
+#if @GNULIB_FPURGE@
+# if @REPLACE_FPURGE@
+#  define fpurge rpl_fpurge
+# endif
+# if @REPLACE_FPURGE@ || address@hidden@
+  /* Discard all pending buffered I/O data on STREAM.
+     STREAM must not be wide-character oriented.
+     Return 0 if successful.  Upon error, return -1 and set errno.  */
+  extern int fpurge (FILE *gl_stream);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef fpurge
+# define fpurge(f) \
+   (GL_LINK_WARNING ("fpurge is not always present - " \
+                     "use gnulib module fpurge for portability"), \
+    fpurge (f))
+#endif
+
+#if @GNULIB_FCLOSE@
+# if @REPLACE_FCLOSE@
+#  define fclose rpl_fclose
+  /* Close STREAM and its underlying file descriptor.  */
+extern int fclose (FILE *stream);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef fclose
+# define fclose(f) \
+   (GL_LINK_WARNING ("fclose is not always POSIX compliant - " \
+                     "use gnulib module fclose for portable " \
+                     "POSIX compliance"), \
+    fclose (f))
+#endif
+
+#if @GNULIB_FPUTC@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
+# undef fputc
+# define fputc rpl_fputc
+extern int fputc (int c, FILE *stream);
+#endif
+
+#if @GNULIB_PUTC@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
+# undef putc
+# define putc rpl_fputc
+extern int putc (int c, FILE *stream);
+#endif
+
+#if @GNULIB_PUTCHAR@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
+# undef putchar
+# define putchar rpl_putchar
+extern int putchar (int c);
+#endif
+
+#if @GNULIB_FPUTS@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
+# undef fputs
+# define fputs rpl_fputs
+extern int fputs (const char *string, FILE *stream);
+#endif
+
+#if @GNULIB_PUTS@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
+# undef puts
+# define puts rpl_puts
+extern int puts (const char *string);
+#endif
+
+#if @GNULIB_FWRITE@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
+# undef fwrite
+# define fwrite rpl_fwrite
+extern size_t fwrite (const void *ptr, size_t s, size_t n, FILE *stream);
+#endif
+
+#if @GNULIB_GETDELIM@
+# if address@hidden@
+/* Read input, up to (and including) the next occurrence of DELIMITER, from
+   STREAM, store it in *LINEPTR (and NUL-terminate it).
+   *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE
+   bytes of space.  It is realloc'd as necessary.
+   Return the number of bytes read and stored at *LINEPTR (not including the
+   NUL terminator), or -1 on error or EOF.  */
+extern ssize_t getdelim (char **lineptr, size_t *linesize, int delimiter,
+                        FILE *stream);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef getdelim
+# define getdelim(l, s, d, f)                                      \
+  (GL_LINK_WARNING ("getdelim is unportable - "                            \
+                   "use gnulib module getdelim for portability"),  \
+   getdelim (l, s, d, f))
+#endif
+
+#if @GNULIB_GETLINE@
+# if @REPLACE_GETLINE@
+#  undef getline
+#  define getline rpl_getline
+# endif
+# if address@hidden@ || @REPLACE_GETLINE@
+/* Read a line, up to (and including) the next newline, from STREAM, store it
+   in *LINEPTR (and NUL-terminate it).
+   *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE
+   bytes of space.  It is realloc'd as necessary.
+   Return the number of bytes read and stored at *LINEPTR (not including the
+   NUL terminator), or -1 on error or EOF.  */
+extern ssize_t getline (char **lineptr, size_t *linesize, FILE *stream);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef getline
+# define getline(l, s, f)                                              \
+  (GL_LINK_WARNING ("getline is unportable - "                         \
+                   "use gnulib module getline for portability"),       \
+   getline (l, s, f))
+#endif
+
+#if @GNULIB_PERROR@
+# if @REPLACE_PERROR@
+#  define perror rpl_perror
+/* Print a message to standard error, describing the value of ERRNO,
+   (if STRING is not NULL and not empty) prefixed with STRING and ": ",
+   and terminated with a newline.  */
+extern void perror (const char *string);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef perror
+# define perror(s) \
+    (GL_LINK_WARNING ("perror is not always POSIX compliant - " \
+                      "use gnulib module perror for portability"), \
+     perror (s))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GL_STDIO_H */
+#endif /* _GL_STDIO_H */
+#endif
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
new file mode 100644
index 0000000..c620b4c
--- /dev/null
+++ b/lib/vasnprintf.c
@@ -0,0 +1,5487 @@
+/* vsprintf with automatic memory allocation.
+   Copyright (C) 1999, 2002-2009 Free Software Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* This file can be parametrized with the following macros:
+     VASNPRINTF         The name of the function being defined.
+     FCHAR_T            The element type of the format string.
+     DCHAR_T            The element type of the destination (result) string.
+     FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
+                        in the format string are ASCII. MUST be set if
+                        FCHAR_T and DCHAR_T are not the same type.
+     DIRECTIVE          Structure denoting a format directive.
+                        Depends on FCHAR_T.
+     DIRECTIVES         Structure denoting the set of format directives of a
+                        format string.  Depends on FCHAR_T.
+     PRINTF_PARSE       Function that parses a format string.
+                        Depends on FCHAR_T.
+     DCHAR_CPY          memcpy like function for DCHAR_T[] arrays.
+     DCHAR_SET          memset like function for DCHAR_T[] arrays.
+     DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
+     SNPRINTF           The system's snprintf (or similar) function.
+                        This may be either snprintf or swprintf.
+     TCHAR_T            The element type of the argument and result string
+                        of the said SNPRINTF function.  This may be either
+                        char or wchar_t.  The code exploits that
+                        sizeof (TCHAR_T) | sizeof (DCHAR_T) and
+                        alignof (TCHAR_T) <= alignof (DCHAR_T).
+     DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
+     DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
+     DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
+     DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
+     DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.  */
+
+/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
+   This must come before <config.h> because <config.h> may include
+   <features.h>, and once <features.h> has been included, it's too late.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE    1
+#endif
+
+#ifndef VASNPRINTF
+# include <config.h>
+#endif
+#ifndef IN_LIBINTL
+# include <alloca.h>
+#endif
+
+/* Specification.  */
+#ifndef VASNPRINTF
+# if WIDE_CHAR_VERSION
+#  include "vasnwprintf.h"
+# else
+#  include "vasnprintf.h"
+# endif
+#endif
+
+#include <locale.h>    /* localeconv() */
+#include <stdio.h>     /* snprintf(), sprintf() */
+#include <stdlib.h>    /* abort(), malloc(), realloc(), free() */
+#include <string.h>    /* memcpy(), strlen() */
+#include <errno.h>     /* errno */
+#include <limits.h>    /* CHAR_BIT */
+#include <float.h>     /* DBL_MAX_EXP, LDBL_MAX_EXP */
+#if HAVE_NL_LANGINFO
+# include <langinfo.h>
+#endif
+#ifndef VASNPRINTF
+# if WIDE_CHAR_VERSION
+#  include "wprintf-parse.h"
+# else
+#  include "printf-parse.h"
+# endif
+#endif
+
+/* Checked size_t computations.  */
+#include "xsize.h"
+
+#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
+# include <math.h>
+# include "float+.h"
+#endif
+
+#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
+# include <math.h>
+# include "isnand-nolibm.h"
+#endif
+
+#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined 
IN_LIBINTL
+# include <math.h>
+# include "isnanl-nolibm.h"
+# include "fpucw.h"
+#endif
+
+#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
+# include <math.h>
+# include "isnand-nolibm.h"
+# include "printf-frexp.h"
+#endif
+
+#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
+# include <math.h>
+# include "isnanl-nolibm.h"
+# include "printf-frexpl.h"
+# include "fpucw.h"
+#endif
+
+/* Default parameters.  */
+#ifndef VASNPRINTF
+# if WIDE_CHAR_VERSION
+#  define VASNPRINTF vasnwprintf
+#  define FCHAR_T wchar_t
+#  define DCHAR_T wchar_t
+#  define TCHAR_T wchar_t
+#  define DCHAR_IS_TCHAR 1
+#  define DIRECTIVE wchar_t_directive
+#  define DIRECTIVES wchar_t_directives
+#  define PRINTF_PARSE wprintf_parse
+#  define DCHAR_CPY wmemcpy
+#  define DCHAR_SET wmemset
+# else
+#  define VASNPRINTF vasnprintf
+#  define FCHAR_T char
+#  define DCHAR_T char
+#  define TCHAR_T char
+#  define DCHAR_IS_TCHAR 1
+#  define DIRECTIVE char_directive
+#  define DIRECTIVES char_directives
+#  define PRINTF_PARSE printf_parse
+#  define DCHAR_CPY memcpy
+#  define DCHAR_SET memset
+# endif
+#endif
+#if WIDE_CHAR_VERSION
+  /* TCHAR_T is wchar_t.  */
+# define USE_SNPRINTF 1
+# if HAVE_DECL__SNWPRINTF
+   /* On Windows, the function swprintf() has a different signature than
+      on Unix; we use the _snwprintf() function instead.  */
+#  define SNPRINTF _snwprintf
+# else
+   /* Unix.  */
+#  define SNPRINTF swprintf
+# endif
+#else
+  /* TCHAR_T is char.  */
+  /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
+     But don't use it on BeOS, since BeOS snprintf produces no output if the
+     size argument is >= 0x3000000.
+     Also don't use it on Linux libc5, since there snprintf with size = 1
+     writes any output without bounds, like sprintf.  */
+# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && 
!(__GNU_LIBRARY__ == 1)
+#  define USE_SNPRINTF 1
+# else
+#  define USE_SNPRINTF 0
+# endif
+# if HAVE_DECL__SNPRINTF
+   /* Windows.  */
+#  define SNPRINTF _snprintf
+# else
+   /* Unix.  */
+#  define SNPRINTF snprintf
+   /* Here we need to call the native snprintf, not rpl_snprintf.  */
+#  undef snprintf
+# endif
+#endif
+/* Here we need to call the native sprintf, not rpl_sprintf.  */
+#undef sprintf
+
+/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
+   warnings in this file.  Use -Dlint to suppress them.  */
+#ifdef lint
+# define IF_LINT(Code) Code
+#else
+# define IF_LINT(Code) /* empty */
+#endif
+
+/* Avoid some warnings from "gcc -Wshadow".
+   This file doesn't use the exp() and remainder() functions.  */
+#undef exp
+#define exp expo
+#undef remainder
+#define remainder rem
+
+#if !USE_SNPRINTF && !WIDE_CHAR_VERSION
+# if (HAVE_STRNLEN && !defined _AIX)
+#  define local_strnlen strnlen
+# else
+#  ifndef local_strnlen_defined
+#   define local_strnlen_defined 1
+static size_t
+local_strnlen (const char *string, size_t maxlen)
+{
+  const char *end = memchr (string, '\0', maxlen);
+  return end ? (size_t) (end - string) : maxlen;
+}
+#  endif
+# endif
+#endif
+
+#if (!USE_SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && 
HAVE_WCHAR_T && (WIDE_CHAR_VERSION || DCHAR_IS_TCHAR)
+# if HAVE_WCSLEN
+#  define local_wcslen wcslen
+# else
+   /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
+      a dependency towards this library, here is a local substitute.
+      Define this substitute only once, even if this file is included
+      twice in the same compilation unit.  */
+#  ifndef local_wcslen_defined
+#   define local_wcslen_defined 1
+static size_t
+local_wcslen (const wchar_t *s)
+{
+  const wchar_t *ptr;
+
+  for (ptr = s; *ptr != (wchar_t) 0; ptr++)
+    ;
+  return ptr - s;
+}
+#  endif
+# endif
+#endif
+
+#if !USE_SNPRINTF && HAVE_WCHAR_T && WIDE_CHAR_VERSION
+# if HAVE_WCSNLEN
+#  define local_wcsnlen wcsnlen
+# else
+#  ifndef local_wcsnlen_defined
+#   define local_wcsnlen_defined 1
+static size_t
+local_wcsnlen (const wchar_t *s, size_t maxlen)
+{
+  const wchar_t *ptr;
+
+  for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
+    ;
+  return ptr - s;
+}
+#  endif
+# endif
+#endif
+
+#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || 
NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || 
NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
+/* Determine the decimal-point character according to the current locale.  */
+# ifndef decimal_point_char_defined
+#  define decimal_point_char_defined 1
+static char
+decimal_point_char ()
+{
+  const char *point;
+  /* Determine it in a multithread-safe way.  We know nl_langinfo is
+     multithread-safe on glibc systems, but is not required to be multithread-
+     safe by POSIX.  sprintf(), however, is multithread-safe.  localeconv()
+     is rarely multithread-safe.  */
+#  if HAVE_NL_LANGINFO && __GLIBC__
+  point = nl_langinfo (RADIXCHAR);
+#  elif 1
+  char pointbuf[5];
+  sprintf (pointbuf, "%#.0f", 1.0);
+  point = &pointbuf[1];
+#  else
+  point = localeconv () -> decimal_point;
+#  endif
+  /* The decimal point is always a single byte: either '.' or ','.  */
+  return (point[0] != '\0' ? point[0] : '.');
+}
+# endif
+#endif
+
+#if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
+
+/* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
+static int
+is_infinite_or_zero (double x)
+{
+  return isnand (x) || x + x == x;
+}
+
+#endif
+
+#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined 
IN_LIBINTL
+
+/* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
+static int
+is_infinite_or_zerol (long double x)
+{
+  return isnanl (x) || x + x == x;
+}
+
+#endif
+
+#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
+
+/* Converting 'long double' to decimal without rare rounding bugs requires
+   real bignums.  We use the naming conventions of GNU gmp, but vastly simpler
+   (and slower) algorithms.  */
+
+typedef unsigned int mp_limb_t;
+# define GMP_LIMB_BITS 32
+typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == 
GMP_LIMB_BITS) - 1];
+
+typedef unsigned long long mp_twolimb_t;
+# define GMP_TWOLIMB_BITS 64
+typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == 
GMP_TWOLIMB_BITS) - 1];
+
+/* Representation of a bignum >= 0.  */
+typedef struct
+{
+  size_t nlimbs;
+  mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc().  
*/
+} mpn_t;
+
+/* Compute the product of two bignums >= 0.
+   Return the allocated memory in case of success, NULL in case of memory
+   allocation failure.  */
+static void *
+multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
+{
+  const mp_limb_t *p1;
+  const mp_limb_t *p2;
+  size_t len1;
+  size_t len2;
+
+  if (src1.nlimbs <= src2.nlimbs)
+    {
+      len1 = src1.nlimbs;
+      p1 = src1.limbs;
+      len2 = src2.nlimbs;
+      p2 = src2.limbs;
+    }
+  else
+    {
+      len1 = src2.nlimbs;
+      p1 = src2.limbs;
+      len2 = src1.nlimbs;
+      p2 = src1.limbs;
+    }
+  /* Now 0 <= len1 <= len2.  */
+  if (len1 == 0)
+    {
+      /* src1 or src2 is zero.  */
+      dest->nlimbs = 0;
+      dest->limbs = (mp_limb_t *) malloc (1);
+    }
+  else
+    {
+      /* Here 1 <= len1 <= len2.  */
+      size_t dlen;
+      mp_limb_t *dp;
+      size_t k, i, j;
+
+      dlen = len1 + len2;
+      dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
+      if (dp == NULL)
+       return NULL;
+      for (k = len2; k > 0; )
+       dp[--k] = 0;
+      for (i = 0; i < len1; i++)
+       {
+         mp_limb_t digit1 = p1[i];
+         mp_twolimb_t carry = 0;
+         for (j = 0; j < len2; j++)
+           {
+             mp_limb_t digit2 = p2[j];
+             carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
+             carry += dp[i + j];
+             dp[i + j] = (mp_limb_t) carry;
+             carry = carry >> GMP_LIMB_BITS;
+           }
+         dp[i + len2] = (mp_limb_t) carry;
+       }
+      /* Normalise.  */
+      while (dlen > 0 && dp[dlen - 1] == 0)
+       dlen--;
+      dest->nlimbs = dlen;
+      dest->limbs = dp;
+    }
+  return dest->limbs;
+}
+
+/* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
+   a is written as  a = q * b + r  with 0 <= r < b.  q is the quotient, r
+   the remainder.
+   Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
+   q is incremented.
+   Return the allocated memory in case of success, NULL in case of memory
+   allocation failure.  */
+static void *
+divide (mpn_t a, mpn_t b, mpn_t *q)
+{
+  /* Algorithm:
+     First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
+     with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
+     If m<n, then q:=0 and r:=a.
+     If m>=n=1, perform a single-precision division:
+       r:=0, j:=m,
+       while j>0 do
+         {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
+               = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
+         j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
+       Normalise [q[m-1],...,q[0]], yields q.
+     If m>=n>1, perform a multiple-precision division:
+       We have a/b < beta^(m-n+1).
+       s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
+       Shift a and b left by s bits, copying them. r:=a.
+       r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
+       For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
+         Compute q* :
+           q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
+           In case of overflow (q* >= beta) set q* := beta-1.
+           Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
+           and c3 := b[n-2] * q*.
+           {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
+            occurred.  Furthermore 0 <= c3 < beta^2.
+            If there was overflow and
+            r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
+            the next test can be skipped.}
+           While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
+             Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
+           If q* > 0:
+             Put r := r - b * q* * beta^j. In detail:
+               [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
+               hence: u:=0, for i:=0 to n-1 do
+                              u := u + q* * b[i],
+                              r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
+                              u:=u div beta (+ 1, if carry in subtraction)
+                      r[n+j]:=r[n+j]-u.
+               {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
+                               < q* + 1 <= beta,
+                the carry u does not overflow.}
+             If a negative carry occurs, put q* := q* - 1
+               and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + 
[0,b[n-1],...,b[0]].
+         Set q[j] := q*.
+       Normalise [q[m-n],..,q[0]]; this yields the quotient q.
+       Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
+       rest r.
+       The room for q[j] can be allocated at the memory location of r[n+j].
+     Finally, round-to-even:
+       Shift r left by 1 bit.
+       If r > b or if r = b and q[0] is odd, q := q+1.
+   */
+  const mp_limb_t *a_ptr = a.limbs;
+  size_t a_len = a.nlimbs;
+  const mp_limb_t *b_ptr = b.limbs;
+  size_t b_len = b.nlimbs;
+  mp_limb_t *roomptr;
+  mp_limb_t *tmp_roomptr = NULL;
+  mp_limb_t *q_ptr;
+  size_t q_len;
+  mp_limb_t *r_ptr;
+  size_t r_len;
+
+  /* Allocate room for a_len+2 digits.
+     (Need a_len+1 digits for the real division and 1 more digit for the
+     final rounding of q.)  */
+  roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
+  if (roomptr == NULL)
+    return NULL;
+
+  /* Normalise a.  */
+  while (a_len > 0 && a_ptr[a_len - 1] == 0)
+    a_len--;
+
+  /* Normalise b.  */
+  for (;;)
+    {
+      if (b_len == 0)
+       /* Division by zero.  */
+       abort ();
+      if (b_ptr[b_len - 1] == 0)
+       b_len--;
+      else
+       break;
+    }
+
+  /* Here m = a_len >= 0 and n = b_len > 0.  */
+
+  if (a_len < b_len)
+    {
+      /* m<n: trivial case.  q=0, r := copy of a.  */
+      r_ptr = roomptr;
+      r_len = a_len;
+      memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
+      q_ptr = roomptr + a_len;
+      q_len = 0;
+    }
+  else if (b_len == 1)
+    {
+      /* n=1: single precision division.
+        beta^(m-1) <= a < beta^m  ==>  beta^(m-2) <= a/b < beta^m  */
+      r_ptr = roomptr;
+      q_ptr = roomptr + 1;
+      {
+       mp_limb_t den = b_ptr[0];
+       mp_limb_t remainder = 0;
+       const mp_limb_t *sourceptr = a_ptr + a_len;
+       mp_limb_t *destptr = q_ptr + a_len;
+       size_t count;
+       for (count = a_len; count > 0; count--)
+         {
+           mp_twolimb_t num =
+             ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
+           *--destptr = num / den;
+           remainder = num % den;
+         }
+       /* Normalise and store r.  */
+       if (remainder > 0)
+         {
+           r_ptr[0] = remainder;
+           r_len = 1;
+         }
+       else
+         r_len = 0;
+       /* Normalise q.  */
+       q_len = a_len;
+       if (q_ptr[q_len - 1] == 0)
+         q_len--;
+      }
+    }
+  else
+    {
+      /* n>1: multiple precision division.
+        beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n  ==>
+        beta^(m-n-1) <= a/b < beta^(m-n+1).  */
+      /* Determine s.  */
+      size_t s;
+      {
+       mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
+       s = 31;
+       if (msd >= 0x10000)
+         {
+           msd = msd >> 16;
+           s -= 16;
+         }
+       if (msd >= 0x100)
+         {
+           msd = msd >> 8;
+           s -= 8;
+         }
+       if (msd >= 0x10)
+         {
+           msd = msd >> 4;
+           s -= 4;
+         }
+       if (msd >= 0x4)
+         {
+           msd = msd >> 2;
+           s -= 2;
+         }
+       if (msd >= 0x2)
+         {
+           msd = msd >> 1;
+           s -= 1;
+         }
+      }
+      /* 0 <= s < GMP_LIMB_BITS.
+        Copy b, shifting it left by s bits.  */
+      if (s > 0)
+       {
+         tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
+         if (tmp_roomptr == NULL)
+           {
+             free (roomptr);
+             return NULL;
+           }
+         {
+           const mp_limb_t *sourceptr = b_ptr;
+           mp_limb_t *destptr = tmp_roomptr;
+           mp_twolimb_t accu = 0;
+           size_t count;
+           for (count = b_len; count > 0; count--)
+             {
+               accu += (mp_twolimb_t) *sourceptr++ << s;
+               *destptr++ = (mp_limb_t) accu;
+               accu = accu >> GMP_LIMB_BITS;
+             }
+           /* accu must be zero, since that was how s was determined.  */
+           if (accu != 0)
+             abort ();
+         }
+         b_ptr = tmp_roomptr;
+       }
+      /* Copy a, shifting it left by s bits, yields r.
+        Memory layout:
+        At the beginning: r = roomptr[0..a_len],
+        at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len]  */
+      r_ptr = roomptr;
+      if (s == 0)
+       {
+         memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
+         r_ptr[a_len] = 0;
+       }
+      else
+       {
+         const mp_limb_t *sourceptr = a_ptr;
+         mp_limb_t *destptr = r_ptr;
+         mp_twolimb_t accu = 0;
+         size_t count;
+         for (count = a_len; count > 0; count--)
+           {
+             accu += (mp_twolimb_t) *sourceptr++ << s;
+             *destptr++ = (mp_limb_t) accu;
+             accu = accu >> GMP_LIMB_BITS;
+           }
+         *destptr++ = (mp_limb_t) accu;
+       }
+      q_ptr = roomptr + b_len;
+      q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
+      {
+       size_t j = a_len - b_len; /* m-n */
+       mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
+       mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
+       mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
+         ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
+       /* Division loop, traversed m-n+1 times.
+          j counts down, b is unchanged, beta/2 <= b[n-1] < beta.  */
+       for (;;)
+         {
+           mp_limb_t q_star;
+           mp_limb_t c1;
+           if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
+             {
+               /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow.  */
+               mp_twolimb_t num =
+                 ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
+                 | r_ptr[j + b_len - 1];
+               q_star = num / b_msd;
+               c1 = num % b_msd;
+             }
+           else
+             {
+               /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1].  */
+               q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
+               /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
+                  <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
+                  <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
+                       {<= beta !}.
+                  If yes, jump directly to the subtraction loop.
+                  (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
+                   <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
+               if (r_ptr[j + b_len] > b_msd
+                   || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
+                 /* r[j+n] >= b[n-1]+1 or
+                    r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
+                    carry.  */
+                 goto subtract;
+             }
+           /* q_star = q*,
+              c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta).  */
+           {
+             mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
+               ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
+             mp_twolimb_t c3 = /* b[n-2] * q* */
+               (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
+             /* While c2 < c3, increase c2 and decrease c3.
+                Consider c3-c2.  While it is > 0, decrease it by
+                b[n-1]*beta+b[n-2].  Because of b[n-1]*beta+b[n-2] >= beta^2/2
+                this can happen only twice.  */
+             if (c3 > c2)
+               {
+                 q_star = q_star - 1; /* q* := q* - 1 */
+                 if (c3 - c2 > b_msdd)
+                   q_star = q_star - 1; /* q* := q* - 1 */
+               }
+           }
+           if (q_star > 0)
+             subtract:
+             {
+               /* Subtract r := r - b * q* * beta^j.  */
+               mp_limb_t cr;
+               {
+                 const mp_limb_t *sourceptr = b_ptr;
+                 mp_limb_t *destptr = r_ptr + j;
+                 mp_twolimb_t carry = 0;
+                 size_t count;
+                 for (count = b_len; count > 0; count--)
+                   {
+                     /* Here 0 <= carry <= q*.  */
+                     carry =
+                       carry
+                       + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
+                       + (mp_limb_t) ~(*destptr);
+                     /* Here 0 <= carry <= beta*q* + beta-1.  */
+                     *destptr++ = ~(mp_limb_t) carry;
+                     carry = carry >> GMP_LIMB_BITS; /* <= q* */
+                   }
+                 cr = (mp_limb_t) carry;
+               }
+               /* Subtract cr from r_ptr[j + b_len], then forget about
+                  r_ptr[j + b_len].  */
+               if (cr > r_ptr[j + b_len])
+                 {
+                   /* Subtraction gave a carry.  */
+                   q_star = q_star - 1; /* q* := q* - 1 */
+                   /* Add b back.  */
+                   {
+                     const mp_limb_t *sourceptr = b_ptr;
+                     mp_limb_t *destptr = r_ptr + j;
+                     mp_limb_t carry = 0;
+                     size_t count;
+                     for (count = b_len; count > 0; count--)
+                       {
+                         mp_limb_t source1 = *sourceptr++;
+                         mp_limb_t source2 = *destptr;
+                         *destptr++ = source1 + source2 + carry;
+                         carry =
+                           (carry
+                            ? source1 >= (mp_limb_t) ~source2
+                            : source1 > (mp_limb_t) ~source2);
+                       }
+                   }
+                   /* Forget about the carry and about r[j+n].  */
+                 }
+             }
+           /* q* is determined.  Store it as q[j].  */
+           q_ptr[j] = q_star;
+           if (j == 0)
+             break;
+           j--;
+         }
+      }
+      r_len = b_len;
+      /* Normalise q.  */
+      if (q_ptr[q_len - 1] == 0)
+       q_len--;
+# if 0 /* Not needed here, since we need r only to compare it with b/2, and
+         b is shifted left by s bits.  */
+      /* Shift r right by s bits.  */
+      if (s > 0)
+       {
+         mp_limb_t ptr = r_ptr + r_len;
+         mp_twolimb_t accu = 0;
+         size_t count;
+         for (count = r_len; count > 0; count--)
+           {
+             accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
+             accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
+             *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
+           }
+       }
+# endif
+      /* Normalise r.  */
+      while (r_len > 0 && r_ptr[r_len - 1] == 0)
+       r_len--;
+    }
+  /* Compare r << 1 with b.  */
+  if (r_len > b_len)
+    goto increment_q;
+  {
+    size_t i;
+    for (i = b_len;;)
+      {
+       mp_limb_t r_i =
+         (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
+         | (i < r_len ? r_ptr[i] << 1 : 0);
+       mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
+       if (r_i > b_i)
+         goto increment_q;
+       if (r_i < b_i)
+         goto keep_q;
+       if (i == 0)
+         break;
+       i--;
+      }
+  }
+  if (q_len > 0 && ((q_ptr[0] & 1) != 0))
+    /* q is odd.  */
+    increment_q:
+    {
+      size_t i;
+      for (i = 0; i < q_len; i++)
+       if (++(q_ptr[i]) != 0)
+         goto keep_q;
+      q_ptr[q_len++] = 1;
+    }
+  keep_q:
+  if (tmp_roomptr != NULL)
+    free (tmp_roomptr);
+  q->limbs = q_ptr;
+  q->nlimbs = q_len;
+  return roomptr;
+}
+
+/* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
+   representation.
+   Destroys the contents of a.
+   Return the allocated memory - containing the decimal digits in low-to-high
+   order, terminated with a NUL character - in case of success, NULL in case
+   of memory allocation failure.  */
+static char *
+convert_to_decimal (mpn_t a, size_t extra_zeroes)
+{
+  mp_limb_t *a_ptr = a.limbs;
+  size_t a_len = a.nlimbs;
+  /* 0.03345 is slightly larger than log(2)/(9*log(10)).  */
+  size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
+  char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
+  if (c_ptr != NULL)
+    {
+      char *d_ptr = c_ptr;
+      for (; extra_zeroes > 0; extra_zeroes--)
+       *d_ptr++ = '0';
+      while (a_len > 0)
+       {
+         /* Divide a by 10^9, in-place.  */
+         mp_limb_t remainder = 0;
+         mp_limb_t *ptr = a_ptr + a_len;
+         size_t count;
+         for (count = a_len; count > 0; count--)
+           {
+             mp_twolimb_t num =
+               ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
+             *ptr = num / 1000000000;
+             remainder = num % 1000000000;
+           }
+         /* Store the remainder as 9 decimal digits.  */
+         for (count = 9; count > 0; count--)
+           {
+             *d_ptr++ = '0' + (remainder % 10);
+             remainder = remainder / 10;
+           }
+         /* Normalize a.  */
+         if (a_ptr[a_len - 1] == 0)
+           a_len--;
+       }
+      /* Remove leading zeroes.  */
+      while (d_ptr > c_ptr && d_ptr[-1] == '0')
+       d_ptr--;
+      /* But keep at least one zero.  */
+      if (d_ptr == c_ptr)
+       *d_ptr++ = '0';
+      /* Terminate the string.  */
+      *d_ptr = '\0';
+    }
+  return c_ptr;
+}
+
+# if NEED_PRINTF_LONG_DOUBLE
+
+/* Assuming x is finite and >= 0:
+   write x as x = 2^e * m, where m is a bignum.
+   Return the allocated memory in case of success, NULL in case of memory
+   allocation failure.  */
+static void *
+decode_long_double (long double x, int *ep, mpn_t *mp)
+{
+  mpn_t m;
+  int exp;
+  long double y;
+  size_t i;
+
+  /* Allocate memory for result.  */
+  m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
+  m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
+  if (m.limbs == NULL)
+    return NULL;
+  /* Split into exponential part and mantissa.  */
+  y = frexpl (x, &exp);
+  if (!(y >= 0.0L && y < 1.0L))
+    abort ();
+  /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
+     latter is an integer.  */
+  /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
+     I'm not sure whether it's safe to cast a 'long double' value between
+     2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
+     'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
+     doesn't matter).  */
+#  if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
+#   if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
+    {
+      mp_limb_t hi, lo;
+      y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
+      hi = (int) y;
+      y -= hi;
+      if (!(y >= 0.0L && y < 1.0L))
+       abort ();
+      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
+      lo = (int) y;
+      y -= lo;
+      if (!(y >= 0.0L && y < 1.0L))
+       abort ();
+      m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | 
lo;
+    }
+#   else
+    {
+      mp_limb_t d;
+      y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
+      d = (int) y;
+      y -= d;
+      if (!(y >= 0.0L && y < 1.0L))
+       abort ();
+      m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
+    }
+#   endif
+#  endif
+  for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
+    {
+      mp_limb_t hi, lo;
+      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
+      hi = (int) y;
+      y -= hi;
+      if (!(y >= 0.0L && y < 1.0L))
+       abort ();
+      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
+      lo = (int) y;
+      y -= lo;
+      if (!(y >= 0.0L && y < 1.0L))
+       abort ();
+      m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
+    }
+#if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
+         precision.  */
+  if (!(y == 0.0L))
+    abort ();
+#endif
+  /* Normalise.  */
+  while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
+    m.nlimbs--;
+  *mp = m;
+  *ep = exp - LDBL_MANT_BIT;
+  return m.limbs;
+}
+
+# endif
+
+# if NEED_PRINTF_DOUBLE
+
+/* Assuming x is finite and >= 0:
+   write x as x = 2^e * m, where m is a bignum.
+   Return the allocated memory in case of success, NULL in case of memory
+   allocation failure.  */
+static void *
+decode_double (double x, int *ep, mpn_t *mp)
+{
+  mpn_t m;
+  int exp;
+  double y;
+  size_t i;
+
+  /* Allocate memory for result.  */
+  m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
+  m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
+  if (m.limbs == NULL)
+    return NULL;
+  /* Split into exponential part and mantissa.  */
+  y = frexp (x, &exp);
+  if (!(y >= 0.0 && y < 1.0))
+    abort ();
+  /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the
+     latter is an integer.  */
+  /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs.
+     I'm not sure whether it's safe to cast a 'double' value between
+     2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
+     'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
+     doesn't matter).  */
+#  if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
+#   if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
+    {
+      mp_limb_t hi, lo;
+      y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
+      hi = (int) y;
+      y -= hi;
+      if (!(y >= 0.0 && y < 1.0))
+       abort ();
+      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
+      lo = (int) y;
+      y -= lo;
+      if (!(y >= 0.0 && y < 1.0))
+       abort ();
+      m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
+    }
+#   else
+    {
+      mp_limb_t d;
+      y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
+      d = (int) y;
+      y -= d;
+      if (!(y >= 0.0 && y < 1.0))
+       abort ();
+      m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
+    }
+#   endif
+#  endif
+  for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
+    {
+      mp_limb_t hi, lo;
+      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
+      hi = (int) y;
+      y -= hi;
+      if (!(y >= 0.0 && y < 1.0))
+       abort ();
+      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
+      lo = (int) y;
+      y -= lo;
+      if (!(y >= 0.0 && y < 1.0))
+       abort ();
+      m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
+    }
+  if (!(y == 0.0))
+    abort ();
+  /* Normalise.  */
+  while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
+    m.nlimbs--;
+  *mp = m;
+  *ep = exp - DBL_MANT_BIT;
+  return m.limbs;
+}
+
+# endif
+
+/* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
+   Returns the decimal representation of round (x * 10^n).
+   Return the allocated memory - containing the decimal digits in low-to-high
+   order, terminated with a NUL character - in case of success, NULL in case
+   of memory allocation failure.  */
+static char *
+scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
+{
+  int s;
+  size_t extra_zeroes;
+  unsigned int abs_n;
+  unsigned int abs_s;
+  mp_limb_t *pow5_ptr;
+  size_t pow5_len;
+  unsigned int s_limbs;
+  unsigned int s_bits;
+  mpn_t pow5;
+  mpn_t z;
+  void *z_memory;
+  char *digits;
+
+  if (memory == NULL)
+    return NULL;
+  /* x = 2^e * m, hence
+     y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
+       = round (2^s * 5^n * m).  */
+  s = e + n;
+  extra_zeroes = 0;
+  /* Factor out a common power of 10 if possible.  */
+  if (s > 0 && n > 0)
+    {
+      extra_zeroes = (s < n ? s : n);
+      s -= extra_zeroes;
+      n -= extra_zeroes;
+    }
+  /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
+     Before converting to decimal, we need to compute
+     z = round (2^s * 5^n * m).  */
+  /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
+     sign.  2.322 is slightly larger than log(5)/log(2).  */
+  abs_n = (n >= 0 ? n : -n);
+  abs_s = (s >= 0 ? s : -s);
+  pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
+                                   + abs_s / GMP_LIMB_BITS + 1)
+                                  * sizeof (mp_limb_t));
+  if (pow5_ptr == NULL)
+    {
+      free (memory);
+      return NULL;
+    }
+  /* Initialize with 1.  */
+  pow5_ptr[0] = 1;
+  pow5_len = 1;
+  /* Multiply with 5^|n|.  */
+  if (abs_n > 0)
+    {
+      static mp_limb_t const small_pow5[13 + 1] =
+       {
+         1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
+         48828125, 244140625, 1220703125
+       };
+      unsigned int n13;
+      for (n13 = 0; n13 <= abs_n; n13 += 13)
+       {
+         mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
+         size_t j;
+         mp_twolimb_t carry = 0;
+         for (j = 0; j < pow5_len; j++)
+           {
+             mp_limb_t digit2 = pow5_ptr[j];
+             carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
+             pow5_ptr[j] = (mp_limb_t) carry;
+             carry = carry >> GMP_LIMB_BITS;
+           }
+         if (carry > 0)
+           pow5_ptr[pow5_len++] = (mp_limb_t) carry;
+       }
+    }
+  s_limbs = abs_s / GMP_LIMB_BITS;
+  s_bits = abs_s % GMP_LIMB_BITS;
+  if (n >= 0 ? s >= 0 : s <= 0)
+    {
+      /* Multiply with 2^|s|.  */
+      if (s_bits > 0)
+       {
+         mp_limb_t *ptr = pow5_ptr;
+         mp_twolimb_t accu = 0;
+         size_t count;
+         for (count = pow5_len; count > 0; count--)
+           {
+             accu += (mp_twolimb_t) *ptr << s_bits;
+             *ptr++ = (mp_limb_t) accu;
+             accu = accu >> GMP_LIMB_BITS;
+           }
+         if (accu > 0)
+           {
+             *ptr = (mp_limb_t) accu;
+             pow5_len++;
+           }
+       }
+      if (s_limbs > 0)
+       {
+         size_t count;
+         for (count = pow5_len; count > 0;)
+           {
+             count--;
+             pow5_ptr[s_limbs + count] = pow5_ptr[count];
+           }
+         for (count = s_limbs; count > 0;)
+           {
+             count--;
+             pow5_ptr[count] = 0;
+           }
+         pow5_len += s_limbs;
+       }
+      pow5.limbs = pow5_ptr;
+      pow5.nlimbs = pow5_len;
+      if (n >= 0)
+       {
+         /* Multiply m with pow5.  No division needed.  */
+         z_memory = multiply (m, pow5, &z);
+       }
+      else
+       {
+         /* Divide m by pow5 and round.  */
+         z_memory = divide (m, pow5, &z);
+       }
+    }
+  else
+    {
+      pow5.limbs = pow5_ptr;
+      pow5.nlimbs = pow5_len;
+      if (n >= 0)
+       {
+         /* n >= 0, s < 0.
+            Multiply m with pow5, then divide by 2^|s|.  */
+         mpn_t numerator;
+         mpn_t denominator;
+         void *tmp_memory;
+         tmp_memory = multiply (m, pow5, &numerator);
+         if (tmp_memory == NULL)
+           {
+             free (pow5_ptr);
+             free (memory);
+             return NULL;
+           }
+         /* Construct 2^|s|.  */
+         {
+           mp_limb_t *ptr = pow5_ptr + pow5_len;
+           size_t i;
+           for (i = 0; i < s_limbs; i++)
+             ptr[i] = 0;
+           ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
+           denominator.limbs = ptr;
+           denominator.nlimbs = s_limbs + 1;
+         }
+         z_memory = divide (numerator, denominator, &z);
+         free (tmp_memory);
+       }
+      else
+       {
+         /* n < 0, s > 0.
+            Multiply m with 2^s, then divide by pow5.  */
+         mpn_t numerator;
+         mp_limb_t *num_ptr;
+         num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
+                                         * sizeof (mp_limb_t));
+         if (num_ptr == NULL)
+           {
+             free (pow5_ptr);
+             free (memory);
+             return NULL;
+           }
+         {
+           mp_limb_t *destptr = num_ptr;
+           {
+             size_t i;
+             for (i = 0; i < s_limbs; i++)
+               *destptr++ = 0;
+           }
+           if (s_bits > 0)
+             {
+               const mp_limb_t *sourceptr = m.limbs;
+               mp_twolimb_t accu = 0;
+               size_t count;
+               for (count = m.nlimbs; count > 0; count--)
+                 {
+                   accu += (mp_twolimb_t) *sourceptr++ << s_bits;
+                   *destptr++ = (mp_limb_t) accu;
+                   accu = accu >> GMP_LIMB_BITS;
+                 }
+               if (accu > 0)
+                 *destptr++ = (mp_limb_t) accu;
+             }
+           else
+             {
+               const mp_limb_t *sourceptr = m.limbs;
+               size_t count;
+               for (count = m.nlimbs; count > 0; count--)
+                 *destptr++ = *sourceptr++;
+             }
+           numerator.limbs = num_ptr;
+           numerator.nlimbs = destptr - num_ptr;
+         }
+         z_memory = divide (numerator, pow5, &z);
+         free (num_ptr);
+       }
+    }
+  free (pow5_ptr);
+  free (memory);
+
+  /* Here y = round (x * 10^n) = z * 10^extra_zeroes.  */
+
+  if (z_memory == NULL)
+    return NULL;
+  digits = convert_to_decimal (z, extra_zeroes);
+  free (z_memory);
+  return digits;
+}
+
+# if NEED_PRINTF_LONG_DOUBLE
+
+/* Assuming x is finite and >= 0, and n is an integer:
+   Returns the decimal representation of round (x * 10^n).
+   Return the allocated memory - containing the decimal digits in low-to-high
+   order, terminated with a NUL character - in case of success, NULL in case
+   of memory allocation failure.  */
+static char *
+scale10_round_decimal_long_double (long double x, int n)
+{
+  int e IF_LINT(= 0);
+  mpn_t m;
+  void *memory = decode_long_double (x, &e, &m);
+  return scale10_round_decimal_decoded (e, m, memory, n);
+}
+
+# endif
+
+# if NEED_PRINTF_DOUBLE
+
+/* Assuming x is finite and >= 0, and n is an integer:
+   Returns the decimal representation of round (x * 10^n).
+   Return the allocated memory - containing the decimal digits in low-to-high
+   order, terminated with a NUL character - in case of success, NULL in case
+   of memory allocation failure.  */
+static char *
+scale10_round_decimal_double (double x, int n)
+{
+  int e IF_LINT(= 0);
+  mpn_t m;
+  void *memory = decode_double (x, &e, &m);
+  return scale10_round_decimal_decoded (e, m, memory, n);
+}
+
+# endif
+
+# if NEED_PRINTF_LONG_DOUBLE
+
+/* Assuming x is finite and > 0:
+   Return an approximation for n with 10^n <= x < 10^(n+1).
+   The approximation is usually the right n, but may be off by 1 sometimes.  */
+static int
+floorlog10l (long double x)
+{
+  int exp;
+  long double y;
+  double z;
+  double l;
+
+  /* Split into exponential part and mantissa.  */
+  y = frexpl (x, &exp);
+  if (!(y >= 0.0L && y < 1.0L))
+    abort ();
+  if (y == 0.0L)
+    return INT_MIN;
+  if (y < 0.5L)
+    {
+      while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 
2))))
+       {
+         y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
+         exp -= GMP_LIMB_BITS;
+       }
+      if (y < (1.0L / (1 << 16)))
+       {
+         y *= 1.0L * (1 << 16);
+         exp -= 16;
+       }
+      if (y < (1.0L / (1 << 8)))
+       {
+         y *= 1.0L * (1 << 8);
+         exp -= 8;
+       }
+      if (y < (1.0L / (1 << 4)))
+       {
+         y *= 1.0L * (1 << 4);
+         exp -= 4;
+       }
+      if (y < (1.0L / (1 << 2)))
+       {
+         y *= 1.0L * (1 << 2);
+         exp -= 2;
+       }
+      if (y < (1.0L / (1 << 1)))
+       {
+         y *= 1.0L * (1 << 1);
+         exp -= 1;
+       }
+    }
+  if (!(y >= 0.5L && y < 1.0L))
+    abort ();
+  /* Compute an approximation for l = log2(x) = exp + log2(y).  */
+  l = exp;
+  z = y;
+  if (z < 0.70710678118654752444)
+    {
+      z *= 1.4142135623730950488;
+      l -= 0.5;
+    }
+  if (z < 0.8408964152537145431)
+    {
+      z *= 1.1892071150027210667;
+      l -= 0.25;
+    }
+  if (z < 0.91700404320467123175)
+    {
+      z *= 1.0905077326652576592;
+      l -= 0.125;
+    }
+  if (z < 0.9576032806985736469)
+    {
+      z *= 1.0442737824274138403;
+      l -= 0.0625;
+    }
+  /* Now 0.95 <= z <= 1.01.  */
+  z = 1 - z;
+  /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
+     Four terms are enough to get an approximation with error < 10^-7.  */
+  l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 
0.25)));
+  /* Finally multiply with log(2)/log(10), yields an approximation for
+     log10(x).  */
+  l *= 0.30102999566398119523;
+  /* Round down to the next integer.  */
+  return (int) l + (l < 0 ? -1 : 0);
+}
+
+# endif
+
+# if NEED_PRINTF_DOUBLE
+
+/* Assuming x is finite and > 0:
+   Return an approximation for n with 10^n <= x < 10^(n+1).
+   The approximation is usually the right n, but may be off by 1 sometimes.  */
+static int
+floorlog10 (double x)
+{
+  int exp;
+  double y;
+  double z;
+  double l;
+
+  /* Split into exponential part and mantissa.  */
+  y = frexp (x, &exp);
+  if (!(y >= 0.0 && y < 1.0))
+    abort ();
+  if (y == 0.0)
+    return INT_MIN;
+  if (y < 0.5)
+    {
+      while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 
2))))
+       {
+         y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
+         exp -= GMP_LIMB_BITS;
+       }
+      if (y < (1.0 / (1 << 16)))
+       {
+         y *= 1.0 * (1 << 16);
+         exp -= 16;
+       }
+      if (y < (1.0 / (1 << 8)))
+       {
+         y *= 1.0 * (1 << 8);
+         exp -= 8;
+       }
+      if (y < (1.0 / (1 << 4)))
+       {
+         y *= 1.0 * (1 << 4);
+         exp -= 4;
+       }
+      if (y < (1.0 / (1 << 2)))
+       {
+         y *= 1.0 * (1 << 2);
+         exp -= 2;
+       }
+      if (y < (1.0 / (1 << 1)))
+       {
+         y *= 1.0 * (1 << 1);
+         exp -= 1;
+       }
+    }
+  if (!(y >= 0.5 && y < 1.0))
+    abort ();
+  /* Compute an approximation for l = log2(x) = exp + log2(y).  */
+  l = exp;
+  z = y;
+  if (z < 0.70710678118654752444)
+    {
+      z *= 1.4142135623730950488;
+      l -= 0.5;
+    }
+  if (z < 0.8408964152537145431)
+    {
+      z *= 1.1892071150027210667;
+      l -= 0.25;
+    }
+  if (z < 0.91700404320467123175)
+    {
+      z *= 1.0905077326652576592;
+      l -= 0.125;
+    }
+  if (z < 0.9576032806985736469)
+    {
+      z *= 1.0442737824274138403;
+      l -= 0.0625;
+    }
+  /* Now 0.95 <= z <= 1.01.  */
+  z = 1 - z;
+  /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
+     Four terms are enough to get an approximation with error < 10^-7.  */
+  l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 
0.25)));
+  /* Finally multiply with log(2)/log(10), yields an approximation for
+     log10(x).  */
+  l *= 0.30102999566398119523;
+  /* Round down to the next integer.  */
+  return (int) l + (l < 0 ? -1 : 0);
+}
+
+# endif
+
+/* Tests whether a string of digits consists of exactly PRECISION zeroes and
+   a single '1' digit.  */
+static int
+is_borderline (const char *digits, size_t precision)
+{
+  for (; precision > 0; precision--, digits++)
+    if (*digits != '0')
+      return 0;
+  if (*digits != '1')
+    return 0;
+  digits++;
+  return *digits == '\0';
+}
+
+#endif
+
+DCHAR_T *
+VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
+           const FCHAR_T *format, va_list args)
+{
+  DIRECTIVES d;
+  arguments a;
+
+  if (PRINTF_PARSE (format, &d, &a) < 0)
+    /* errno is already set.  */
+    return NULL;
+
+#define CLEANUP() \
+  free (d.dir);                                                                
\
+  if (a.arg)                                                           \
+    free (a.arg);
+
+  if (PRINTF_FETCHARGS (args, &a) < 0)
+    {
+      CLEANUP ();
+      errno = EINVAL;
+      return NULL;
+    }
+
+  {
+    size_t buf_neededlength;
+    TCHAR_T *buf;
+    TCHAR_T *buf_malloced;
+    const FCHAR_T *cp;
+    size_t i;
+    DIRECTIVE *dp;
+    /* Output string accumulator.  */
+    DCHAR_T *result;
+    size_t allocated;
+    size_t length;
+
+    /* Allocate a small buffer that will hold a directive passed to
+       sprintf or snprintf.  */
+    buf_neededlength =
+      xsum4 (7, d.max_width_length, d.max_precision_length, 6);
+#if HAVE_ALLOCA
+    if (buf_neededlength < 4000 / sizeof (TCHAR_T))
+      {
+       buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
+       buf_malloced = NULL;
+      }
+    else
+#endif
+      {
+       size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
+       if (size_overflow_p (buf_memsize))
+         goto out_of_memory_1;
+       buf = (TCHAR_T *) malloc (buf_memsize);
+       if (buf == NULL)
+         goto out_of_memory_1;
+       buf_malloced = buf;
+      }
+
+    if (resultbuf != NULL)
+      {
+       result = resultbuf;
+       allocated = *lengthp;
+      }
+    else
+      {
+       result = NULL;
+       allocated = 0;
+      }
+    length = 0;
+    /* Invariants:
+       result is either == resultbuf or == NULL or malloc-allocated.
+       If length > 0, then result != NULL.  */
+
+    /* Ensures that allocated >= needed.  Aborts through a jump to
+       out_of_memory if needed is SIZE_MAX or otherwise too big.  */
+#define ENSURE_ALLOCATION(needed) \
+    if ((needed) > allocated)                                               \
+      {                                                                        
     \
+       size_t memory_size;                                                  \
+       DCHAR_T *memory;                                                     \
+                                                                            \
+       allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
+       if ((needed) > allocated)                                            \
+         allocated = (needed);                                              \
+       memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
+       if (size_overflow_p (memory_size))                                   \
+         goto out_of_memory;                                                \
+       if (result == resultbuf || result == NULL)                           \
+         memory = (DCHAR_T *) malloc (memory_size);                         \
+       else                                                                 \
+         memory = (DCHAR_T *) realloc (result, memory_size);                \
+       if (memory == NULL)                                                  \
+         goto out_of_memory;                                                \
+       if (result == resultbuf && length > 0)                               \
+         DCHAR_CPY (memory, result, length);                                \
+       result = memory;                                                     \
+      }
+
+    for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
+      {
+       if (cp != dp->dir_start)
+         {
+           size_t n = dp->dir_start - cp;
+           size_t augmented_length = xsum (length, n);
+
+           ENSURE_ALLOCATION (augmented_length);
+           /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
+              need that the format string contains only ASCII characters
+              if FCHAR_T and DCHAR_T are not the same type.  */
+           if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
+             {
+               DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
+               length = augmented_length;
+             }
+           else
+             {
+               do
+                 result[length++] = (unsigned char) *cp++;
+               while (--n > 0);
+             }
+         }
+       if (i == d.count)
+         break;
+
+       /* Execute a single directive.  */
+       if (dp->conversion == '%')
+         {
+           size_t augmented_length;
+
+           if (!(dp->arg_index == ARG_NONE))
+             abort ();
+           augmented_length = xsum (length, 1);
+           ENSURE_ALLOCATION (augmented_length);
+           result[length] = '%';
+           length = augmented_length;
+         }
+       else
+         {
+           if (!(dp->arg_index != ARG_NONE))
+             abort ();
+
+           if (dp->conversion == 'n')
+             {
+               switch (a.arg[dp->arg_index].type)
+                 {
+                 case TYPE_COUNT_SCHAR_POINTER:
+                   *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
+                   break;
+                 case TYPE_COUNT_SHORT_POINTER:
+                   *a.arg[dp->arg_index].a.a_count_short_pointer = length;
+                   break;
+                 case TYPE_COUNT_INT_POINTER:
+                   *a.arg[dp->arg_index].a.a_count_int_pointer = length;
+                   break;
+                 case TYPE_COUNT_LONGINT_POINTER:
+                   *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
+                   break;
+#if HAVE_LONG_LONG_INT
+                 case TYPE_COUNT_LONGLONGINT_POINTER:
+                   *a.arg[dp->arg_index].a.a_count_longlongint_pointer = 
length;
+                   break;
+#endif
+                 default:
+                   abort ();
+                 }
+             }
+#if ENABLE_UNISTDIO
+           /* The unistdio extensions.  */
+           else if (dp->conversion == 'U')
+             {
+               arg_type type = a.arg[dp->arg_index].type;
+               int flags = dp->flags;
+               int has_width;
+               size_t width;
+               int has_precision;
+               size_t precision;
+
+               has_width = 0;
+               width = 0;
+               if (dp->width_start != dp->width_end)
+                 {
+                   if (dp->width_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->width_arg_index].a.a_int;
+                       if (arg < 0)
+                         {
+                           /* "A negative field width is taken as a '-' flag
+                               followed by a positive field width."  */
+                           flags |= FLAG_LEFT;
+                           width = (unsigned int) (-arg);
+                         }
+                       else
+                         width = arg;
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->width_start;
+
+                       do
+                         width = xsum (xtimes (width, 10), *digitp++ - '0');
+                       while (digitp != dp->width_end);
+                     }
+                   has_width = 1;
+                 }
+
+               has_precision = 0;
+               precision = 0;
+               if (dp->precision_start != dp->precision_end)
+                 {
+                   if (dp->precision_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->precision_arg_index].a.a_int;
+                       /* "A negative precision is taken as if the precision
+                           were omitted."  */
+                       if (arg >= 0)
+                         {
+                           precision = arg;
+                           has_precision = 1;
+                         }
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->precision_start + 1;
+
+                       precision = 0;
+                       while (digitp != dp->precision_end)
+                         precision = xsum (xtimes (precision, 10), *digitp++ - 
'0');
+                       has_precision = 1;
+                     }
+                 }
+
+               switch (type)
+                 {
+                 case TYPE_U8_STRING:
+                   {
+                     const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
+                     const uint8_t *arg_end;
+                     size_t characters;
+
+                     if (has_precision)
+                       {
+                         /* Use only PRECISION characters, from the left.  */
+                         arg_end = arg;
+                         characters = 0;
+                         for (; precision > 0; precision--)
+                           {
+                             int count = u8_strmblen (arg_end);
+                             if (count == 0)
+                               break;
+                             if (count < 0)
+                               {
+                                 if (!(result == resultbuf || result == NULL))
+                                   free (result);
+                                 if (buf_malloced != NULL)
+                                   free (buf_malloced);
+                                 CLEANUP ();
+                                 errno = EILSEQ;
+                                 return NULL;
+                               }
+                             arg_end += count;
+                             characters++;
+                           }
+                       }
+                     else if (has_width)
+                       {
+                         /* Use the entire string, and count the number of
+                            characters.  */
+                         arg_end = arg;
+                         characters = 0;
+                         for (;;)
+                           {
+                             int count = u8_strmblen (arg_end);
+                             if (count == 0)
+                               break;
+                             if (count < 0)
+                               {
+                                 if (!(result == resultbuf || result == NULL))
+                                   free (result);
+                                 if (buf_malloced != NULL)
+                                   free (buf_malloced);
+                                 CLEANUP ();
+                                 errno = EILSEQ;
+                                 return NULL;
+                               }
+                             arg_end += count;
+                             characters++;
+                           }
+                       }
+                     else
+                       {
+                         /* Use the entire string.  */
+                         arg_end = arg + u8_strlen (arg);
+                         /* The number of characters doesn't matter.  */
+                         characters = 0;
+                       }
+
+                     if (has_width && width > characters
+                         && !(dp->flags & FLAG_LEFT))
+                       {
+                         size_t n = width - characters;
+                         ENSURE_ALLOCATION (xsum (length, n));
+                         DCHAR_SET (result + length, ' ', n);
+                         length += n;
+                       }
+
+# if DCHAR_IS_UINT8_T
+                     {
+                       size_t n = arg_end - arg;
+                       ENSURE_ALLOCATION (xsum (length, n));
+                       DCHAR_CPY (result + length, arg, n);
+                       length += n;
+                     }
+# else
+                     { /* Convert.  */
+                       DCHAR_T *converted = result + length;
+                       size_t converted_len = allocated - length;
+#  if DCHAR_IS_TCHAR
+                       /* Convert from UTF-8 to locale encoding.  */
+                       converted =
+                         u8_conv_to_encoding (locale_charset (),
+                                              iconveh_question_mark,
+                                              arg, arg_end - arg, NULL,
+                                              converted, &converted_len);
+#  else
+                       /* Convert from UTF-8 to UTF-16/UTF-32.  */
+                       converted =
+                         U8_TO_DCHAR (arg, arg_end - arg,
+                                      converted, &converted_len);
+#  endif
+                       if (converted == NULL)
+                         {
+                           int saved_errno = errno;
+                           if (!(result == resultbuf || result == NULL))
+                             free (result);
+                           if (buf_malloced != NULL)
+                             free (buf_malloced);
+                           CLEANUP ();
+                           errno = saved_errno;
+                           return NULL;
+                         }
+                       if (converted != result + length)
+                         {
+                           ENSURE_ALLOCATION (xsum (length, converted_len));
+                           DCHAR_CPY (result + length, converted, 
converted_len);
+                           free (converted);
+                         }
+                       length += converted_len;
+                     }
+# endif
+
+                     if (has_width && width > characters
+                         && (dp->flags & FLAG_LEFT))
+                       {
+                         size_t n = width - characters;
+                         ENSURE_ALLOCATION (xsum (length, n));
+                         DCHAR_SET (result + length, ' ', n);
+                         length += n;
+                       }
+                   }
+                   break;
+
+                 case TYPE_U16_STRING:
+                   {
+                     const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
+                     const uint16_t *arg_end;
+                     size_t characters;
+
+                     if (has_precision)
+                       {
+                         /* Use only PRECISION characters, from the left.  */
+                         arg_end = arg;
+                         characters = 0;
+                         for (; precision > 0; precision--)
+                           {
+                             int count = u16_strmblen (arg_end);
+                             if (count == 0)
+                               break;
+                             if (count < 0)
+                               {
+                                 if (!(result == resultbuf || result == NULL))
+                                   free (result);
+                                 if (buf_malloced != NULL)
+                                   free (buf_malloced);
+                                 CLEANUP ();
+                                 errno = EILSEQ;
+                                 return NULL;
+                               }
+                             arg_end += count;
+                             characters++;
+                           }
+                       }
+                     else if (has_width)
+                       {
+                         /* Use the entire string, and count the number of
+                            characters.  */
+                         arg_end = arg;
+                         characters = 0;
+                         for (;;)
+                           {
+                             int count = u16_strmblen (arg_end);
+                             if (count == 0)
+                               break;
+                             if (count < 0)
+                               {
+                                 if (!(result == resultbuf || result == NULL))
+                                   free (result);
+                                 if (buf_malloced != NULL)
+                                   free (buf_malloced);
+                                 CLEANUP ();
+                                 errno = EILSEQ;
+                                 return NULL;
+                               }
+                             arg_end += count;
+                             characters++;
+                           }
+                       }
+                     else
+                       {
+                         /* Use the entire string.  */
+                         arg_end = arg + u16_strlen (arg);
+                         /* The number of characters doesn't matter.  */
+                         characters = 0;
+                       }
+
+                     if (has_width && width > characters
+                         && !(dp->flags & FLAG_LEFT))
+                       {
+                         size_t n = width - characters;
+                         ENSURE_ALLOCATION (xsum (length, n));
+                         DCHAR_SET (result + length, ' ', n);
+                         length += n;
+                       }
+
+# if DCHAR_IS_UINT16_T
+                     {
+                       size_t n = arg_end - arg;
+                       ENSURE_ALLOCATION (xsum (length, n));
+                       DCHAR_CPY (result + length, arg, n);
+                       length += n;
+                     }
+# else
+                     { /* Convert.  */
+                       DCHAR_T *converted = result + length;
+                       size_t converted_len = allocated - length;
+#  if DCHAR_IS_TCHAR
+                       /* Convert from UTF-16 to locale encoding.  */
+                       converted =
+                         u16_conv_to_encoding (locale_charset (),
+                                               iconveh_question_mark,
+                                               arg, arg_end - arg, NULL,
+                                               converted, &converted_len);
+#  else
+                       /* Convert from UTF-16 to UTF-8/UTF-32.  */
+                       converted =
+                         U16_TO_DCHAR (arg, arg_end - arg,
+                                       converted, &converted_len);
+#  endif
+                       if (converted == NULL)
+                         {
+                           int saved_errno = errno;
+                           if (!(result == resultbuf || result == NULL))
+                             free (result);
+                           if (buf_malloced != NULL)
+                             free (buf_malloced);
+                           CLEANUP ();
+                           errno = saved_errno;
+                           return NULL;
+                         }
+                       if (converted != result + length)
+                         {
+                           ENSURE_ALLOCATION (xsum (length, converted_len));
+                           DCHAR_CPY (result + length, converted, 
converted_len);
+                           free (converted);
+                         }
+                       length += converted_len;
+                     }
+# endif
+
+                     if (has_width && width > characters
+                         && (dp->flags & FLAG_LEFT))
+                       {
+                         size_t n = width - characters;
+                         ENSURE_ALLOCATION (xsum (length, n));
+                         DCHAR_SET (result + length, ' ', n);
+                         length += n;
+                       }
+                   }
+                   break;
+
+                 case TYPE_U32_STRING:
+                   {
+                     const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
+                     const uint32_t *arg_end;
+                     size_t characters;
+
+                     if (has_precision)
+                       {
+                         /* Use only PRECISION characters, from the left.  */
+                         arg_end = arg;
+                         characters = 0;
+                         for (; precision > 0; precision--)
+                           {
+                             int count = u32_strmblen (arg_end);
+                             if (count == 0)
+                               break;
+                             if (count < 0)
+                               {
+                                 if (!(result == resultbuf || result == NULL))
+                                   free (result);
+                                 if (buf_malloced != NULL)
+                                   free (buf_malloced);
+                                 CLEANUP ();
+                                 errno = EILSEQ;
+                                 return NULL;
+                               }
+                             arg_end += count;
+                             characters++;
+                           }
+                       }
+                     else if (has_width)
+                       {
+                         /* Use the entire string, and count the number of
+                            characters.  */
+                         arg_end = arg;
+                         characters = 0;
+                         for (;;)
+                           {
+                             int count = u32_strmblen (arg_end);
+                             if (count == 0)
+                               break;
+                             if (count < 0)
+                               {
+                                 if (!(result == resultbuf || result == NULL))
+                                   free (result);
+                                 if (buf_malloced != NULL)
+                                   free (buf_malloced);
+                                 CLEANUP ();
+                                 errno = EILSEQ;
+                                 return NULL;
+                               }
+                             arg_end += count;
+                             characters++;
+                           }
+                       }
+                     else
+                       {
+                         /* Use the entire string.  */
+                         arg_end = arg + u32_strlen (arg);
+                         /* The number of characters doesn't matter.  */
+                         characters = 0;
+                       }
+
+                     if (has_width && width > characters
+                         && !(dp->flags & FLAG_LEFT))
+                       {
+                         size_t n = width - characters;
+                         ENSURE_ALLOCATION (xsum (length, n));
+                         DCHAR_SET (result + length, ' ', n);
+                         length += n;
+                       }
+
+# if DCHAR_IS_UINT32_T
+                     {
+                       size_t n = arg_end - arg;
+                       ENSURE_ALLOCATION (xsum (length, n));
+                       DCHAR_CPY (result + length, arg, n);
+                       length += n;
+                     }
+# else
+                     { /* Convert.  */
+                       DCHAR_T *converted = result + length;
+                       size_t converted_len = allocated - length;
+#  if DCHAR_IS_TCHAR
+                       /* Convert from UTF-32 to locale encoding.  */
+                       converted =
+                         u32_conv_to_encoding (locale_charset (),
+                                               iconveh_question_mark,
+                                               arg, arg_end - arg, NULL,
+                                               converted, &converted_len);
+#  else
+                       /* Convert from UTF-32 to UTF-8/UTF-16.  */
+                       converted =
+                         U32_TO_DCHAR (arg, arg_end - arg,
+                                       converted, &converted_len);
+#  endif
+                       if (converted == NULL)
+                         {
+                           int saved_errno = errno;
+                           if (!(result == resultbuf || result == NULL))
+                             free (result);
+                           if (buf_malloced != NULL)
+                             free (buf_malloced);
+                           CLEANUP ();
+                           errno = saved_errno;
+                           return NULL;
+                         }
+                       if (converted != result + length)
+                         {
+                           ENSURE_ALLOCATION (xsum (length, converted_len));
+                           DCHAR_CPY (result + length, converted, 
converted_len);
+                           free (converted);
+                         }
+                       length += converted_len;
+                     }
+# endif
+
+                     if (has_width && width > characters
+                         && (dp->flags & FLAG_LEFT))
+                       {
+                         size_t n = width - characters;
+                         ENSURE_ALLOCATION (xsum (length, n));
+                         DCHAR_SET (result + length, ' ', n);
+                         length += n;
+                       }
+                   }
+                   break;
+
+                 default:
+                   abort ();
+                 }
+             }
+#endif
+#if (!USE_SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && 
HAVE_WCHAR_T
+           else if (dp->conversion == 's'
+# if WIDE_CHAR_VERSION
+                    && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
+# else
+                    && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
+# endif
+                   )
+             {
+               /* The normal handling of the 's' directive below requires
+                  allocating a temporary buffer.  The determination of its
+                  length (tmp_length), in the case when a precision is
+                  specified, below requires a conversion between a char[]
+                  string and a wchar_t[] wide string.  It could be done, but
+                  we have no guarantee that the implementation of sprintf will
+                  use the exactly same algorithm.  Without this guarantee, it
+                  is possible to have buffer overrun bugs.  In order to avoid
+                  such bugs, we implement the entire processing of the 's'
+                  directive ourselves.  */
+               int flags = dp->flags;
+               int has_width;
+               size_t width;
+               int has_precision;
+               size_t precision;
+
+               has_width = 0;
+               width = 0;
+               if (dp->width_start != dp->width_end)
+                 {
+                   if (dp->width_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->width_arg_index].a.a_int;
+                       if (arg < 0)
+                         {
+                           /* "A negative field width is taken as a '-' flag
+                               followed by a positive field width."  */
+                           flags |= FLAG_LEFT;
+                           width = (unsigned int) (-arg);
+                         }
+                       else
+                         width = arg;
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->width_start;
+
+                       do
+                         width = xsum (xtimes (width, 10), *digitp++ - '0');
+                       while (digitp != dp->width_end);
+                     }
+                   has_width = 1;
+                 }
+
+               has_precision = 0;
+               precision = 6;
+               if (dp->precision_start != dp->precision_end)
+                 {
+                   if (dp->precision_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->precision_arg_index].a.a_int;
+                       /* "A negative precision is taken as if the precision
+                           were omitted."  */
+                       if (arg >= 0)
+                         {
+                           precision = arg;
+                           has_precision = 1;
+                         }
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->precision_start + 1;
+
+                       precision = 0;
+                       while (digitp != dp->precision_end)
+                         precision = xsum (xtimes (precision, 10), *digitp++ - 
'0');
+                       has_precision = 1;
+                     }
+                 }
+
+# if WIDE_CHAR_VERSION
+               /* %s in vasnwprintf.  See the specification of fwprintf.  */
+               {
+                 const char *arg = a.arg[dp->arg_index].a.a_string;
+                 const char *arg_end;
+                 size_t characters;
+
+                 if (has_precision)
+                   {
+                     /* Use only as many bytes as needed to produce PRECISION
+                        wide characters, from the left.  */
+#  if HAVE_MBRTOWC
+                     mbstate_t state;
+                     memset (&state, '\0', sizeof (mbstate_t));
+#  endif
+                     arg_end = arg;
+                     characters = 0;
+                     for (; precision > 0; precision--)
+                       {
+                         int count;
+#  if HAVE_MBRTOWC
+                         count = mbrlen (arg_end, MB_CUR_MAX, &state);
+#  else
+                         count = mblen (arg_end, MB_CUR_MAX);
+#  endif
+                         if (count == 0)
+                           /* Found the terminating NUL.  */
+                           break;
+                         if (count < 0)
+                           {
+                             /* Invalid or incomplete multibyte character.  */
+                             if (!(result == resultbuf || result == NULL))
+                               free (result);
+                             if (buf_malloced != NULL)
+                               free (buf_malloced);
+                             CLEANUP ();
+                             errno = EILSEQ;
+                             return NULL;
+                           }
+                         arg_end += count;
+                         characters++;
+                       }
+                   }
+                 else if (has_width)
+                   {
+                     /* Use the entire string, and count the number of wide
+                        characters.  */
+#  if HAVE_MBRTOWC
+                     mbstate_t state;
+                     memset (&state, '\0', sizeof (mbstate_t));
+#  endif
+                     arg_end = arg;
+                     characters = 0;
+                     for (;;)
+                       {
+                         int count;
+#  if HAVE_MBRTOWC
+                         count = mbrlen (arg_end, MB_CUR_MAX, &state);
+#  else
+                         count = mblen (arg_end, MB_CUR_MAX);
+#  endif
+                         if (count == 0)
+                           /* Found the terminating NUL.  */
+                           break;
+                         if (count < 0)
+                           {
+                             /* Invalid or incomplete multibyte character.  */
+                             if (!(result == resultbuf || result == NULL))
+                               free (result);
+                             if (buf_malloced != NULL)
+                               free (buf_malloced);
+                             CLEANUP ();
+                             errno = EILSEQ;
+                             return NULL;
+                           }
+                         arg_end += count;
+                         characters++;
+                       }
+                   }
+                 else
+                   {
+                     /* Use the entire string.  */
+                     arg_end = arg + strlen (arg);
+                     /* The number of characters doesn't matter.  */
+                     characters = 0;
+                   }
+
+                 if (has_width && width > characters
+                     && !(dp->flags & FLAG_LEFT))
+                   {
+                     size_t n = width - characters;
+                     ENSURE_ALLOCATION (xsum (length, n));
+                     DCHAR_SET (result + length, ' ', n);
+                     length += n;
+                   }
+
+                 if (has_precision || has_width)
+                   {
+                     /* We know the number of wide characters in advance.  */
+                     size_t remaining;
+#  if HAVE_MBRTOWC
+                     mbstate_t state;
+                     memset (&state, '\0', sizeof (mbstate_t));
+#  endif
+                     ENSURE_ALLOCATION (xsum (length, characters));
+                     for (remaining = characters; remaining > 0; remaining--)
+                       {
+                         wchar_t wc;
+                         int count;
+#  if HAVE_MBRTOWC
+                         count = mbrtowc (&wc, arg, arg_end - arg, &state);
+#  else
+                         count = mbtowc (&wc, arg, arg_end - arg);
+#  endif
+                         if (count <= 0)
+                           /* mbrtowc not consistent with mbrlen, or mbtowc
+                              not consistent with mblen.  */
+                           abort ();
+                         result[length++] = wc;
+                         arg += count;
+                       }
+                     if (!(arg == arg_end))
+                       abort ();
+                   }
+                 else
+                   {
+#  if HAVE_MBRTOWC
+                     mbstate_t state;
+                     memset (&state, '\0', sizeof (mbstate_t));
+#  endif
+                     while (arg < arg_end)
+                       {
+                         wchar_t wc;
+                         int count;
+#  if HAVE_MBRTOWC
+                         count = mbrtowc (&wc, arg, arg_end - arg, &state);
+#  else
+                         count = mbtowc (&wc, arg, arg_end - arg);
+#  endif
+                         if (count <= 0)
+                           /* mbrtowc not consistent with mbrlen, or mbtowc
+                              not consistent with mblen.  */
+                           abort ();
+                         ENSURE_ALLOCATION (xsum (length, 1));
+                         result[length++] = wc;
+                         arg += count;
+                       }
+                   }
+
+                 if (has_width && width > characters
+                     && (dp->flags & FLAG_LEFT))
+                   {
+                     size_t n = width - characters;
+                     ENSURE_ALLOCATION (xsum (length, n));
+                     DCHAR_SET (result + length, ' ', n);
+                     length += n;
+                   }
+               }
+# else
+               /* %ls in vasnprintf.  See the specification of fprintf.  */
+               {
+                 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
+                 const wchar_t *arg_end;
+                 size_t characters;
+#  if !DCHAR_IS_TCHAR
+                 /* This code assumes that TCHAR_T is 'char'.  */
+                 typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 1];
+                 TCHAR_T *tmpsrc;
+                 DCHAR_T *tmpdst;
+                 size_t tmpdst_len;
+#  endif
+                 size_t w;
+
+                 if (has_precision)
+                   {
+                     /* Use only as many wide characters as needed to produce
+                        at most PRECISION bytes, from the left.  */
+#  if HAVE_WCRTOMB
+                     mbstate_t state;
+                     memset (&state, '\0', sizeof (mbstate_t));
+#  endif
+                     arg_end = arg;
+                     characters = 0;
+                     while (precision > 0)
+                       {
+                         char buf[64]; /* Assume MB_CUR_MAX <= 64.  */
+                         int count;
+
+                         if (*arg_end == 0)
+                           /* Found the terminating null wide character.  */
+                           break;
+#  if HAVE_WCRTOMB
+                         count = wcrtomb (buf, *arg_end, &state);
+#  else
+                         count = wctomb (buf, *arg_end);
+#  endif
+                         if (count < 0)
+                           {
+                             /* Cannot convert.  */
+                             if (!(result == resultbuf || result == NULL))
+                               free (result);
+                             if (buf_malloced != NULL)
+                               free (buf_malloced);
+                             CLEANUP ();
+                             errno = EILSEQ;
+                             return NULL;
+                           }
+                         if (precision < count)
+                           break;
+                         arg_end++;
+                         characters += count;
+                         precision -= count;
+                       }
+                   }
+#  if DCHAR_IS_TCHAR
+                 else if (has_width)
+#  else
+                 else
+#  endif
+                   {
+                     /* Use the entire string, and count the number of
+                        bytes.  */
+#  if HAVE_WCRTOMB
+                     mbstate_t state;
+                     memset (&state, '\0', sizeof (mbstate_t));
+#  endif
+                     arg_end = arg;
+                     characters = 0;
+                     for (;;)
+                       {
+                         char buf[64]; /* Assume MB_CUR_MAX <= 64.  */
+                         int count;
+
+                         if (*arg_end == 0)
+                           /* Found the terminating null wide character.  */
+                           break;
+#  if HAVE_WCRTOMB
+                         count = wcrtomb (buf, *arg_end, &state);
+#  else
+                         count = wctomb (buf, *arg_end);
+#  endif
+                         if (count < 0)
+                           {
+                             /* Cannot convert.  */
+                             if (!(result == resultbuf || result == NULL))
+                               free (result);
+                             if (buf_malloced != NULL)
+                               free (buf_malloced);
+                             CLEANUP ();
+                             errno = EILSEQ;
+                             return NULL;
+                           }
+                         arg_end++;
+                         characters += count;
+                       }
+                   }
+#  if DCHAR_IS_TCHAR
+                 else
+                   {
+                     /* Use the entire string.  */
+                     arg_end = arg + local_wcslen (arg);
+                     /* The number of bytes doesn't matter.  */
+                     characters = 0;
+                   }
+#  endif
+
+#  if !DCHAR_IS_TCHAR
+                 /* Convert the string into a piece of temporary memory.  */
+                 tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
+                 if (tmpsrc == NULL)
+                   goto out_of_memory;
+                 {
+                   TCHAR_T *tmpptr = tmpsrc;
+                   size_t remaining;
+#   if HAVE_WCRTOMB
+                   mbstate_t state;
+                   memset (&state, '\0', sizeof (mbstate_t));
+#   endif
+                   for (remaining = characters; remaining > 0; )
+                     {
+                       char buf[64]; /* Assume MB_CUR_MAX <= 64.  */
+                       int count;
+
+                       if (*arg == 0)
+                         abort ();
+#   if HAVE_WCRTOMB
+                       count = wcrtomb (buf, *arg, &state);
+#   else
+                       count = wctomb (buf, *arg);
+#   endif
+                       if (count <= 0)
+                         /* Inconsistency.  */
+                         abort ();
+                       memcpy (tmpptr, buf, count);
+                       tmpptr += count;
+                       arg++;
+                       remaining -= count;
+                     }
+                   if (!(arg == arg_end))
+                     abort ();
+                 }
+
+                 /* Convert from TCHAR_T[] to DCHAR_T[].  */
+                 tmpdst =
+                   DCHAR_CONV_FROM_ENCODING (locale_charset (),
+                                             iconveh_question_mark,
+                                             tmpsrc, characters,
+                                             NULL,
+                                             NULL, &tmpdst_len);
+                 if (tmpdst == NULL)
+                   {
+                     int saved_errno = errno;
+                     free (tmpsrc);
+                     if (!(result == resultbuf || result == NULL))
+                       free (result);
+                     if (buf_malloced != NULL)
+                       free (buf_malloced);
+                     CLEANUP ();
+                     errno = saved_errno;
+                     return NULL;
+                   }
+                 free (tmpsrc);
+#  endif
+
+                 if (has_width)
+                   {
+#  if ENABLE_UNISTDIO
+                     /* Outside POSIX, it's preferrable to compare the width
+                        against the number of _characters_ of the converted
+                        value.  */
+                     w = DCHAR_MBSNLEN (result + length, characters);
+#  else
+                     /* The width is compared against the number of _bytes_
+                        of the converted value, says POSIX.  */
+                     w = characters;
+#  endif
+                   }
+                 else
+                   /* w doesn't matter.  */
+                   w = 0;
+
+                 if (has_width && width > w
+                     && !(dp->flags & FLAG_LEFT))
+                   {
+                     size_t n = width - w;
+                     ENSURE_ALLOCATION (xsum (length, n));
+                     DCHAR_SET (result + length, ' ', n);
+                     length += n;
+                   }
+
+#  if DCHAR_IS_TCHAR
+                 if (has_precision || has_width)
+                   {
+                     /* We know the number of bytes in advance.  */
+                     size_t remaining;
+#   if HAVE_WCRTOMB
+                     mbstate_t state;
+                     memset (&state, '\0', sizeof (mbstate_t));
+#   endif
+                     ENSURE_ALLOCATION (xsum (length, characters));
+                     for (remaining = characters; remaining > 0; )
+                       {
+                         char buf[64]; /* Assume MB_CUR_MAX <= 64.  */
+                         int count;
+
+                         if (*arg == 0)
+                           abort ();
+#   if HAVE_WCRTOMB
+                         count = wcrtomb (buf, *arg, &state);
+#   else
+                         count = wctomb (buf, *arg);
+#   endif
+                         if (count <= 0)
+                           /* Inconsistency.  */
+                           abort ();
+                         memcpy (result + length, buf, count);
+                         length += count;
+                         arg++;
+                         remaining -= count;
+                       }
+                     if (!(arg == arg_end))
+                       abort ();
+                   }
+                 else
+                   {
+#   if HAVE_WCRTOMB
+                     mbstate_t state;
+                     memset (&state, '\0', sizeof (mbstate_t));
+#   endif
+                     while (arg < arg_end)
+                       {
+                         char buf[64]; /* Assume MB_CUR_MAX <= 64.  */
+                         int count;
+
+                         if (*arg == 0)
+                           abort ();
+#   if HAVE_WCRTOMB
+                         count = wcrtomb (buf, *arg, &state);
+#   else
+                         count = wctomb (buf, *arg);
+#   endif
+                         if (count <= 0)
+                           /* Inconsistency.  */
+                           abort ();
+                         ENSURE_ALLOCATION (xsum (length, count));
+                         memcpy (result + length, buf, count);
+                         length += count;
+                         arg++;
+                       }
+                   }
+#  else
+                 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
+                 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
+                 free (tmpdst);
+                 length += tmpdst_len;
+#  endif
+
+                 if (has_width && width > w
+                     && (dp->flags & FLAG_LEFT))
+                   {
+                     size_t n = width - w;
+                     ENSURE_ALLOCATION (xsum (length, n));
+                     DCHAR_SET (result + length, ' ', n);
+                     length += n;
+                   }
+               }
+             }
+# endif
+#endif
+#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) 
&& !defined IN_LIBINTL
+           else if ((dp->conversion == 'a' || dp->conversion == 'A')
+# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && 
NEED_PRINTF_DOUBLE))
+                    && (0
+#  if NEED_PRINTF_DOUBLE
+                        || a.arg[dp->arg_index].type == TYPE_DOUBLE
+#  endif
+#  if NEED_PRINTF_LONG_DOUBLE
+                        || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
+#  endif
+                       )
+# endif
+                   )
+             {
+               arg_type type = a.arg[dp->arg_index].type;
+               int flags = dp->flags;
+               int has_width;
+               size_t width;
+               int has_precision;
+               size_t precision;
+               size_t tmp_length;
+               DCHAR_T tmpbuf[700];
+               DCHAR_T *tmp;
+               DCHAR_T *pad_ptr;
+               DCHAR_T *p;
+
+               has_width = 0;
+               width = 0;
+               if (dp->width_start != dp->width_end)
+                 {
+                   if (dp->width_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->width_arg_index].a.a_int;
+                       if (arg < 0)
+                         {
+                           /* "A negative field width is taken as a '-' flag
+                               followed by a positive field width."  */
+                           flags |= FLAG_LEFT;
+                           width = (unsigned int) (-arg);
+                         }
+                       else
+                         width = arg;
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->width_start;
+
+                       do
+                         width = xsum (xtimes (width, 10), *digitp++ - '0');
+                       while (digitp != dp->width_end);
+                     }
+                   has_width = 1;
+                 }
+
+               has_precision = 0;
+               precision = 0;
+               if (dp->precision_start != dp->precision_end)
+                 {
+                   if (dp->precision_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->precision_arg_index].a.a_int;
+                       /* "A negative precision is taken as if the precision
+                           were omitted."  */
+                       if (arg >= 0)
+                         {
+                           precision = arg;
+                           has_precision = 1;
+                         }
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->precision_start + 1;
+
+                       precision = 0;
+                       while (digitp != dp->precision_end)
+                         precision = xsum (xtimes (precision, 10), *digitp++ - 
'0');
+                       has_precision = 1;
+                     }
+                 }
+
+               /* Allocate a temporary buffer of sufficient size.  */
+               if (type == TYPE_LONGDOUBLE)
+                 tmp_length =
+                   (unsigned int) ((LDBL_DIG + 1)
+                                   * 0.831 /* decimal -> hexadecimal */
+                                  )
+                   + 1; /* turn floor into ceil */
+               else
+                 tmp_length =
+                   (unsigned int) ((DBL_DIG + 1)
+                                   * 0.831 /* decimal -> hexadecimal */
+                                  )
+                   + 1; /* turn floor into ceil */
+               if (tmp_length < precision)
+                 tmp_length = precision;
+               /* Account for sign, decimal point etc. */
+               tmp_length = xsum (tmp_length, 12);
+
+               if (tmp_length < width)
+                 tmp_length = width;
+
+               tmp_length = xsum (tmp_length, 1); /* account for trailing NUL 
*/
+
+               if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
+                 tmp = tmpbuf;
+               else
+                 {
+                   size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
+
+                   if (size_overflow_p (tmp_memsize))
+                     /* Overflow, would lead to out of memory.  */
+                     goto out_of_memory;
+                   tmp = (DCHAR_T *) malloc (tmp_memsize);
+                   if (tmp == NULL)
+                     /* Out of memory.  */
+                     goto out_of_memory;
+                 }
+
+               pad_ptr = NULL;
+               p = tmp;
+               if (type == TYPE_LONGDOUBLE)
+                 {
+# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
+                   long double arg = a.arg[dp->arg_index].a.a_longdouble;
+
+                   if (isnanl (arg))
+                     {
+                       if (dp->conversion == 'A')
+                         {
+                           *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
+                         }
+                       else
+                         {
+                           *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
+                         }
+                     }
+                   else
+                     {
+                       int sign = 0;
+                       DECL_LONG_DOUBLE_ROUNDING
+
+                       BEGIN_LONG_DOUBLE_ROUNDING ();
+
+                       if (signbit (arg)) /* arg < 0.0L or negative zero */
+                         {
+                           sign = -1;
+                           arg = -arg;
+                         }
+
+                       if (sign < 0)
+                         *p++ = '-';
+                       else if (flags & FLAG_SHOWSIGN)
+                         *p++ = '+';
+                       else if (flags & FLAG_SPACE)
+                         *p++ = ' ';
+
+                       if (arg > 0.0L && arg + arg == arg)
+                         {
+                           if (dp->conversion == 'A')
+                             {
+                               *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
+                             }
+                           else
+                             {
+                               *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+                             }
+                         }
+                       else
+                         {
+                           int exponent;
+                           long double mantissa;
+
+                           if (arg > 0.0L)
+                             mantissa = printf_frexpl (arg, &exponent);
+                           else
+                             {
+                               exponent = 0;
+                               mantissa = 0.0L;
+                             }
+
+                           if (has_precision
+                               && precision < (unsigned int) ((LDBL_DIG + 1) * 
0.831) + 1)
+                             {
+                               /* Round the mantissa.  */
+                               long double tail = mantissa;
+                               size_t q;
+
+                               for (q = precision; ; q--)
+                                 {
+                                   int digit = (int) tail;
+                                   tail -= digit;
+                                   if (q == 0)
+                                     {
+                                       if (digit & 1 ? tail >= 0.5L : tail > 
0.5L)
+                                         tail = 1 - tail;
+                                       else
+                                         tail = - tail;
+                                       break;
+                                     }
+                                   tail *= 16.0L;
+                                 }
+                               if (tail != 0.0L)
+                                 for (q = precision; q > 0; q--)
+                                   tail *= 0.0625L;
+                               mantissa += tail;
+                             }
+
+                           *p++ = '0';
+                           *p++ = dp->conversion - 'A' + 'X';
+                           pad_ptr = p;
+                           {
+                             int digit;
+
+                             digit = (int) mantissa;
+                             mantissa -= digit;
+                             *p++ = '0' + digit;
+                             if ((flags & FLAG_ALT)
+                                 || mantissa > 0.0L || precision > 0)
+                               {
+                                 *p++ = decimal_point_char ();
+                                 /* This loop terminates because we assume
+                                    that FLT_RADIX is a power of 2.  */
+                                 while (mantissa > 0.0L)
+                                   {
+                                     mantissa *= 16.0L;
+                                     digit = (int) mantissa;
+                                     mantissa -= digit;
+                                     *p++ = digit
+                                            + (digit < 10
+                                               ? '0'
+                                               : dp->conversion - 10);
+                                     if (precision > 0)
+                                       precision--;
+                                   }
+                                 while (precision > 0)
+                                   {
+                                     *p++ = '0';
+                                     precision--;
+                                   }
+                               }
+                             }
+                             *p++ = dp->conversion - 'A' + 'P';
+#  if WIDE_CHAR_VERSION
+                             {
+                               static const wchar_t decimal_format[] =
+                                 { '%', '+', 'd', '\0' };
+                               SNPRINTF (p, 6 + 1, decimal_format, exponent);
+                             }
+                             while (*p != '\0')
+                               p++;
+#  else
+                             if (sizeof (DCHAR_T) == 1)
+                               {
+                                 sprintf ((char *) p, "%+d", exponent);
+                                 while (*p != '\0')
+                                   p++;
+                               }
+                             else
+                               {
+                                 char expbuf[6 + 1];
+                                 const char *ep;
+                                 sprintf (expbuf, "%+d", exponent);
+                                 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
+                                   p++;
+                               }
+#  endif
+                         }
+
+                       END_LONG_DOUBLE_ROUNDING ();
+                     }
+# else
+                   abort ();
+# endif
+                 }
+               else
+                 {
+# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
+                   double arg = a.arg[dp->arg_index].a.a_double;
+
+                   if (isnand (arg))
+                     {
+                       if (dp->conversion == 'A')
+                         {
+                           *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
+                         }
+                       else
+                         {
+                           *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
+                         }
+                     }
+                   else
+                     {
+                       int sign = 0;
+
+                       if (signbit (arg)) /* arg < 0.0 or negative zero */
+                         {
+                           sign = -1;
+                           arg = -arg;
+                         }
+
+                       if (sign < 0)
+                         *p++ = '-';
+                       else if (flags & FLAG_SHOWSIGN)
+                         *p++ = '+';
+                       else if (flags & FLAG_SPACE)
+                         *p++ = ' ';
+
+                       if (arg > 0.0 && arg + arg == arg)
+                         {
+                           if (dp->conversion == 'A')
+                             {
+                               *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
+                             }
+                           else
+                             {
+                               *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+                             }
+                         }
+                       else
+                         {
+                           int exponent;
+                           double mantissa;
+
+                           if (arg > 0.0)
+                             mantissa = printf_frexp (arg, &exponent);
+                           else
+                             {
+                               exponent = 0;
+                               mantissa = 0.0;
+                             }
+
+                           if (has_precision
+                               && precision < (unsigned int) ((DBL_DIG + 1) * 
0.831) + 1)
+                             {
+                               /* Round the mantissa.  */
+                               double tail = mantissa;
+                               size_t q;
+
+                               for (q = precision; ; q--)
+                                 {
+                                   int digit = (int) tail;
+                                   tail -= digit;
+                                   if (q == 0)
+                                     {
+                                       if (digit & 1 ? tail >= 0.5 : tail > 
0.5)
+                                         tail = 1 - tail;
+                                       else
+                                         tail = - tail;
+                                       break;
+                                     }
+                                   tail *= 16.0;
+                                 }
+                               if (tail != 0.0)
+                                 for (q = precision; q > 0; q--)
+                                   tail *= 0.0625;
+                               mantissa += tail;
+                             }
+
+                           *p++ = '0';
+                           *p++ = dp->conversion - 'A' + 'X';
+                           pad_ptr = p;
+                           {
+                             int digit;
+
+                             digit = (int) mantissa;
+                             mantissa -= digit;
+                             *p++ = '0' + digit;
+                             if ((flags & FLAG_ALT)
+                                 || mantissa > 0.0 || precision > 0)
+                               {
+                                 *p++ = decimal_point_char ();
+                                 /* This loop terminates because we assume
+                                    that FLT_RADIX is a power of 2.  */
+                                 while (mantissa > 0.0)
+                                   {
+                                     mantissa *= 16.0;
+                                     digit = (int) mantissa;
+                                     mantissa -= digit;
+                                     *p++ = digit
+                                            + (digit < 10
+                                               ? '0'
+                                               : dp->conversion - 10);
+                                     if (precision > 0)
+                                       precision--;
+                                   }
+                                 while (precision > 0)
+                                   {
+                                     *p++ = '0';
+                                     precision--;
+                                   }
+                               }
+                             }
+                             *p++ = dp->conversion - 'A' + 'P';
+#  if WIDE_CHAR_VERSION
+                             {
+                               static const wchar_t decimal_format[] =
+                                 { '%', '+', 'd', '\0' };
+                               SNPRINTF (p, 6 + 1, decimal_format, exponent);
+                             }
+                             while (*p != '\0')
+                               p++;
+#  else
+                             if (sizeof (DCHAR_T) == 1)
+                               {
+                                 sprintf ((char *) p, "%+d", exponent);
+                                 while (*p != '\0')
+                                   p++;
+                               }
+                             else
+                               {
+                                 char expbuf[6 + 1];
+                                 const char *ep;
+                                 sprintf (expbuf, "%+d", exponent);
+                                 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
+                                   p++;
+                               }
+#  endif
+                         }
+                     }
+# else
+                   abort ();
+# endif
+                 }
+               /* The generated string now extends from tmp to p, with the
+                  zero padding insertion point being at pad_ptr.  */
+               if (has_width && p - tmp < width)
+                 {
+                   size_t pad = width - (p - tmp);
+                   DCHAR_T *end = p + pad;
+
+                   if (flags & FLAG_LEFT)
+                     {
+                       /* Pad with spaces on the right.  */
+                       for (; pad > 0; pad--)
+                         *p++ = ' ';
+                     }
+                   else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
+                     {
+                       /* Pad with zeroes.  */
+                       DCHAR_T *q = end;
+
+                       while (p > pad_ptr)
+                         *--q = *--p;
+                       for (; pad > 0; pad--)
+                         *p++ = '0';
+                     }
+                   else
+                     {
+                       /* Pad with spaces on the left.  */
+                       DCHAR_T *q = end;
+
+                       while (p > tmp)
+                         *--q = *--p;
+                       for (; pad > 0; pad--)
+                         *p++ = ' ';
+                     }
+
+                   p = end;
+                 }
+
+               {
+                 size_t count = p - tmp;
+
+                 if (count >= tmp_length)
+                   /* tmp_length was incorrectly calculated - fix the
+                      code above!  */
+                   abort ();
+
+                 /* Make room for the result.  */
+                 if (count >= allocated - length)
+                   {
+                     size_t n = xsum (length, count);
+
+                     ENSURE_ALLOCATION (n);
+                   }
+
+                 /* Append the result.  */
+                 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
+                 if (tmp != tmpbuf)
+                   free (tmp);
+                 length += count;
+               }
+             }
+#endif
+#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || 
NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined 
IN_LIBINTL
+           else if ((dp->conversion == 'f' || dp->conversion == 'F'
+                     || dp->conversion == 'e' || dp->conversion == 'E'
+                     || dp->conversion == 'g' || dp->conversion == 'G'
+                     || dp->conversion == 'a' || dp->conversion == 'A')
+                    && (0
+# if NEED_PRINTF_DOUBLE
+                        || a.arg[dp->arg_index].type == TYPE_DOUBLE
+# elif NEED_PRINTF_INFINITE_DOUBLE
+                        || (a.arg[dp->arg_index].type == TYPE_DOUBLE
+                            /* The systems (mingw) which produce wrong output
+                               for Inf, -Inf, and NaN also do so for -0.0.
+                               Therefore we treat this case here as well.  */
+                            && is_infinite_or_zero 
(a.arg[dp->arg_index].a.a_double))
+# endif
+# if NEED_PRINTF_LONG_DOUBLE
+                        || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
+# elif NEED_PRINTF_INFINITE_LONG_DOUBLE
+                        || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
+                            /* Some systems produce wrong output for Inf,
+                               -Inf, and NaN.  Some systems in this category
+                               (IRIX 5.3) also do so for -0.0.  Therefore we
+                               treat this case here as well.  */
+                            && is_infinite_or_zerol 
(a.arg[dp->arg_index].a.a_longdouble))
+# endif
+                       ))
+             {
+# if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && 
(NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
+               arg_type type = a.arg[dp->arg_index].type;
+# endif
+               int flags = dp->flags;
+               int has_width;
+               size_t width;
+               int has_precision;
+               size_t precision;
+               size_t tmp_length;
+               DCHAR_T tmpbuf[700];
+               DCHAR_T *tmp;
+               DCHAR_T *pad_ptr;
+               DCHAR_T *p;
+
+               has_width = 0;
+               width = 0;
+               if (dp->width_start != dp->width_end)
+                 {
+                   if (dp->width_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->width_arg_index].a.a_int;
+                       if (arg < 0)
+                         {
+                           /* "A negative field width is taken as a '-' flag
+                               followed by a positive field width."  */
+                           flags |= FLAG_LEFT;
+                           width = (unsigned int) (-arg);
+                         }
+                       else
+                         width = arg;
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->width_start;
+
+                       do
+                         width = xsum (xtimes (width, 10), *digitp++ - '0');
+                       while (digitp != dp->width_end);
+                     }
+                   has_width = 1;
+                 }
+
+               has_precision = 0;
+               precision = 0;
+               if (dp->precision_start != dp->precision_end)
+                 {
+                   if (dp->precision_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->precision_arg_index].a.a_int;
+                       /* "A negative precision is taken as if the precision
+                           were omitted."  */
+                       if (arg >= 0)
+                         {
+                           precision = arg;
+                           has_precision = 1;
+                         }
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->precision_start + 1;
+
+                       precision = 0;
+                       while (digitp != dp->precision_end)
+                         precision = xsum (xtimes (precision, 10), *digitp++ - 
'0');
+                       has_precision = 1;
+                     }
+                 }
+
+               /* POSIX specifies the default precision to be 6 for %f, %F,
+                  %e, %E, but not for %g, %G.  Implementations appear to use
+                  the same default precision also for %g, %G.  But for %a, %A,
+                  the default precision is 0.  */
+               if (!has_precision)
+                 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
+                   precision = 6;
+
+               /* Allocate a temporary buffer of sufficient size.  */
+# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
+               tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG 
+ 1);
+# elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
+               tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
+# elif NEED_PRINTF_LONG_DOUBLE
+               tmp_length = LDBL_DIG + 1;
+# elif NEED_PRINTF_DOUBLE
+               tmp_length = DBL_DIG + 1;
+# else
+               tmp_length = 0;
+# endif
+               if (tmp_length < precision)
+                 tmp_length = precision;
+# if NEED_PRINTF_LONG_DOUBLE
+#  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
+               if (type == TYPE_LONGDOUBLE)
+#  endif
+                 if (dp->conversion == 'f' || dp->conversion == 'F')
+                   {
+                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
+                     if (!(isnanl (arg) || arg + arg == arg))
+                       {
+                         /* arg is finite and nonzero.  */
+                         int exponent = floorlog10l (arg < 0 ? -arg : arg);
+                         if (exponent >= 0 && tmp_length < exponent + 
precision)
+                           tmp_length = exponent + precision;
+                       }
+                   }
+# endif
+# if NEED_PRINTF_DOUBLE
+#  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
+               if (type == TYPE_DOUBLE)
+#  endif
+                 if (dp->conversion == 'f' || dp->conversion == 'F')
+                   {
+                     double arg = a.arg[dp->arg_index].a.a_double;
+                     if (!(isnand (arg) || arg + arg == arg))
+                       {
+                         /* arg is finite and nonzero.  */
+                         int exponent = floorlog10 (arg < 0 ? -arg : arg);
+                         if (exponent >= 0 && tmp_length < exponent + 
precision)
+                           tmp_length = exponent + precision;
+                       }
+                   }
+# endif
+               /* Account for sign, decimal point etc. */
+               tmp_length = xsum (tmp_length, 12);
+
+               if (tmp_length < width)
+                 tmp_length = width;
+
+               tmp_length = xsum (tmp_length, 1); /* account for trailing NUL 
*/
+
+               if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
+                 tmp = tmpbuf;
+               else
+                 {
+                   size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
+
+                   if (size_overflow_p (tmp_memsize))
+                     /* Overflow, would lead to out of memory.  */
+                     goto out_of_memory;
+                   tmp = (DCHAR_T *) malloc (tmp_memsize);
+                   if (tmp == NULL)
+                     /* Out of memory.  */
+                     goto out_of_memory;
+                 }
+
+               pad_ptr = NULL;
+               p = tmp;
+
+# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
+#  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
+               if (type == TYPE_LONGDOUBLE)
+#  endif
+                 {
+                   long double arg = a.arg[dp->arg_index].a.a_longdouble;
+
+                   if (isnanl (arg))
+                     {
+                       if (dp->conversion >= 'A' && dp->conversion <= 'Z')
+                         {
+                           *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
+                         }
+                       else
+                         {
+                           *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
+                         }
+                     }
+                   else
+                     {
+                       int sign = 0;
+                       DECL_LONG_DOUBLE_ROUNDING
+
+                       BEGIN_LONG_DOUBLE_ROUNDING ();
+
+                       if (signbit (arg)) /* arg < 0.0L or negative zero */
+                         {
+                           sign = -1;
+                           arg = -arg;
+                         }
+
+                       if (sign < 0)
+                         *p++ = '-';
+                       else if (flags & FLAG_SHOWSIGN)
+                         *p++ = '+';
+                       else if (flags & FLAG_SPACE)
+                         *p++ = ' ';
+
+                       if (arg > 0.0L && arg + arg == arg)
+                         {
+                           if (dp->conversion >= 'A' && dp->conversion <= 'Z')
+                             {
+                               *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
+                             }
+                           else
+                             {
+                               *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+                             }
+                         }
+                       else
+                         {
+#  if NEED_PRINTF_LONG_DOUBLE
+                           pad_ptr = p;
+
+                           if (dp->conversion == 'f' || dp->conversion == 'F')
+                             {
+                               char *digits;
+                               size_t ndigits;
+
+                               digits =
+                                 scale10_round_decimal_long_double (arg, 
precision);
+                               if (digits == NULL)
+                                 {
+                                   END_LONG_DOUBLE_ROUNDING ();
+                                   goto out_of_memory;
+                                 }
+                               ndigits = strlen (digits);
+
+                               if (ndigits > precision)
+                                 do
+                                   {
+                                     --ndigits;
+                                     *p++ = digits[ndigits];
+                                   }
+                                 while (ndigits > precision);
+                               else
+                                 *p++ = '0';
+                               /* Here ndigits <= precision.  */
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > ndigits; precision--)
+                                     *p++ = '0';
+                                   while (ndigits > 0)
+                                     {
+                                       --ndigits;
+                                       *p++ = digits[ndigits];
+                                     }
+                                 }
+
+                               free (digits);
+                             }
+                           else if (dp->conversion == 'e' || dp->conversion == 
'E')
+                             {
+                               int exponent;
+
+                               if (arg == 0.0L)
+                                 {
+                                   exponent = 0;
+                                   *p++ = '0';
+                                   if ((flags & FLAG_ALT) || precision > 0)
+                                     {
+                                       *p++ = decimal_point_char ();
+                                       for (; precision > 0; precision--)
+                                         *p++ = '0';
+                                     }
+                                 }
+                               else
+                                 {
+                                   /* arg > 0.0L.  */
+                                   int adjusted;
+                                   char *digits;
+                                   size_t ndigits;
+
+                                   exponent = floorlog10l (arg);
+                                   adjusted = 0;
+                                   for (;;)
+                                     {
+                                       digits =
+                                         scale10_round_decimal_long_double 
(arg,
+                                                                            
(int)precision - exponent);
+                                       if (digits == NULL)
+                                         {
+                                           END_LONG_DOUBLE_ROUNDING ();
+                                           goto out_of_memory;
+                                         }
+                                       ndigits = strlen (digits);
+
+                                       if (ndigits == precision + 1)
+                                         break;
+                                       if (ndigits < precision
+                                           || ndigits > precision + 2)
+                                         /* The exponent was not guessed
+                                            precisely enough.  */
+                                         abort ();
+                                       if (adjusted)
+                                         /* None of two values of exponent is
+                                            the right one.  Prevent an endless
+                                            loop.  */
+                                         abort ();
+                                       free (digits);
+                                       if (ndigits == precision)
+                                         exponent -= 1;
+                                       else
+                                         exponent += 1;
+                                       adjusted = 1;
+                                     }
+                                   /* Here ndigits = precision+1.  */
+                                   if (is_borderline (digits, precision))
+                                     {
+                                       /* Maybe the exponent guess was too high
+                                          and a smaller exponent can be reached
+                                          by turning a 10...0 into 9...9x.  */
+                                       char *digits2 =
+                                         scale10_round_decimal_long_double 
(arg,
+                                                                            
(int)precision - exponent + 1);
+                                       if (digits2 == NULL)
+                                         {
+                                           free (digits);
+                                           END_LONG_DOUBLE_ROUNDING ();
+                                           goto out_of_memory;
+                                         }
+                                       if (strlen (digits2) == precision + 1)
+                                         {
+                                           free (digits);
+                                           digits = digits2;
+                                           exponent -= 1;
+                                         }
+                                       else
+                                         free (digits2);
+                                     }
+                                   /* Here ndigits = precision+1.  */
+
+                                   *p++ = digits[--ndigits];
+                                   if ((flags & FLAG_ALT) || precision > 0)
+                                     {
+                                       *p++ = decimal_point_char ();
+                                       while (ndigits > 0)
+                                         {
+                                           --ndigits;
+                                           *p++ = digits[ndigits];
+                                         }
+                                     }
+
+                                   free (digits);
+                                 }
+
+                               *p++ = dp->conversion; /* 'e' or 'E' */
+#   if WIDE_CHAR_VERSION
+                               {
+                                 static const wchar_t decimal_format[] =
+                                   { '%', '+', '.', '2', 'd', '\0' };
+                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
+                               }
+                               while (*p != '\0')
+                                 p++;
+#   else
+                               if (sizeof (DCHAR_T) == 1)
+                                 {
+                                   sprintf ((char *) p, "%+.2d", exponent);
+                                   while (*p != '\0')
+                                     p++;
+                                 }
+                               else
+                                 {
+                                   char expbuf[6 + 1];
+                                   const char *ep;
+                                   sprintf (expbuf, "%+.2d", exponent);
+                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
+                                     p++;
+                                 }
+#   endif
+                             }
+                           else if (dp->conversion == 'g' || dp->conversion == 
'G')
+                             {
+                               if (precision == 0)
+                                 precision = 1;
+                               /* precision >= 1.  */
+
+                               if (arg == 0.0L)
+                                 /* The exponent is 0, >= -4, < precision.
+                                    Use fixed-point notation.  */
+                                 {
+                                   size_t ndigits = precision;
+                                   /* Number of trailing zeroes that have to be
+                                      dropped.  */
+                                   size_t nzeroes =
+                                     (flags & FLAG_ALT ? 0 : precision - 1);
+
+                                   --ndigits;
+                                   *p++ = '0';
+                                   if ((flags & FLAG_ALT) || ndigits > nzeroes)
+                                     {
+                                       *p++ = decimal_point_char ();
+                                       while (ndigits > nzeroes)
+                                         {
+                                           --ndigits;
+                                           *p++ = '0';
+                                         }
+                                     }
+                                 }
+                               else
+                                 {
+                                   /* arg > 0.0L.  */
+                                   int exponent;
+                                   int adjusted;
+                                   char *digits;
+                                   size_t ndigits;
+                                   size_t nzeroes;
+
+                                   exponent = floorlog10l (arg);
+                                   adjusted = 0;
+                                   for (;;)
+                                     {
+                                       digits =
+                                         scale10_round_decimal_long_double 
(arg,
+                                                                            
(int)(precision - 1) - exponent);
+                                       if (digits == NULL)
+                                         {
+                                           END_LONG_DOUBLE_ROUNDING ();
+                                           goto out_of_memory;
+                                         }
+                                       ndigits = strlen (digits);
+
+                                       if (ndigits == precision)
+                                         break;
+                                       if (ndigits < precision - 1
+                                           || ndigits > precision + 1)
+                                         /* The exponent was not guessed
+                                            precisely enough.  */
+                                         abort ();
+                                       if (adjusted)
+                                         /* None of two values of exponent is
+                                            the right one.  Prevent an endless
+                                            loop.  */
+                                         abort ();
+                                       free (digits);
+                                       if (ndigits < precision)
+                                         exponent -= 1;
+                                       else
+                                         exponent += 1;
+                                       adjusted = 1;
+                                     }
+                                   /* Here ndigits = precision.  */
+                                   if (is_borderline (digits, precision - 1))
+                                     {
+                                       /* Maybe the exponent guess was too high
+                                          and a smaller exponent can be reached
+                                          by turning a 10...0 into 9...9x.  */
+                                       char *digits2 =
+                                         scale10_round_decimal_long_double 
(arg,
+                                                                            
(int)(precision - 1) - exponent + 1);
+                                       if (digits2 == NULL)
+                                         {
+                                           free (digits);
+                                           END_LONG_DOUBLE_ROUNDING ();
+                                           goto out_of_memory;
+                                         }
+                                       if (strlen (digits2) == precision)
+                                         {
+                                           free (digits);
+                                           digits = digits2;
+                                           exponent -= 1;
+                                         }
+                                       else
+                                         free (digits2);
+                                     }
+                                   /* Here ndigits = precision.  */
+
+                                   /* Determine the number of trailing zeroes
+                                      that have to be dropped.  */
+                                   nzeroes = 0;
+                                   if ((flags & FLAG_ALT) == 0)
+                                     while (nzeroes < ndigits
+                                            && digits[nzeroes] == '0')
+                                       nzeroes++;
+
+                                   /* The exponent is now determined.  */
+                                   if (exponent >= -4
+                                       && exponent < (long)precision)
+                                     {
+                                       /* Fixed-point notation:
+                                          max(exponent,0)+1 digits, then the
+                                          decimal point, then the remaining
+                                          digits without trailing zeroes.  */
+                                       if (exponent >= 0)
+                                         {
+                                           size_t count = exponent + 1;
+                                           /* Note: count <= precision = 
ndigits.  */
+                                           for (; count > 0; count--)
+                                             *p++ = digits[--ndigits];
+                                           if ((flags & FLAG_ALT) || ndigits > 
nzeroes)
+                                             {
+                                               *p++ = decimal_point_char ();
+                                               while (ndigits > nzeroes)
+                                                 {
+                                                   --ndigits;
+                                                   *p++ = digits[ndigits];
+                                                 }
+                                             }
+                                         }
+                                       else
+                                         {
+                                           size_t count = -exponent - 1;
+                                           *p++ = '0';
+                                           *p++ = decimal_point_char ();
+                                           for (; count > 0; count--)
+                                             *p++ = '0';
+                                           while (ndigits > nzeroes)
+                                             {
+                                               --ndigits;
+                                               *p++ = digits[ndigits];
+                                             }
+                                         }
+                                     }
+                                   else
+                                     {
+                                       /* Exponential notation.  */
+                                       *p++ = digits[--ndigits];
+                                       if ((flags & FLAG_ALT) || ndigits > 
nzeroes)
+                                         {
+                                           *p++ = decimal_point_char ();
+                                           while (ndigits > nzeroes)
+                                             {
+                                               --ndigits;
+                                               *p++ = digits[ndigits];
+                                             }
+                                         }
+                                       *p++ = dp->conversion - 'G' + 'E'; /* 
'e' or 'E' */
+#   if WIDE_CHAR_VERSION
+                                       {
+                                         static const wchar_t decimal_format[] 
=
+                                           { '%', '+', '.', '2', 'd', '\0' };
+                                         SNPRINTF (p, 6 + 1, decimal_format, 
exponent);
+                                       }
+                                       while (*p != '\0')
+                                         p++;
+#   else
+                                       if (sizeof (DCHAR_T) == 1)
+                                         {
+                                           sprintf ((char *) p, "%+.2d", 
exponent);
+                                           while (*p != '\0')
+                                             p++;
+                                         }
+                                       else
+                                         {
+                                           char expbuf[6 + 1];
+                                           const char *ep;
+                                           sprintf (expbuf, "%+.2d", exponent);
+                                           for (ep = expbuf; (*p = *ep) != 
'\0'; ep++)
+                                             p++;
+                                         }
+#   endif
+                                     }
+
+                                   free (digits);
+                                 }
+                             }
+                           else
+                             abort ();
+#  else
+                           /* arg is finite.  */
+                           if (!(arg == 0.0L))
+                             abort ();
+
+                           pad_ptr = p;
+
+                           if (dp->conversion == 'f' || dp->conversion == 'F')
+                             {
+                               *p++ = '0';
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > 0; precision--)
+                                     *p++ = '0';
+                                 }
+                             }
+                           else if (dp->conversion == 'e' || dp->conversion == 
'E')
+                             {
+                               *p++ = '0';
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > 0; precision--)
+                                     *p++ = '0';
+                                 }
+                               *p++ = dp->conversion; /* 'e' or 'E' */
+                               *p++ = '+';
+                               *p++ = '0';
+                               *p++ = '0';
+                             }
+                           else if (dp->conversion == 'g' || dp->conversion == 
'G')
+                             {
+                               *p++ = '0';
+                               if (flags & FLAG_ALT)
+                                 {
+                                   size_t ndigits =
+                                     (precision > 0 ? precision - 1 : 0);
+                                   *p++ = decimal_point_char ();
+                                   for (; ndigits > 0; --ndigits)
+                                     *p++ = '0';
+                                 }
+                             }
+                           else if (dp->conversion == 'a' || dp->conversion == 
'A')
+                             {
+                               *p++ = '0';
+                               *p++ = dp->conversion - 'A' + 'X';
+                               pad_ptr = p;
+                               *p++ = '0';
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > 0; precision--)
+                                     *p++ = '0';
+                                 }
+                               *p++ = dp->conversion - 'A' + 'P';
+                               *p++ = '+';
+                               *p++ = '0';
+                             }
+                           else
+                             abort ();
+#  endif
+                         }
+
+                       END_LONG_DOUBLE_ROUNDING ();
+                     }
+                 }
+#  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
+               else
+#  endif
+# endif
+# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
+                 {
+                   double arg = a.arg[dp->arg_index].a.a_double;
+
+                   if (isnand (arg))
+                     {
+                       if (dp->conversion >= 'A' && dp->conversion <= 'Z')
+                         {
+                           *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
+                         }
+                       else
+                         {
+                           *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
+                         }
+                     }
+                   else
+                     {
+                       int sign = 0;
+
+                       if (signbit (arg)) /* arg < 0.0 or negative zero */
+                         {
+                           sign = -1;
+                           arg = -arg;
+                         }
+
+                       if (sign < 0)
+                         *p++ = '-';
+                       else if (flags & FLAG_SHOWSIGN)
+                         *p++ = '+';
+                       else if (flags & FLAG_SPACE)
+                         *p++ = ' ';
+
+                       if (arg > 0.0 && arg + arg == arg)
+                         {
+                           if (dp->conversion >= 'A' && dp->conversion <= 'Z')
+                             {
+                               *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
+                             }
+                           else
+                             {
+                               *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+                             }
+                         }
+                       else
+                         {
+#  if NEED_PRINTF_DOUBLE
+                           pad_ptr = p;
+
+                           if (dp->conversion == 'f' || dp->conversion == 'F')
+                             {
+                               char *digits;
+                               size_t ndigits;
+
+                               digits =
+                                 scale10_round_decimal_double (arg, precision);
+                               if (digits == NULL)
+                                 goto out_of_memory;
+                               ndigits = strlen (digits);
+
+                               if (ndigits > precision)
+                                 do
+                                   {
+                                     --ndigits;
+                                     *p++ = digits[ndigits];
+                                   }
+                                 while (ndigits > precision);
+                               else
+                                 *p++ = '0';
+                               /* Here ndigits <= precision.  */
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > ndigits; precision--)
+                                     *p++ = '0';
+                                   while (ndigits > 0)
+                                     {
+                                       --ndigits;
+                                       *p++ = digits[ndigits];
+                                     }
+                                 }
+
+                               free (digits);
+                             }
+                           else if (dp->conversion == 'e' || dp->conversion == 
'E')
+                             {
+                               int exponent;
+
+                               if (arg == 0.0)
+                                 {
+                                   exponent = 0;
+                                   *p++ = '0';
+                                   if ((flags & FLAG_ALT) || precision > 0)
+                                     {
+                                       *p++ = decimal_point_char ();
+                                       for (; precision > 0; precision--)
+                                         *p++ = '0';
+                                     }
+                                 }
+                               else
+                                 {
+                                   /* arg > 0.0.  */
+                                   int adjusted;
+                                   char *digits;
+                                   size_t ndigits;
+
+                                   exponent = floorlog10 (arg);
+                                   adjusted = 0;
+                                   for (;;)
+                                     {
+                                       digits =
+                                         scale10_round_decimal_double (arg,
+                                                                       
(int)precision - exponent);
+                                       if (digits == NULL)
+                                         goto out_of_memory;
+                                       ndigits = strlen (digits);
+
+                                       if (ndigits == precision + 1)
+                                         break;
+                                       if (ndigits < precision
+                                           || ndigits > precision + 2)
+                                         /* The exponent was not guessed
+                                            precisely enough.  */
+                                         abort ();
+                                       if (adjusted)
+                                         /* None of two values of exponent is
+                                            the right one.  Prevent an endless
+                                            loop.  */
+                                         abort ();
+                                       free (digits);
+                                       if (ndigits == precision)
+                                         exponent -= 1;
+                                       else
+                                         exponent += 1;
+                                       adjusted = 1;
+                                     }
+                                   /* Here ndigits = precision+1.  */
+                                   if (is_borderline (digits, precision))
+                                     {
+                                       /* Maybe the exponent guess was too high
+                                          and a smaller exponent can be reached
+                                          by turning a 10...0 into 9...9x.  */
+                                       char *digits2 =
+                                         scale10_round_decimal_double (arg,
+                                                                       
(int)precision - exponent + 1);
+                                       if (digits2 == NULL)
+                                         {
+                                           free (digits);
+                                           goto out_of_memory;
+                                         }
+                                       if (strlen (digits2) == precision + 1)
+                                         {
+                                           free (digits);
+                                           digits = digits2;
+                                           exponent -= 1;
+                                         }
+                                       else
+                                         free (digits2);
+                                     }
+                                   /* Here ndigits = precision+1.  */
+
+                                   *p++ = digits[--ndigits];
+                                   if ((flags & FLAG_ALT) || precision > 0)
+                                     {
+                                       *p++ = decimal_point_char ();
+                                       while (ndigits > 0)
+                                         {
+                                           --ndigits;
+                                           *p++ = digits[ndigits];
+                                         }
+                                     }
+
+                                   free (digits);
+                                 }
+
+                               *p++ = dp->conversion; /* 'e' or 'E' */
+#   if WIDE_CHAR_VERSION
+                               {
+                                 static const wchar_t decimal_format[] =
+                                   /* Produce the same number of exponent 
digits
+                                      as the native printf implementation.  */
+#    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+                                   { '%', '+', '.', '3', 'd', '\0' };
+#    else
+                                   { '%', '+', '.', '2', 'd', '\0' };
+#    endif
+                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
+                               }
+                               while (*p != '\0')
+                                 p++;
+#   else
+                               {
+                                 static const char decimal_format[] =
+                                   /* Produce the same number of exponent 
digits
+                                      as the native printf implementation.  */
+#    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+                                   "%+.3d";
+#    else
+                                   "%+.2d";
+#    endif
+                                 if (sizeof (DCHAR_T) == 1)
+                                   {
+                                     sprintf ((char *) p, decimal_format, 
exponent);
+                                     while (*p != '\0')
+                                       p++;
+                                   }
+                                 else
+                                   {
+                                     char expbuf[6 + 1];
+                                     const char *ep;
+                                     sprintf (expbuf, decimal_format, 
exponent);
+                                     for (ep = expbuf; (*p = *ep) != '\0'; 
ep++)
+                                       p++;
+                                   }
+                               }
+#   endif
+                             }
+                           else if (dp->conversion == 'g' || dp->conversion == 
'G')
+                             {
+                               if (precision == 0)
+                                 precision = 1;
+                               /* precision >= 1.  */
+
+                               if (arg == 0.0)
+                                 /* The exponent is 0, >= -4, < precision.
+                                    Use fixed-point notation.  */
+                                 {
+                                   size_t ndigits = precision;
+                                   /* Number of trailing zeroes that have to be
+                                      dropped.  */
+                                   size_t nzeroes =
+                                     (flags & FLAG_ALT ? 0 : precision - 1);
+
+                                   --ndigits;
+                                   *p++ = '0';
+                                   if ((flags & FLAG_ALT) || ndigits > nzeroes)
+                                     {
+                                       *p++ = decimal_point_char ();
+                                       while (ndigits > nzeroes)
+                                         {
+                                           --ndigits;
+                                           *p++ = '0';
+                                         }
+                                     }
+                                 }
+                               else
+                                 {
+                                   /* arg > 0.0.  */
+                                   int exponent;
+                                   int adjusted;
+                                   char *digits;
+                                   size_t ndigits;
+                                   size_t nzeroes;
+
+                                   exponent = floorlog10 (arg);
+                                   adjusted = 0;
+                                   for (;;)
+                                     {
+                                       digits =
+                                         scale10_round_decimal_double (arg,
+                                                                       
(int)(precision - 1) - exponent);
+                                       if (digits == NULL)
+                                         goto out_of_memory;
+                                       ndigits = strlen (digits);
+
+                                       if (ndigits == precision)
+                                         break;
+                                       if (ndigits < precision - 1
+                                           || ndigits > precision + 1)
+                                         /* The exponent was not guessed
+                                            precisely enough.  */
+                                         abort ();
+                                       if (adjusted)
+                                         /* None of two values of exponent is
+                                            the right one.  Prevent an endless
+                                            loop.  */
+                                         abort ();
+                                       free (digits);
+                                       if (ndigits < precision)
+                                         exponent -= 1;
+                                       else
+                                         exponent += 1;
+                                       adjusted = 1;
+                                     }
+                                   /* Here ndigits = precision.  */
+                                   if (is_borderline (digits, precision - 1))
+                                     {
+                                       /* Maybe the exponent guess was too high
+                                          and a smaller exponent can be reached
+                                          by turning a 10...0 into 9...9x.  */
+                                       char *digits2 =
+                                         scale10_round_decimal_double (arg,
+                                                                       
(int)(precision - 1) - exponent + 1);
+                                       if (digits2 == NULL)
+                                         {
+                                           free (digits);
+                                           goto out_of_memory;
+                                         }
+                                       if (strlen (digits2) == precision)
+                                         {
+                                           free (digits);
+                                           digits = digits2;
+                                           exponent -= 1;
+                                         }
+                                       else
+                                         free (digits2);
+                                     }
+                                   /* Here ndigits = precision.  */
+
+                                   /* Determine the number of trailing zeroes
+                                      that have to be dropped.  */
+                                   nzeroes = 0;
+                                   if ((flags & FLAG_ALT) == 0)
+                                     while (nzeroes < ndigits
+                                            && digits[nzeroes] == '0')
+                                       nzeroes++;
+
+                                   /* The exponent is now determined.  */
+                                   if (exponent >= -4
+                                       && exponent < (long)precision)
+                                     {
+                                       /* Fixed-point notation:
+                                          max(exponent,0)+1 digits, then the
+                                          decimal point, then the remaining
+                                          digits without trailing zeroes.  */
+                                       if (exponent >= 0)
+                                         {
+                                           size_t count = exponent + 1;
+                                           /* Note: count <= precision = 
ndigits.  */
+                                           for (; count > 0; count--)
+                                             *p++ = digits[--ndigits];
+                                           if ((flags & FLAG_ALT) || ndigits > 
nzeroes)
+                                             {
+                                               *p++ = decimal_point_char ();
+                                               while (ndigits > nzeroes)
+                                                 {
+                                                   --ndigits;
+                                                   *p++ = digits[ndigits];
+                                                 }
+                                             }
+                                         }
+                                       else
+                                         {
+                                           size_t count = -exponent - 1;
+                                           *p++ = '0';
+                                           *p++ = decimal_point_char ();
+                                           for (; count > 0; count--)
+                                             *p++ = '0';
+                                           while (ndigits > nzeroes)
+                                             {
+                                               --ndigits;
+                                               *p++ = digits[ndigits];
+                                             }
+                                         }
+                                     }
+                                   else
+                                     {
+                                       /* Exponential notation.  */
+                                       *p++ = digits[--ndigits];
+                                       if ((flags & FLAG_ALT) || ndigits > 
nzeroes)
+                                         {
+                                           *p++ = decimal_point_char ();
+                                           while (ndigits > nzeroes)
+                                             {
+                                               --ndigits;
+                                               *p++ = digits[ndigits];
+                                             }
+                                         }
+                                       *p++ = dp->conversion - 'G' + 'E'; /* 
'e' or 'E' */
+#   if WIDE_CHAR_VERSION
+                                       {
+                                         static const wchar_t decimal_format[] 
=
+                                           /* Produce the same number of 
exponent digits
+                                              as the native printf 
implementation.  */
+#    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+                                           { '%', '+', '.', '3', 'd', '\0' };
+#    else
+                                           { '%', '+', '.', '2', 'd', '\0' };
+#    endif
+                                         SNPRINTF (p, 6 + 1, decimal_format, 
exponent);
+                                       }
+                                       while (*p != '\0')
+                                         p++;
+#   else
+                                       {
+                                         static const char decimal_format[] =
+                                           /* Produce the same number of 
exponent digits
+                                              as the native printf 
implementation.  */
+#    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+                                           "%+.3d";
+#    else
+                                           "%+.2d";
+#    endif
+                                         if (sizeof (DCHAR_T) == 1)
+                                           {
+                                             sprintf ((char *) p, 
decimal_format, exponent);
+                                             while (*p != '\0')
+                                               p++;
+                                           }
+                                         else
+                                           {
+                                             char expbuf[6 + 1];
+                                             const char *ep;
+                                             sprintf (expbuf, decimal_format, 
exponent);
+                                             for (ep = expbuf; (*p = *ep) != 
'\0'; ep++)
+                                               p++;
+                                           }
+                                       }
+#   endif
+                                     }
+
+                                   free (digits);
+                                 }
+                             }
+                           else
+                             abort ();
+#  else
+                           /* arg is finite.  */
+                           if (!(arg == 0.0))
+                             abort ();
+
+                           pad_ptr = p;
+
+                           if (dp->conversion == 'f' || dp->conversion == 'F')
+                             {
+                               *p++ = '0';
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > 0; precision--)
+                                     *p++ = '0';
+                                 }
+                             }
+                           else if (dp->conversion == 'e' || dp->conversion == 
'E')
+                             {
+                               *p++ = '0';
+                               if ((flags & FLAG_ALT) || precision > 0)
+                                 {
+                                   *p++ = decimal_point_char ();
+                                   for (; precision > 0; precision--)
+                                     *p++ = '0';
+                                 }
+                               *p++ = dp->conversion; /* 'e' or 'E' */
+                               *p++ = '+';
+                               /* Produce the same number of exponent digits as
+                                  the native printf implementation.  */
+#   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+                               *p++ = '0';
+#   endif
+                               *p++ = '0';
+                               *p++ = '0';
+                             }
+                           else if (dp->conversion == 'g' || dp->conversion == 
'G')
+                             {
+                               *p++ = '0';
+                               if (flags & FLAG_ALT)
+                                 {
+                                   size_t ndigits =
+                                     (precision > 0 ? precision - 1 : 0);
+                                   *p++ = decimal_point_char ();
+                                   for (; ndigits > 0; --ndigits)
+                                     *p++ = '0';
+                                 }
+                             }
+                           else
+                             abort ();
+#  endif
+                         }
+                     }
+                 }
+# endif
+
+               /* The generated string now extends from tmp to p, with the
+                  zero padding insertion point being at pad_ptr.  */
+               if (has_width && p - tmp < width)
+                 {
+                   size_t pad = width - (p - tmp);
+                   DCHAR_T *end = p + pad;
+
+                   if (flags & FLAG_LEFT)
+                     {
+                       /* Pad with spaces on the right.  */
+                       for (; pad > 0; pad--)
+                         *p++ = ' ';
+                     }
+                   else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
+                     {
+                       /* Pad with zeroes.  */
+                       DCHAR_T *q = end;
+
+                       while (p > pad_ptr)
+                         *--q = *--p;
+                       for (; pad > 0; pad--)
+                         *p++ = '0';
+                     }
+                   else
+                     {
+                       /* Pad with spaces on the left.  */
+                       DCHAR_T *q = end;
+
+                       while (p > tmp)
+                         *--q = *--p;
+                       for (; pad > 0; pad--)
+                         *p++ = ' ';
+                     }
+
+                   p = end;
+                 }
+
+               {
+                 size_t count = p - tmp;
+
+                 if (count >= tmp_length)
+                   /* tmp_length was incorrectly calculated - fix the
+                      code above!  */
+                   abort ();
+
+                 /* Make room for the result.  */
+                 if (count >= allocated - length)
+                   {
+                     size_t n = xsum (length, count);
+
+                     ENSURE_ALLOCATION (n);
+                   }
+
+                 /* Append the result.  */
+                 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
+                 if (tmp != tmpbuf)
+                   free (tmp);
+                 length += count;
+               }
+             }
+#endif
+           else
+             {
+               arg_type type = a.arg[dp->arg_index].type;
+               int flags = dp->flags;
+#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || 
NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || 
NEED_PRINTF_UNBOUNDED_PRECISION
+               int has_width;
+               size_t width;
+#endif
+#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
+               int has_precision;
+               size_t precision;
+#endif
+#if NEED_PRINTF_UNBOUNDED_PRECISION
+               int prec_ourselves;
+#else
+#              define prec_ourselves 0
+#endif
+#if NEED_PRINTF_FLAG_LEFTADJUST
+#              define pad_ourselves 1
+#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || 
NEED_PRINTF_UNBOUNDED_PRECISION
+               int pad_ourselves;
+#else
+#              define pad_ourselves 0
+#endif
+               TCHAR_T *fbp;
+               unsigned int prefix_count;
+               int prefixes[2] IF_LINT (= { 0 });
+#if !USE_SNPRINTF
+               size_t tmp_length;
+               TCHAR_T tmpbuf[700];
+               TCHAR_T *tmp;
+#endif
+
+#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || 
NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || 
NEED_PRINTF_UNBOUNDED_PRECISION
+               has_width = 0;
+               width = 0;
+               if (dp->width_start != dp->width_end)
+                 {
+                   if (dp->width_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->width_arg_index].a.a_int;
+                       if (arg < 0)
+                         {
+                           /* "A negative field width is taken as a '-' flag
+                               followed by a positive field width."  */
+                           flags |= FLAG_LEFT;
+                           width = (unsigned int) (-arg);
+                         }
+                       else
+                         width = arg;
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->width_start;
+
+                       do
+                         width = xsum (xtimes (width, 10), *digitp++ - '0');
+                       while (digitp != dp->width_end);
+                     }
+                   has_width = 1;
+                 }
+#endif
+
+#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
+               has_precision = 0;
+               precision = 6;
+               if (dp->precision_start != dp->precision_end)
+                 {
+                   if (dp->precision_arg_index != ARG_NONE)
+                     {
+                       int arg;
+
+                       if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+                         abort ();
+                       arg = a.arg[dp->precision_arg_index].a.a_int;
+                       /* "A negative precision is taken as if the precision
+                           were omitted."  */
+                       if (arg >= 0)
+                         {
+                           precision = arg;
+                           has_precision = 1;
+                         }
+                     }
+                   else
+                     {
+                       const FCHAR_T *digitp = dp->precision_start + 1;
+
+                       precision = 0;
+                       while (digitp != dp->precision_end)
+                         precision = xsum (xtimes (precision, 10), *digitp++ - 
'0');
+                       has_precision = 1;
+                     }
+                 }
+#endif
+
+               /* Decide whether to handle the precision ourselves.  */
+#if NEED_PRINTF_UNBOUNDED_PRECISION
+               switch (dp->conversion)
+                 {
+                 case 'd': case 'i': case 'u':
+                 case 'o':
+                 case 'x': case 'X': case 'p':
+                   prec_ourselves = has_precision && (precision > 0);
+                   break;
+                 default:
+                   prec_ourselves = 0;
+                   break;
+                 }
+#endif
+
+               /* Decide whether to perform the padding ourselves.  */
+#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || 
NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
+               switch (dp->conversion)
+                 {
+# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
+                 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
+                    to perform the padding after this conversion.  Functions
+                    with unistdio extensions perform the padding based on
+                    character count rather than element count.  */
+                 case 'c': case 's':
+# endif
+# if NEED_PRINTF_FLAG_ZERO
+                 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
+                 case 'a': case 'A':
+# endif
+                   pad_ourselves = 1;
+                   break;
+                 default:
+                   pad_ourselves = prec_ourselves;
+                   break;
+                 }
+#endif
+
+#if !USE_SNPRINTF
+               /* Allocate a temporary buffer of sufficient size for calling
+                  sprintf.  */
+               {
+                 switch (dp->conversion)
+                   {
+
+                   case 'd': case 'i': case 'u':
+# if HAVE_LONG_LONG_INT
+                     if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
+                                         * 0.30103 /* binary -> decimal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     else
+# endif
+                     if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned long) * CHAR_BIT
+                                         * 0.30103 /* binary -> decimal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     else
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned int) * CHAR_BIT
+                                         * 0.30103 /* binary -> decimal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     if (tmp_length < precision)
+                       tmp_length = precision;
+                     /* Multiply by 2, as an estimate for FLAG_GROUP.  */
+                     tmp_length = xsum (tmp_length, tmp_length);
+                     /* Add 1, to account for a leading sign.  */
+                     tmp_length = xsum (tmp_length, 1);
+                     break;
+
+                   case 'o':
+# if HAVE_LONG_LONG_INT
+                     if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
+                                         * 0.333334 /* binary -> octal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     else
+# endif
+                     if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned long) * CHAR_BIT
+                                         * 0.333334 /* binary -> octal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     else
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned int) * CHAR_BIT
+                                         * 0.333334 /* binary -> octal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     if (tmp_length < precision)
+                       tmp_length = precision;
+                     /* Add 1, to account for a leading sign.  */
+                     tmp_length = xsum (tmp_length, 1);
+                     break;
+
+                   case 'x': case 'X':
+# if HAVE_LONG_LONG_INT
+                     if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
+                                         * 0.25 /* binary -> hexadecimal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     else
+# endif
+                     if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned long) * CHAR_BIT
+                                         * 0.25 /* binary -> hexadecimal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     else
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned int) * CHAR_BIT
+                                         * 0.25 /* binary -> hexadecimal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     if (tmp_length < precision)
+                       tmp_length = precision;
+                     /* Add 2, to account for a leading sign or alternate 
form.  */
+                     tmp_length = xsum (tmp_length, 2);
+                     break;
+
+                   case 'f': case 'F':
+                     if (type == TYPE_LONGDOUBLE)
+                       tmp_length =
+                         (unsigned int) (LDBL_MAX_EXP
+                                         * 0.30103 /* binary -> decimal */
+                                         * 2 /* estimate for FLAG_GROUP */
+                                        )
+                         + 1 /* turn floor into ceil */
+                         + 10; /* sign, decimal point etc. */
+                     else
+                       tmp_length =
+                         (unsigned int) (DBL_MAX_EXP
+                                         * 0.30103 /* binary -> decimal */
+                                         * 2 /* estimate for FLAG_GROUP */
+                                        )
+                         + 1 /* turn floor into ceil */
+                         + 10; /* sign, decimal point etc. */
+                     tmp_length = xsum (tmp_length, precision);
+                     break;
+
+                   case 'e': case 'E': case 'g': case 'G':
+                     tmp_length =
+                       12; /* sign, decimal point, exponent etc. */
+                     tmp_length = xsum (tmp_length, precision);
+                     break;
+
+                   case 'a': case 'A':
+                     if (type == TYPE_LONGDOUBLE)
+                       tmp_length =
+                         (unsigned int) (LDBL_DIG
+                                         * 0.831 /* decimal -> hexadecimal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     else
+                       tmp_length =
+                         (unsigned int) (DBL_DIG
+                                         * 0.831 /* decimal -> hexadecimal */
+                                        )
+                         + 1; /* turn floor into ceil */
+                     if (tmp_length < precision)
+                       tmp_length = precision;
+                     /* Account for sign, decimal point etc. */
+                     tmp_length = xsum (tmp_length, 12);
+                     break;
+
+                   case 'c':
+# if HAVE_WINT_T && !WIDE_CHAR_VERSION
+                     if (type == TYPE_WIDE_CHAR)
+                       tmp_length = MB_CUR_MAX;
+                     else
+# endif
+                       tmp_length = 1;
+                     break;
+
+                   case 's':
+# if HAVE_WCHAR_T
+                     if (type == TYPE_WIDE_STRING)
+                       {
+#  if WIDE_CHAR_VERSION
+                         /* ISO C says about %ls in fwprintf:
+                              "If the precision is not specified or is greater
+                               than the size of the array, the array shall
+                               contain a null wide character."
+                            So if there is a precision, we must not use
+                            wcslen.  */
+                         const wchar_t *arg =
+                           a.arg[dp->arg_index].a.a_wide_string;
+
+                         if (has_precision)
+                           tmp_length = local_wcsnlen (arg, precision);
+                         else
+                           tmp_length = local_wcslen (arg);
+#  else
+                         /* ISO C says about %ls in fprintf:
+                              "If a precision is specified, no more than that
+                               many bytes are written (including shift
+                               sequences, if any), and the array shall contain
+                               a null wide character if, to equal the
+                               multibyte character sequence length given by
+                               the precision, the function would need to
+                               access a wide character one past the end of the
+                               array."
+                            So if there is a precision, we must not use
+                            wcslen.  */
+                         /* This case has already been handled above.  */
+                         abort ();
+#  endif
+                       }
+                     else
+# endif
+                       {
+# if WIDE_CHAR_VERSION
+                         /* ISO C says about %s in fwprintf:
+                              "If the precision is not specified or is greater
+                               than the size of the converted array, the
+                               converted array shall contain a null wide
+                               character."
+                            So if there is a precision, we must not use
+                            strlen.  */
+                         /* This case has already been handled above.  */
+                         abort ();
+# else
+                         /* ISO C says about %s in fprintf:
+                              "If the precision is not specified or greater
+                               than the size of the array, the array shall
+                               contain a null character."
+                            So if there is a precision, we must not use
+                            strlen.  */
+                         const char *arg = a.arg[dp->arg_index].a.a_string;
+
+                         if (has_precision)
+                           tmp_length = local_strnlen (arg, precision);
+                         else
+                           tmp_length = strlen (arg);
+# endif
+                       }
+                     break;
+
+                   case 'p':
+                     tmp_length =
+                       (unsigned int) (sizeof (void *) * CHAR_BIT
+                                       * 0.25 /* binary -> hexadecimal */
+                                      )
+                         + 1 /* turn floor into ceil */
+                         + 2; /* account for leading 0x */
+                     break;
+
+                   default:
+                     abort ();
+                   }
+
+                 if (!pad_ourselves)
+                   {
+# if ENABLE_UNISTDIO
+                     /* Padding considers the number of characters, therefore
+                        the number of elements after padding may be
+                          > max (tmp_length, width)
+                        but is certainly
+                          <= tmp_length + width.  */
+                     tmp_length = xsum (tmp_length, width);
+# else
+                     /* Padding considers the number of elements,
+                        says POSIX.  */
+                     if (tmp_length < width)
+                       tmp_length = width;
+# endif
+                   }
+
+                 tmp_length = xsum (tmp_length, 1); /* account for trailing 
NUL */
+               }
+
+               if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
+                 tmp = tmpbuf;
+               else
+                 {
+                   size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
+
+                   if (size_overflow_p (tmp_memsize))
+                     /* Overflow, would lead to out of memory.  */
+                     goto out_of_memory;
+                   tmp = (TCHAR_T *) malloc (tmp_memsize);
+                   if (tmp == NULL)
+                     /* Out of memory.  */
+                     goto out_of_memory;
+                 }
+#endif
+
+               /* Construct the format string for calling snprintf or
+                  sprintf.  */
+               fbp = buf;
+               *fbp++ = '%';
+#if NEED_PRINTF_FLAG_GROUPING
+               /* The underlying implementation doesn't support the ' flag.
+                  Produce no grouping characters in this case; this is
+                  acceptable because the grouping is locale dependent.  */
+#else
+               if (flags & FLAG_GROUP)
+                 *fbp++ = '\'';
+#endif
+               if (flags & FLAG_LEFT)
+                 *fbp++ = '-';
+               if (flags & FLAG_SHOWSIGN)
+                 *fbp++ = '+';
+               if (flags & FLAG_SPACE)
+                 *fbp++ = ' ';
+               if (flags & FLAG_ALT)
+                 *fbp++ = '#';
+               if (!pad_ourselves)
+                 {
+                   if (flags & FLAG_ZERO)
+                     *fbp++ = '0';
+                   if (dp->width_start != dp->width_end)
+                     {
+                       size_t n = dp->width_end - dp->width_start;
+                       /* The width specification is known to consist only
+                          of standard ASCII characters.  */
+                       if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
+                         {
+                           memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
+                           fbp += n;
+                         }
+                       else
+                         {
+                           const FCHAR_T *mp = dp->width_start;
+                           do
+                             *fbp++ = (unsigned char) *mp++;
+                           while (--n > 0);
+                         }
+                     }
+                 }
+               if (!prec_ourselves)
+                 {
+                   if (dp->precision_start != dp->precision_end)
+                     {
+                       size_t n = dp->precision_end - dp->precision_start;
+                       /* The precision specification is known to consist only
+                          of standard ASCII characters.  */
+                       if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
+                         {
+                           memcpy (fbp, dp->precision_start, n * sizeof 
(TCHAR_T));
+                           fbp += n;
+                         }
+                       else
+                         {
+                           const FCHAR_T *mp = dp->precision_start;
+                           do
+                             *fbp++ = (unsigned char) *mp++;
+                           while (--n > 0);
+                         }
+                     }
+                 }
+
+               switch (type)
+                 {
+#if HAVE_LONG_LONG_INT
+                 case TYPE_LONGLONGINT:
+                 case TYPE_ULONGLONGINT:
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+                   *fbp++ = 'I';
+                   *fbp++ = '6';
+                   *fbp++ = '4';
+                   break;
+# else
+                   *fbp++ = 'l';
+                   /*FALLTHROUGH*/
+# endif
+#endif
+                 case TYPE_LONGINT:
+                 case TYPE_ULONGINT:
+#if HAVE_WINT_T
+                 case TYPE_WIDE_CHAR:
+#endif
+#if HAVE_WCHAR_T
+                 case TYPE_WIDE_STRING:
+#endif
+                   *fbp++ = 'l';
+                   break;
+                 case TYPE_LONGDOUBLE:
+                   *fbp++ = 'L';
+                   break;
+                 default:
+                   break;
+                 }
+#if NEED_PRINTF_DIRECTIVE_F
+               if (dp->conversion == 'F')
+                 *fbp = 'f';
+               else
+#endif
+                 *fbp = dp->conversion;
+#if USE_SNPRINTF
+# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined 
_WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
+               fbp[1] = '%';
+               fbp[2] = 'n';
+               fbp[3] = '\0';
+# else
+               /* On glibc2 systems from glibc >= 2.3 - probably also older
+                  ones - we know that snprintf's returns value conforms to
+                  ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
+                  Therefore we can avoid using %n in this situation.
+                  On glibc2 systems from 2004-10-18 or newer, the use of %n
+                  in format strings in writable memory may crash the program
+                  (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
+                  in this situation.  */
+               /* On native Win32 systems (such as mingw), we can avoid using
+                  %n because:
+                    - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
+                      snprintf does not write more than the specified number
+                      of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
+                      '4', '5', '6' into buf, not '4', '5', '\0'.)
+                    - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
+                      allows us to recognize the case of an insufficient
+                      buffer size: it returns -1 in this case.
+                  On native Win32 systems (such as mingw) where the OS is
+                  Windows Vista, the use of %n in format strings by default
+                  crashes the program. See
+                    <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
+                    
<http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
+                  So we should avoid %n in this situation.  */
+               fbp[1] = '\0';
+# endif
+#else
+               fbp[1] = '\0';
+#endif
+
+               /* Construct the arguments for calling snprintf or sprintf.  */
+               prefix_count = 0;
+               if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
+                 {
+                   if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                     abort ();
+                   prefixes[prefix_count++] = 
a.arg[dp->width_arg_index].a.a_int;
+                 }
+               if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
+                 {
+                   if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+                     abort ();
+                   prefixes[prefix_count++] = 
a.arg[dp->precision_arg_index].a.a_int;
+                 }
+
+#if USE_SNPRINTF
+               /* The SNPRINTF result is appended after result[0..length].
+                  The latter is an array of DCHAR_T; SNPRINTF appends an
+                  array of TCHAR_T to it.  This is possible because
+                  sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
+                  alignof (TCHAR_T) <= alignof (DCHAR_T).  */
+# define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
+               /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
+                  where an snprintf() with maxlen==1 acts like sprintf().  */
+               ENSURE_ALLOCATION (xsum (length,
+                                        (2 + TCHARS_PER_DCHAR - 1)
+                                        / TCHARS_PER_DCHAR));
+               /* Prepare checking whether snprintf returns the count
+                  via %n.  */
+               *(TCHAR_T *) (result + length) = '\0';
+#endif
+
+               for (;;)
+                 {
+                   int count = -1;
+
+#if USE_SNPRINTF
+                   int retcount = 0;
+                   size_t maxlen = allocated - length;
+                   /* SNPRINTF can fail if its second argument is
+                      > INT_MAX.  */
+                   if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
+                     maxlen = INT_MAX / TCHARS_PER_DCHAR;
+                   maxlen = maxlen * TCHARS_PER_DCHAR;
+# define SNPRINTF_BUF(arg) \
+                   switch (prefix_count)                                   \
+                     {                                                     \
+                     case 0:                                               \
+                       retcount = SNPRINTF ((TCHAR_T *) (result + length), \
+                                            maxlen, buf,                   \
+                                            arg, &count);                  \
+                       break;                                              \
+                     case 1:                                               \
+                       retcount = SNPRINTF ((TCHAR_T *) (result + length), \
+                                            maxlen, buf,                   \
+                                            prefixes[0], arg, &count);     \
+                       break;                                              \
+                     case 2:                                               \
+                       retcount = SNPRINTF ((TCHAR_T *) (result + length), \
+                                            maxlen, buf,                   \
+                                            prefixes[0], prefixes[1], arg, \
+                                            &count);                       \
+                       break;                                              \
+                     default:                                              \
+                       abort ();                                           \
+                     }
+#else
+# define SNPRINTF_BUF(arg) \
+                   switch (prefix_count)                                   \
+                     {                                                     \
+                     case 0:                                               \
+                       count = sprintf (tmp, buf, arg);                    \
+                       break;                                              \
+                     case 1:                                               \
+                       count = sprintf (tmp, buf, prefixes[0], arg);       \
+                       break;                                              \
+                     case 2:                                               \
+                       count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
+                                        arg);                              \
+                       break;                                              \
+                     default:                                              \
+                       abort ();                                           \
+                     }
+#endif
+
+                   switch (type)
+                     {
+                     case TYPE_SCHAR:
+                       {
+                         int arg = a.arg[dp->arg_index].a.a_schar;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_UCHAR:
+                       {
+                         unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_SHORT:
+                       {
+                         int arg = a.arg[dp->arg_index].a.a_short;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_USHORT:
+                       {
+                         unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_INT:
+                       {
+                         int arg = a.arg[dp->arg_index].a.a_int;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_UINT:
+                       {
+                         unsigned int arg = a.arg[dp->arg_index].a.a_uint;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_LONGINT:
+                       {
+                         long int arg = a.arg[dp->arg_index].a.a_longint;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_ULONGINT:
+                       {
+                         unsigned long int arg = 
a.arg[dp->arg_index].a.a_ulongint;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+#if HAVE_LONG_LONG_INT
+                     case TYPE_LONGLONGINT:
+                       {
+                         long long int arg = 
a.arg[dp->arg_index].a.a_longlongint;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_ULONGLONGINT:
+                       {
+                         unsigned long long int arg = 
a.arg[dp->arg_index].a.a_ulonglongint;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+#endif
+                     case TYPE_DOUBLE:
+                       {
+                         double arg = a.arg[dp->arg_index].a.a_double;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_LONGDOUBLE:
+                       {
+                         long double arg = a.arg[dp->arg_index].a.a_longdouble;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     case TYPE_CHAR:
+                       {
+                         int arg = a.arg[dp->arg_index].a.a_char;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+#if HAVE_WINT_T
+                     case TYPE_WIDE_CHAR:
+                       {
+                         wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+#endif
+                     case TYPE_STRING:
+                       {
+                         const char *arg = a.arg[dp->arg_index].a.a_string;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+#if HAVE_WCHAR_T
+                     case TYPE_WIDE_STRING:
+                       {
+                         const wchar_t *arg = 
a.arg[dp->arg_index].a.a_wide_string;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+#endif
+                     case TYPE_POINTER:
+                       {
+                         void *arg = a.arg[dp->arg_index].a.a_pointer;
+                         SNPRINTF_BUF (arg);
+                       }
+                       break;
+                     default:
+                       abort ();
+                     }
+
+#if USE_SNPRINTF
+                   /* Portability: Not all implementations of snprintf()
+                      are ISO C 99 compliant.  Determine the number of
+                      bytes that snprintf() has produced or would have
+                      produced.  */
+                   if (count >= 0)
+                     {
+                       /* Verify that snprintf() has NUL-terminated its
+                          result.  */
+                       if (count < maxlen
+                           && ((TCHAR_T *) (result + length)) [count] != '\0')
+                         abort ();
+                       /* Portability hack.  */
+                       if (retcount > count)
+                         count = retcount;
+                     }
+                   else
+                     {
+                       /* snprintf() doesn't understand the '%n'
+                          directive.  */
+                       if (fbp[1] != '\0')
+                         {
+                           /* Don't use the '%n' directive; instead, look
+                              at the snprintf() return value.  */
+                           fbp[1] = '\0';
+                           continue;
+                         }
+                       else
+                         {
+                           /* Look at the snprintf() return value.  */
+                           if (retcount < 0)
+                             {
+                               /* HP-UX 10.20 snprintf() is doubly deficient:
+                                  It doesn't understand the '%n' directive,
+                                  *and* it returns -1 (rather than the length
+                                  that would have been required) when the
+                                  buffer is too small.  */
+                               size_t bigger_need =
+                                 xsum (xtimes (allocated, 2), 12);
+                               ENSURE_ALLOCATION (bigger_need);
+                               continue;
+                             }
+                           else
+                             count = retcount;
+                         }
+                     }
+#endif
+
+                   /* Attempt to handle failure.  */
+                   if (count < 0)
+                     {
+                       if (!(result == resultbuf || result == NULL))
+                         free (result);
+                       if (buf_malloced != NULL)
+                         free (buf_malloced);
+                       CLEANUP ();
+                       errno = EINVAL;
+                       return NULL;
+                     }
+
+#if USE_SNPRINTF
+                   /* Handle overflow of the allocated buffer.
+                      If such an overflow occurs, a C99 compliant snprintf()
+                      returns a count >= maxlen.  However, a non-compliant
+                      snprintf() function returns only count = maxlen - 1.  To
+                      cover both cases, test whether count >= maxlen - 1.  */
+                   if ((unsigned int) count + 1 >= maxlen)
+                     {
+                       /* If maxlen already has attained its allowed maximum,
+                          allocating more memory will not increase maxlen.
+                          Instead of looping, bail out.  */
+                       if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
+                         goto overflow;
+                       else
+                         {
+                           /* Need at least (count + 1) * sizeof (TCHAR_T)
+                              bytes.  (The +1 is for the trailing NUL.)
+                              But ask for (count + 2) * sizeof (TCHAR_T)
+                              bytes, so that in the next round, we likely get
+                                maxlen > (unsigned int) count + 1
+                              and so we don't get here again.
+                              And allocate proportionally, to avoid looping
+                              eternally if snprintf() reports a too small
+                              count.  */
+                           size_t n =
+                             xmax (xsum (length,
+                                         ((unsigned int) count + 2
+                                          + TCHARS_PER_DCHAR - 1)
+                                         / TCHARS_PER_DCHAR),
+                                   xtimes (allocated, 2));
+
+                           ENSURE_ALLOCATION (n);
+                           continue;
+                         }
+                     }
+#endif
+
+#if NEED_PRINTF_UNBOUNDED_PRECISION
+                   if (prec_ourselves)
+                     {
+                       /* Handle the precision.  */
+                       TCHAR_T *prec_ptr =
+# if USE_SNPRINTF
+                         (TCHAR_T *) (result + length);
+# else
+                         tmp;
+# endif
+                       size_t prefix_count;
+                       size_t move;
+
+                       prefix_count = 0;
+                       /* Put the additional zeroes after the sign.  */
+                       if (count >= 1
+                           && (*prec_ptr == '-' || *prec_ptr == '+'
+                               || *prec_ptr == ' '))
+                         prefix_count = 1;
+                       /* Put the additional zeroes after the 0x prefix if
+                          (flags & FLAG_ALT) || (dp->conversion == 'p').  */
+                       else if (count >= 2
+                                && prec_ptr[0] == '0'
+                                && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
+                         prefix_count = 2;
+
+                       move = count - prefix_count;
+                       if (precision > move)
+                         {
+                           /* Insert zeroes.  */
+                           size_t insert = precision - move;
+                           TCHAR_T *prec_end;
+
+# if USE_SNPRINTF
+                           size_t n =
+                             xsum (length,
+                                   (count + insert + TCHARS_PER_DCHAR - 1)
+                                   / TCHARS_PER_DCHAR);
+                           length += (count + TCHARS_PER_DCHAR - 1) / 
TCHARS_PER_DCHAR;
+                           ENSURE_ALLOCATION (n);
+                           length -= (count + TCHARS_PER_DCHAR - 1) / 
TCHARS_PER_DCHAR;
+                           prec_ptr = (TCHAR_T *) (result + length);
+# endif
+
+                           prec_end = prec_ptr + count;
+                           prec_ptr += prefix_count;
+
+                           while (prec_end > prec_ptr)
+                             {
+                               prec_end--;
+                               prec_end[insert] = prec_end[0];
+                             }
+
+                           prec_end += insert;
+                           do
+                             *--prec_end = '0';
+                           while (prec_end > prec_ptr);
+
+                           count += insert;
+                         }
+                     }
+#endif
+
+#if !USE_SNPRINTF
+                   if (count >= tmp_length)
+                     /* tmp_length was incorrectly calculated - fix the
+                        code above!  */
+                     abort ();
+#endif
+
+#if !DCHAR_IS_TCHAR
+                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
+                   if (dp->conversion == 'c' || dp->conversion == 's')
+                     {
+                       /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
+                          TYPE_WIDE_STRING.
+                          The result string is not certainly ASCII.  */
+                       const TCHAR_T *tmpsrc;
+                       DCHAR_T *tmpdst;
+                       size_t tmpdst_len;
+                       /* This code assumes that TCHAR_T is 'char'.  */
+                       typedef int TCHAR_T_verify
+                                   [2 * (sizeof (TCHAR_T) == 1) - 1];
+# if USE_SNPRINTF
+                       tmpsrc = (TCHAR_T *) (result + length);
+# else
+                       tmpsrc = tmp;
+# endif
+                       tmpdst =
+                         DCHAR_CONV_FROM_ENCODING (locale_charset (),
+                                                   iconveh_question_mark,
+                                                   tmpsrc, count,
+                                                   NULL,
+                                                   NULL, &tmpdst_len);
+                       if (tmpdst == NULL)
+                         {
+                           int saved_errno = errno;
+                           if (!(result == resultbuf || result == NULL))
+                             free (result);
+                           if (buf_malloced != NULL)
+                             free (buf_malloced);
+                           CLEANUP ();
+                           errno = saved_errno;
+                           return NULL;
+                         }
+                       ENSURE_ALLOCATION (xsum (length, tmpdst_len));
+                       DCHAR_CPY (result + length, tmpdst, tmpdst_len);
+                       free (tmpdst);
+                       count = tmpdst_len;
+                     }
+                   else
+                     {
+                       /* The result string is ASCII.
+                          Simple 1:1 conversion.  */
+# if USE_SNPRINTF
+                       /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
+                          no-op conversion, in-place on the array starting
+                          at (result + length).  */
+                       if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
+# endif
+                         {
+                           const TCHAR_T *tmpsrc;
+                           DCHAR_T *tmpdst;
+                           size_t n;
+
+# if USE_SNPRINTF
+                           if (result == resultbuf)
+                             {
+                               tmpsrc = (TCHAR_T *) (result + length);
+                               /* ENSURE_ALLOCATION will not move tmpsrc
+                                  (because it's part of resultbuf).  */
+                               ENSURE_ALLOCATION (xsum (length, count));
+                             }
+                           else
+                             {
+                               /* ENSURE_ALLOCATION will move the array
+                                  (because it uses realloc().  */
+                               ENSURE_ALLOCATION (xsum (length, count));
+                               tmpsrc = (TCHAR_T *) (result + length);
+                             }
+# else
+                           tmpsrc = tmp;
+                           ENSURE_ALLOCATION (xsum (length, count));
+# endif
+                           tmpdst = result + length;
+                           /* Copy backwards, because of overlapping.  */
+                           tmpsrc += count;
+                           tmpdst += count;
+                           for (n = count; n > 0; n--)
+                             *--tmpdst = (unsigned char) *--tmpsrc;
+                         }
+                     }
+#endif
+
+#if DCHAR_IS_TCHAR && !USE_SNPRINTF
+                   /* Make room for the result.  */
+                   if (count > allocated - length)
+                     {
+                       /* Need at least count elements.  But allocate
+                          proportionally.  */
+                       size_t n =
+                         xmax (xsum (length, count), xtimes (allocated, 2));
+
+                       ENSURE_ALLOCATION (n);
+                     }
+#endif
+
+                   /* Here count <= allocated - length.  */
+
+                   /* Perform padding.  */
+#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || 
NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+                   if (pad_ourselves && has_width)
+                     {
+                       size_t w;
+# if ENABLE_UNISTDIO
+                       /* Outside POSIX, it's preferrable to compare the width
+                          against the number of _characters_ of the converted
+                          value.  */
+                       w = DCHAR_MBSNLEN (result + length, count);
+# else
+                       /* The width is compared against the number of _bytes_
+                          of the converted value, says POSIX.  */
+                       w = count;
+# endif
+                       if (w < width)
+                         {
+                           size_t pad = width - w;
+
+                           /* Make room for the result.  */
+                           if (xsum (count, pad) > allocated - length)
+                             {
+                               /* Need at least count + pad elements.  But
+                                  allocate proportionally.  */
+                               size_t n =
+                                 xmax (xsum3 (length, count, pad),
+                                       xtimes (allocated, 2));
+
+# if USE_SNPRINTF
+                               length += count;
+                               ENSURE_ALLOCATION (n);
+                               length -= count;
+# else
+                               ENSURE_ALLOCATION (n);
+# endif
+                             }
+                           /* Here count + pad <= allocated - length.  */
+
+                           {
+# if !DCHAR_IS_TCHAR || USE_SNPRINTF
+                             DCHAR_T * const rp = result + length;
+# else
+                             DCHAR_T * const rp = tmp;
+# endif
+                             DCHAR_T *p = rp + count;
+                             DCHAR_T *end = p + pad;
+                             DCHAR_T *pad_ptr;
+# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
+                             if (dp->conversion == 'c'
+                                 || dp->conversion == 's')
+                               /* No zero-padding for string directives.  */
+                               pad_ptr = NULL;
+                             else
+# endif
+                               {
+                                 pad_ptr = (*rp == '-' ? rp + 1 : rp);
+                                 /* No zero-padding of "inf" and "nan".  */
+                                 if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
+                                     || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
+                                   pad_ptr = NULL;
+                               }
+                             /* The generated string now extends from rp to p,
+                                with the zero padding insertion point being at
+                                pad_ptr.  */
+
+                             count = count + pad; /* = end - rp */
+
+                             if (flags & FLAG_LEFT)
+                               {
+                                 /* Pad with spaces on the right.  */
+                                 for (; pad > 0; pad--)
+                                   *p++ = ' ';
+                               }
+                             else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
+                               {
+                                 /* Pad with zeroes.  */
+                                 DCHAR_T *q = end;
+
+                                 while (p > pad_ptr)
+                                   *--q = *--p;
+                                 for (; pad > 0; pad--)
+                                   *p++ = '0';
+                               }
+                             else
+                               {
+                                 /* Pad with spaces on the left.  */
+                                 DCHAR_T *q = end;
+
+                                 while (p > rp)
+                                   *--q = *--p;
+                                 for (; pad > 0; pad--)
+                                   *p++ = ' ';
+                               }
+                           }
+                         }
+                     }
+#endif
+
+                   /* Here still count <= allocated - length.  */
+
+#if !DCHAR_IS_TCHAR || USE_SNPRINTF
+                   /* The snprintf() result did fit.  */
+#else
+                   /* Append the sprintf() result.  */
+                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
+#endif
+#if !USE_SNPRINTF
+                   if (tmp != tmpbuf)
+                     free (tmp);
+#endif
+
+#if NEED_PRINTF_DIRECTIVE_F
+                   if (dp->conversion == 'F')
+                     {
+                       /* Convert the %f result to upper case for %F.  */
+                       DCHAR_T *rp = result + length;
+                       size_t rc;
+                       for (rc = count; rc > 0; rc--, rp++)
+                         if (*rp >= 'a' && *rp <= 'z')
+                           *rp = *rp - 'a' + 'A';
+                     }
+#endif
+
+                   length += count;
+                   break;
+                 }
+             }
+         }
+      }
+
+    /* Add the final NUL.  */
+    ENSURE_ALLOCATION (xsum (length, 1));
+    result[length] = '\0';
+
+    if (result != resultbuf && length + 1 < allocated)
+      {
+       /* Shrink the allocated memory if possible.  */
+       DCHAR_T *memory;
+
+       memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
+       if (memory != NULL)
+         result = memory;
+      }
+
+    if (buf_malloced != NULL)
+      free (buf_malloced);
+    CLEANUP ();
+    *lengthp = length;
+    /* Note that we can produce a big string of a length > INT_MAX.  POSIX
+       says that snprintf() fails with errno = EOVERFLOW in this case, but
+       that's only because snprintf() returns an 'int'.  This function does
+       not have this limitation.  */
+    return result;
+
+#if USE_SNPRINTF
+  overflow:
+    if (!(result == resultbuf || result == NULL))
+      free (result);
+    if (buf_malloced != NULL)
+      free (buf_malloced);
+    CLEANUP ();
+    errno = EOVERFLOW;
+    return NULL;
+#endif
+
+  out_of_memory:
+    if (!(result == resultbuf || result == NULL))
+      free (result);
+    if (buf_malloced != NULL)
+      free (buf_malloced);
+  out_of_memory_1:
+    CLEANUP ();
+    errno = ENOMEM;
+    return NULL;
+  }
+}
+
+#undef TCHARS_PER_DCHAR
+#undef SNPRINTF
+#undef USE_SNPRINTF
+#undef DCHAR_CPY
+#undef PRINTF_PARSE
+#undef DIRECTIVES
+#undef DIRECTIVE
+#undef DCHAR_IS_TCHAR
+#undef TCHAR_T
+#undef DCHAR_T
+#undef FCHAR_T
+#undef VASNPRINTF
diff --git a/lib/vasnprintf.h b/lib/vasnprintf.h
new file mode 100644
index 0000000..5ceab44
--- /dev/null
+++ b/lib/vasnprintf.h
@@ -0,0 +1,81 @@
+/* vsprintf with automatic memory allocation.
+   Copyright (C) 2002-2004, 2007-2008 Free Software Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _VASNPRINTF_H
+#define _VASNPRINTF_H
+
+/* Get va_list.  */
+#include <stdarg.h>
+
+/* Get size_t.  */
+#include <stddef.h>
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+#  define __attribute__(Spec) /* empty */
+# endif
+/* The __-protected variants of `format' and `printf' attributes
+   are accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+#  define __format__ format
+#  define __printf__ printf
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Write formatted output to a string dynamically allocated with malloc().
+   You can pass a preallocated buffer for the result in RESULTBUF and its
+   size in *LENGTHP; otherwise you pass RESULTBUF = NULL.
+   If successful, return the address of the string (this may be = RESULTBUF
+   if no dynamic memory allocation was necessary) and set *LENGTHP to the
+   number of resulting bytes, excluding the trailing NUL.  Upon error, set
+   errno and return NULL.
+
+   When dynamic memory allocation occurs, the preallocated buffer is left
+   alone (with possibly modified contents).  This makes it possible to use
+   a statically allocated or stack-allocated buffer, like this:
+
+          char buf[100];
+          size_t len = sizeof (buf);
+          char *output = vasnprintf (buf, &len, format, args);
+          if (output == NULL)
+            ... error handling ...;
+          else
+            {
+              ... use the output string ...;
+              if (output != buf)
+                free (output);
+            }
+  */
+#if REPLACE_VASNPRINTF
+# define asnprintf rpl_asnprintf
+# define vasnprintf rpl_vasnprintf
+#endif
+extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, 
...)
+       __attribute__ ((__format__ (__printf__, 3, 4)));
+extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char 
*format, va_list args)
+       __attribute__ ((__format__ (__printf__, 3, 0)));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VASNPRINTF_H */
diff --git a/lib/vsnprintf.c b/lib/vsnprintf.c
new file mode 100644
index 0000000..1fdfb6b
--- /dev/null
+++ b/lib/vsnprintf.c
@@ -0,0 +1,71 @@
+/* Formatted output to strings.
+   Copyright (C) 2004, 2006-2008 Free Software Foundation, Inc.
+   Written by Simon Josefsson and Yoann Vandoorselaere <address@hidden>.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification.  */
+#include <stdio.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "vasnprintf.h"
+
+/* Print formatted output to string STR.  Similar to vsprintf, but
+   additional length SIZE limit how much is written into STR.  Returns
+   string length of formatted string (which may be larger than SIZE).
+   STR may be NULL, in which case nothing will be written.  On error,
+   return a negative value.  */
+int
+vsnprintf (char *str, size_t size, const char *format, va_list args)
+{
+  char *output;
+  size_t len;
+  size_t lenbuf = size;
+
+  output = vasnprintf (str, &lenbuf, format, args);
+  len = lenbuf;
+
+  if (!output)
+    return -1;
+
+  if (output != str)
+    {
+      if (size)
+       {
+         size_t pruned_len = (len < size ? len : size - 1);
+         memcpy (str, output, pruned_len);
+         str[pruned_len] = '\0';
+       }
+
+      free (output);
+    }
+
+  if (len > INT_MAX)
+    {
+      errno = EOVERFLOW;
+      return -1;
+    }
+
+  return len;
+}
diff --git a/lib/xsize.h b/lib/xsize.h
new file mode 100644
index 0000000..0b30045
--- /dev/null
+++ b/lib/xsize.h
@@ -0,0 +1,108 @@
+/* xsize.h -- Checked size_t computations.
+
+   Copyright (C) 2003, 2008 Free Software Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _XSIZE_H
+#define _XSIZE_H
+
+/* Get size_t.  */
+#include <stddef.h>
+
+/* Get SIZE_MAX.  */
+#include <limits.h>
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+/* The size of memory objects is often computed through expressions of
+   type size_t. Example:
+      void* p = malloc (header_size + n * element_size).
+   These computations can lead to overflow.  When this happens, malloc()
+   returns a piece of memory that is way too small, and the program then
+   crashes while attempting to fill the memory.
+   To avoid this, the functions and macros in this file check for overflow.
+   The convention is that SIZE_MAX represents overflow.
+   malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc
+   implementation that uses mmap --, it's recommended to use size_overflow_p()
+   or size_in_bounds_p() before invoking malloc().
+   The example thus becomes:
+      size_t size = xsum (header_size, xtimes (n, element_size));
+      void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
+*/
+
+/* Convert an arbitrary value >= 0 to type size_t.  */
+#define xcast_size_t(N) \
+  ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)
+
+/* Sum of two sizes, with overflow check.  */
+static inline size_t
+#if __GNUC__ >= 3
+__attribute__ ((__pure__))
+#endif
+xsum (size_t size1, size_t size2)
+{
+  size_t sum = size1 + size2;
+  return (sum >= size1 ? sum : SIZE_MAX);
+}
+
+/* Sum of three sizes, with overflow check.  */
+static inline size_t
+#if __GNUC__ >= 3
+__attribute__ ((__pure__))
+#endif
+xsum3 (size_t size1, size_t size2, size_t size3)
+{
+  return xsum (xsum (size1, size2), size3);
+}
+
+/* Sum of four sizes, with overflow check.  */
+static inline size_t
+#if __GNUC__ >= 3
+__attribute__ ((__pure__))
+#endif
+xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
+{
+  return xsum (xsum (xsum (size1, size2), size3), size4);
+}
+
+/* Maximum of two sizes, with overflow check.  */
+static inline size_t
+#if __GNUC__ >= 3
+__attribute__ ((__pure__))
+#endif
+xmax (size_t size1, size_t size2)
+{
+  /* No explicit check is needed here, because for any n:
+     max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX.  */
+  return (size1 >= size2 ? size1 : size2);
+}
+
+/* Multiplication of a count with an element size, with overflow check.
+   The count must be >= 0 and the element size must be > 0.
+   This is a macro, not an inline function, so that it works correctly even
+   when N is of a wider type and N > SIZE_MAX.  */
+#define xtimes(N, ELSIZE) \
+  ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)
+
+/* Check for overflow.  */
+#define size_overflow_p(SIZE) \
+  ((SIZE) == SIZE_MAX)
+/* Check against overflow.  */
+#define size_in_bounds_p(SIZE) \
+  ((SIZE) != SIZE_MAX)
+
+#endif /* _XSIZE_H */
diff --git a/m4/errno_h.m4 b/m4/errno_h.m4
new file mode 100644
index 0000000..4ce1ccb
--- /dev/null
+++ b/m4/errno_h.m4
@@ -0,0 +1,115 @@
+# errno_h.m4 serial 6
+dnl Copyright (C) 2004, 2006, 2008, 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN_ONCE([gl_HEADER_ERRNO_H],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_CACHE_CHECK([for complete errno.h], [gl_cv_header_errno_h_complete], [
+    AC_EGREP_CPP([booboo],[
+#include <errno.h>
+#if !defined ENOMSG
+booboo
+#endif
+#if !defined EIDRM
+booboo
+#endif
+#if !defined ENOLINK
+booboo
+#endif
+#if !defined EPROTO
+booboo
+#endif
+#if !defined EMULTIHOP
+booboo
+#endif
+#if !defined EBADMSG
+booboo
+#endif
+#if !defined EOVERFLOW
+booboo
+#endif
+#if !defined ENOTSUP
+booboo
+#endif
+#if !defined ESTALE
+booboo
+#endif
+#if !defined ECANCELED
+booboo
+#endif
+      ],
+      [gl_cv_header_errno_h_complete=no],
+      [gl_cv_header_errno_h_complete=yes])
+  ])
+  if test $gl_cv_header_errno_h_complete = yes; then
+    ERRNO_H=''
+  else
+    gl_CHECK_NEXT_HEADERS([errno.h])
+    ERRNO_H='errno.h'
+  fi
+  AC_SUBST([ERRNO_H])
+  gl_REPLACE_ERRNO_VALUE([EMULTIHOP])
+  gl_REPLACE_ERRNO_VALUE([ENOLINK])
+  gl_REPLACE_ERRNO_VALUE([EOVERFLOW])
+])
+
+# Assuming $1 = EOVERFLOW.
+# The EOVERFLOW errno value ought to be defined in <errno.h>, according to
+# POSIX.  But some systems (like OpenBSD 4.0 or AIX 3) don't define it, and
+# some systems (like OSF/1) define it when _XOPEN_SOURCE_EXTENDED is defined.
+# Check for the value of EOVERFLOW.
+# Set the variables EOVERFLOW_HIDDEN and EOVERFLOW_VALUE.
+AC_DEFUN([gl_REPLACE_ERRNO_VALUE],
+[
+  if test -n "$ERRNO_H"; then
+    AC_CACHE_CHECK([for ]$1[ value], [gl_cv_header_errno_h_]$1, [
+      AC_EGREP_CPP([yes],[
+#include <errno.h>
+#ifdef ]$1[
+yes
+#endif
+      ],
+      [gl_cv_header_errno_h_]$1[=yes],
+      [gl_cv_header_errno_h_]$1[=no])
+      if test $gl_cv_header_errno_h_]$1[ = no; then
+        AC_EGREP_CPP([yes],[
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <errno.h>
+#ifdef ]$1[
+yes
+#endif
+          ], [gl_cv_header_errno_h_]$1[=hidden])
+        if test $gl_cv_header_errno_h_]$1[ = hidden; then
+          dnl The macro exists but is hidden.
+          dnl Define it to the same value.
+          AC_COMPUTE_INT([gl_cv_header_errno_h_]$1, $1, [
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <errno.h>
+/* The following two lines are a workaround against an autoconf-2.52 bug.  */
+#include <stdio.h>
+#include <stdlib.h>
+])
+        fi
+      fi
+    ])
+    case $gl_cv_header_errno_h_]$1[ in
+      yes | no)
+        ]$1[_HIDDEN=0; ]$1[_VALUE=
+        ;;
+      *)
+        ]$1[_HIDDEN=1; ]$1[_VALUE="$gl_cv_header_errno_h_]$1["
+        ;;
+    esac
+    AC_SUBST($1[_HIDDEN])
+    AC_SUBST($1[_VALUE])
+  fi
+])
+
+dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in.
+dnl Remove this when we can assume autoconf >= 2.61.
+m4_ifdef([AC_COMPUTE_INT], [], [
+  AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])])
+])
diff --git a/m4/float_h.m4 b/m4/float_h.m4
new file mode 100644
index 0000000..d36e3a4
--- /dev/null
+++ b/m4/float_h.m4
@@ -0,0 +1,19 @@
+# float_h.m4 serial 3
+dnl Copyright (C) 2007 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FLOAT_H],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  FLOAT_H=
+  case "$host_os" in
+    beos* | openbsd*)
+      FLOAT_H=float.h
+      gl_CHECK_NEXT_HEADERS([float.h])
+      ;;
+  esac
+  AC_SUBST([FLOAT_H])
+])
diff --git a/m4/getpagesize.m4 b/m4/getpagesize.m4
new file mode 100644
index 0000000..0d07a3a
--- /dev/null
+++ b/m4/getpagesize.m4
@@ -0,0 +1,29 @@
+# getpagesize.m4 serial 7
+dnl Copyright (C) 2002, 2004-2005, 2007 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_GETPAGESIZE],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_CHECK_FUNCS([getpagesize])
+  if test $ac_cv_func_getpagesize = no; then
+    HAVE_GETPAGESIZE=0
+    AC_CHECK_HEADERS([OS.h])
+    if test $ac_cv_header_OS_h = yes; then
+      HAVE_OS_H=1
+    fi
+    AC_CHECK_HEADERS([sys/param.h])
+    if test $ac_cv_header_sys_param_h = yes; then
+      HAVE_SYS_PARAM_H=1
+    fi
+  fi
+  case "$host_os" in
+    mingw*)
+      REPLACE_GETPAGESIZE=1
+      AC_LIBOBJ([getpagesize])
+      ;;
+  esac
+])
diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4
index e70283f..aad4999 100644
--- a/m4/gnulib-cache.m4
+++ b/m4/gnulib-cache.m4
@@ -15,7 +15,7 @@
 
 
 # Specification in the form of a command-line invocation:
-#   gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 
--doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool 
--macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap canonicalize-lgpl 
count-one-bits environ extensions flock fpieee full-read full-write havelib 
iconv_open-utf lib-symbol-visibility libunistring putenv stdlib strcase 
strftime striconveh string
+#   gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 
--doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool 
--macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap canonicalize-lgpl 
count-one-bits environ extensions flock fpieee full-read full-write havelib 
iconv_open-utf lib-symbol-visibility libunistring putenv stdlib strcase 
strftime striconveh string vsnprintf
 
 # Specification in the form of a few gnulib-tool.m4 macro invocations:
 gl_LOCAL_DIR([])
@@ -41,6 +41,7 @@ gl_MODULES([
   strftime
   striconveh
   string
+  vsnprintf
 ])
 gl_AVOID([])
 gl_SOURCE_BASE([lib])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index ef0534e..0c2b968 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -51,8 +51,12 @@ AC_DEFUN([gl_INIT],
   gl_COUNT_ONE_BITS
   gl_ENVIRON
   gl_UNISTD_MODULE_INDICATOR([environ])
+  gl_HEADER_ERRNO_H
+  gl_FLOAT_H
   gl_FUNC_FLOCK
   gl_HEADER_SYS_FILE_MODULE_INDICATOR([flock])
+  gl_FUNC_GETPAGESIZE
+  gl_UNISTD_MODULE_INDICATOR([getpagesize])
   AM_ICONV
   gl_ICONV_H
   gl_FUNC_ICONV_OPEN
@@ -72,6 +76,8 @@ AC_DEFUN([gl_INIT],
   gl_WCHAR_MODULE_INDICATOR([mbrtowc])
   gl_FUNC_MBSINIT
   gl_WCHAR_MODULE_INDICATOR([mbsinit])
+  gl_FUNC_MEMCHR
+  gl_STRING_MODULE_INDICATOR([memchr])
   gl_MULTIARCH
   gl_PATHMAX
   gl_FUNC_PUTENV
@@ -80,9 +86,11 @@ AC_DEFUN([gl_INIT],
   gl_UNISTD_MODULE_INDICATOR([readlink])
   gl_SAFE_READ
   gl_SAFE_WRITE
+  gl_SIZE_MAX
   gt_TYPE_SSIZE_T
   AM_STDBOOL_H
   gl_STDINT_H
+  gl_STDIO_H
   gl_STDLIB_H
   gl_STRCASE
   gl_FUNC_GNU_STRFTIME
@@ -101,9 +109,13 @@ AC_DEFUN([gl_INIT],
   gl_MODULE_INDICATOR([unistr/u8-mbtouc-unsafe])
   gl_MODULE_INDICATOR([unistr/u8-mbtoucr])
   gl_MODULE_INDICATOR([unistr/u8-uctomb])
+  gl_FUNC_VASNPRINTF
+  gl_FUNC_VSNPRINTF
+  gl_STDIO_MODULE_INDICATOR([vsnprintf])
   gl_WCHAR_H
   gl_FUNC_WRITE
   gl_UNISTD_MODULE_INDICATOR([write])
+  gl_XSIZE
   m4_ifval(gl_LIBSOURCES_LIST, [
     m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ ||
       for gl_file in ]gl_LIBSOURCES_LIST[ ; do
@@ -235,6 +247,7 @@ AC_DEFUN([gl_FILE_LIST], [
   build-aux/config.rpath
   build-aux/link-warning.h
   lib/alloca.in.h
+  lib/asnprintf.c
   lib/byteswap.in.h
   lib/c-ctype.c
   lib/c-ctype.h
@@ -246,11 +259,15 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/canonicalize.h
   lib/config.charset
   lib/count-one-bits.h
+  lib/errno.in.h
+  lib/float+.h
+  lib/float.in.h
   lib/flock.c
   lib/full-read.c
   lib/full-read.h
   lib/full-write.c
   lib/full-write.h
+  lib/getpagesize.c
   lib/iconv.c
   lib/iconv.in.h
   lib/iconv_close.c
@@ -269,7 +286,13 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/mbrlen.c
   lib/mbrtowc.c
   lib/mbsinit.c
+  lib/memchr.c
+  lib/memchr.valgrind
   lib/pathmax.h
+  lib/printf-args.c
+  lib/printf-args.h
+  lib/printf-parse.c
+  lib/printf-parse.h
   lib/putenv.c
   lib/readlink.c
   lib/ref-add.sin
@@ -278,8 +301,11 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/safe-read.h
   lib/safe-write.c
   lib/safe-write.h
+  lib/size_max.h
   lib/stdbool.in.h
   lib/stdint.in.h
+  lib/stdio-write.c
+  lib/stdio.in.h
   lib/stdlib.in.h
   lib/strcasecmp.c
   lib/streq.h
@@ -304,9 +330,13 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/unistr/u8-uctomb-aux.c
   lib/unistr/u8-uctomb.c
   lib/unitypes.h
+  lib/vasnprintf.c
+  lib/vasnprintf.h
   lib/verify.h
+  lib/vsnprintf.c
   lib/wchar.in.h
   lib/write.c
+  lib/xsize.h
   m4/00gnulib.m4
   m4/alloca.m4
   m4/autobuild.m4
@@ -316,9 +346,12 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/count-one-bits.m4
   m4/eealloc.m4
   m4/environ.m4
+  m4/errno_h.m4
   m4/extensions.m4
+  m4/float_h.m4
   m4/flock.m4
   m4/fpieee.m4
+  m4/getpagesize.m4
   m4/glibc21.m4
   m4/gnulib-common.m4
   m4/iconv.m4
@@ -326,6 +359,8 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/iconv_open.m4
   m4/include_next.m4
   m4/inline.m4
+  m4/intmax_t.m4
+  m4/inttypes_h.m4
   m4/lib-ld.m4
   m4/lib-link.m4
   m4/lib-prefix.m4
@@ -341,15 +376,21 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/mbrtowc.m4
   m4/mbsinit.m4
   m4/mbstate_t.m4
+  m4/memchr.m4
+  m4/mmap-anon.m4
   m4/multiarch.m4
   m4/pathmax.m4
+  m4/printf.m4
   m4/putenv.m4
   m4/readlink.m4
   m4/safe-read.m4
   m4/safe-write.m4
+  m4/size_max.m4
   m4/ssize_t.m4
   m4/stdbool.m4
   m4/stdint.m4
+  m4/stdint_h.m4
+  m4/stdio_h.m4
   m4/stdlib_h.m4
   m4/strcase.m4
   m4/strftime.m4
@@ -360,8 +401,12 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/time_r.m4
   m4/tm_gmtoff.m4
   m4/unistd_h.m4
+  m4/vasnprintf.m4
   m4/visibility.m4
+  m4/vsnprintf.m4
   m4/wchar.m4
+  m4/wchar_t.m4
   m4/wint_t.m4
   m4/write.m4
+  m4/xsize.m4
 ])
diff --git a/m4/intmax_t.m4 b/m4/intmax_t.m4
new file mode 100644
index 0000000..264cb57
--- /dev/null
+++ b/m4/intmax_t.m4
@@ -0,0 +1,61 @@
+# intmax_t.m4 serial 7
+dnl Copyright (C) 1997-2004, 2006-2007, 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+AC_PREREQ([2.13])
+
+# Define intmax_t to 'long' or 'long long'
+# if it is not already defined in <stdint.h> or <inttypes.h>.
+
+AC_DEFUN([gl_AC_TYPE_INTMAX_T],
+[
+  dnl For simplicity, we assume that a header file defines 'intmax_t' if and
+  dnl only if it defines 'uintmax_t'.
+  AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+  AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+  if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; 
then
+    AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+    test $ac_cv_type_long_long_int = yes \
+      && ac_type='long long' \
+      || ac_type='long'
+    AC_DEFINE_UNQUOTED([intmax_t], [$ac_type],
+     [Define to long or long long if <inttypes.h> and <stdint.h> don't 
define.])
+  else
+    AC_DEFINE([HAVE_INTMAX_T], [1],
+      [Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>.])
+  fi
+])
+
+dnl An alternative would be to explicitly test for 'intmax_t'.
+
+AC_DEFUN([gt_AC_TYPE_INTMAX_T],
+[
+  AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+  AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+  AC_CACHE_CHECK([for intmax_t], [gt_cv_c_intmax_t],
+    [AC_TRY_COMPILE([
+#include <stddef.h>
+#include <stdlib.h>
+#if HAVE_STDINT_H_WITH_UINTMAX
+#include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H_WITH_UINTMAX
+#include <inttypes.h>
+#endif
+], [intmax_t x = -1; return !x;], gt_cv_c_intmax_t=yes, gt_cv_c_intmax_t=no)])
+  if test $gt_cv_c_intmax_t = yes; then
+    AC_DEFINE([HAVE_INTMAX_T], [1],
+      [Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>.])
+  else
+    AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+    test $ac_cv_type_long_long_int = yes \
+      && ac_type='long long' \
+      || ac_type='long'
+    AC_DEFINE_UNQUOTED([intmax_t], [$ac_type],
+     [Define to long or long long if <stdint.h> and <inttypes.h> don't 
define.])
+  fi
+])
diff --git a/m4/inttypes_h.m4 b/m4/inttypes_h.m4
new file mode 100644
index 0000000..f4ca160
--- /dev/null
+++ b/m4/inttypes_h.m4
@@ -0,0 +1,26 @@
+# inttypes_h.m4 serial 9
+dnl Copyright (C) 1997-2004, 2006, 2008, 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_INTTYPES_H_WITH_UINTMAX if <inttypes.h> exists,
+# doesn't clash with <sys/types.h>, and declares uintmax_t.
+
+AC_DEFUN([gl_AC_HEADER_INTTYPES_H],
+[
+  AC_CACHE_CHECK([for inttypes.h], [gl_cv_header_inttypes_h],
+  [AC_TRY_COMPILE(
+    [#include <sys/types.h>
+#include <inttypes.h>],
+    [uintmax_t i = (uintmax_t) -1; return !i;],
+    [gl_cv_header_inttypes_h=yes],
+    [gl_cv_header_inttypes_h=no])])
+  if test $gl_cv_header_inttypes_h = yes; then
+    AC_DEFINE_UNQUOTED([HAVE_INTTYPES_H_WITH_UINTMAX], [1],
+      [Define if <inttypes.h> exists, doesn't clash with <sys/types.h>,
+       and declares uintmax_t. ])
+  fi
+])
diff --git a/m4/lib-link.m4 b/m4/lib-link.m4
index 2144203..2f8b7ff 100644
--- a/m4/lib-link.m4
+++ b/m4/lib-link.m4
@@ -1,4 +1,4 @@
-# lib-link.m4 serial 19 (gettext-0.18)
+# lib-link.m4 serial 20 (gettext-0.18)
 dnl Copyright (C) 2001-2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -82,7 +82,7 @@ AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
   ])
   if test "$ac_cv_lib[]Name" = yes; then
     HAVE_LIB[]NAME=yes
-    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib[]$1 library.])
+    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
     AC_MSG_CHECKING([how to link with lib[]$1])
     AC_MSG_RESULT([$LIB[]NAME])
   else
@@ -210,6 +210,9 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
   LTLIB[]NAME=
   INC[]NAME=
   LIB[]NAME[]_PREFIX=
+  dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
+  dnl computed. So it has to be reset here.
+  HAVE_LIB[]NAME=
   rpathdirs=
   ltrpathdirs=
   names_already_handled=
diff --git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4
index 11d7d23..2fddcc8 100644
--- a/m4/mbrtowc.m4
+++ b/m4/mbrtowc.m4
@@ -1,4 +1,4 @@
-# mbrtowc.m4 serial 15
+# mbrtowc.m4 serial 16
 dnl Copyright (C) 2001-2002, 2004-2005, 2008, 2009 Free Software Foundation, 
Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -156,6 +156,7 @@ changequote([,])dnl
       if test $LOCALE_ZH_CN != none; then
         AC_TRY_RUN([
 #include <locale.h>
+#include <stdlib.h>
 #include <string.h>
 #include <wchar.h>
 int main ()
diff --git a/m4/memchr.m4 b/m4/memchr.m4
new file mode 100644
index 0000000..1194bac
--- /dev/null
+++ b/m4/memchr.m4
@@ -0,0 +1,86 @@
+# memchr.m4 serial 7
+dnl Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN_ONCE([gl_FUNC_MEMCHR],
+[
+  dnl Check for prerequisites for memory fence checks.
+  gl_FUNC_MMAP_ANON
+  AC_CHECK_HEADERS_ONCE([sys/mman.h])
+  AC_CHECK_FUNCS_ONCE([mprotect])
+
+  dnl These days, we assume memchr is present.  But just in case...
+  AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+  AC_REPLACE_FUNCS([memchr])
+  if test $ac_cv_func_memchr = no; then
+    gl_PREREQ_MEMCHR
+    REPLACE_MEMCHR=1
+  fi
+
+  if test $ac_cv_func_memchr = yes; then
+    # Detect platform-specific bugs in some versions of glibc:
+    # memchr should not dereference anything with length 0
+    #   http://bugzilla.redhat.com/499689
+    # memchr should not dereference overestimated length after a match
+    #   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737
+    #   http://sourceware.org/bugzilla/show_bug.cgi?id=10162
+    # Assume that memchr works on platforms that lack mprotect.
+    AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works],
+      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <string.h>
+#if HAVE_SYS_MMAN_H
+# include <fcntl.h>
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/mman.h>
+# ifndef MAP_FILE
+#  define MAP_FILE 0
+# endif
+#endif
+]], [[
+  char *fence = NULL;
+#if HAVE_SYS_MMAN_H && HAVE_MPROTECT
+# if HAVE_MAP_ANONYMOUS
+  const int flags = MAP_ANONYMOUS | MAP_PRIVATE;
+  const int fd = -1;
+# else /* !HAVE_MAP_ANONYMOUS */
+  const int flags = MAP_FILE | MAP_PRIVATE;
+  int fd = open ("/dev/zero", O_RDONLY, 0666);
+  if (fd >= 0)
+# endif
+    {
+      int pagesize = getpagesize ();
+      char *two_pages =
+       (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE,
+                      flags, fd, 0);
+      if (two_pages != (char *)(-1)
+         && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0)
+       fence = two_pages + pagesize;
+    }
+#endif
+  if (fence)
+    {
+      if (memchr (fence, 0, 0))
+        return 1;
+      strcpy (fence - 9, "12345678");
+      if (memchr (fence - 9, 0, 79) != fence - 1)
+        return 2;
+    }
+  return 0;
+]])], [gl_cv_func_memchr_works=yes], [gl_cv_func_memchr_works=no],
+      [dnl Be pessimistic for now.
+       gl_cv_func_memchr_works="guessing no"])])
+    if test "$gl_cv_func_memchr_works" != yes; then
+      gl_PREREQ_MEMCHR
+      REPLACE_MEMCHR=1
+      AC_LIBOBJ([memchr])
+    fi
+  fi
+])
+
+# Prerequisites of lib/memchr.c.
+AC_DEFUN([gl_PREREQ_MEMCHR], [
+  AC_CHECK_HEADERS([bp-sym.h])
+])
diff --git a/m4/mmap-anon.m4 b/m4/mmap-anon.m4
new file mode 100644
index 0000000..14b6270
--- /dev/null
+++ b/m4/mmap-anon.m4
@@ -0,0 +1,59 @@
+# mmap-anon.m4 serial 8
+dnl Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Detect how mmap can be used to create anonymous (not file-backed) memory
+# mappings.
+# - On Linux, AIX, OSF/1, Solaris, Cygwin, Interix, Haiku, both MAP_ANONYMOUS
+#   and MAP_ANON exist and have the same value.
+# - On HP-UX, only MAP_ANONYMOUS exists.
+# - On MacOS X, FreeBSD, NetBSD, OpenBSD, only MAP_ANON exists.
+# - On IRIX, neither exists, and a file descriptor opened to /dev/zero must be
+#   used.
+
+AC_DEFUN([gl_FUNC_MMAP_ANON],
+[
+  dnl Work around a bug of AC_EGREP_CPP in autoconf-2.57.
+  AC_REQUIRE([AC_PROG_CPP])
+  AC_REQUIRE([AC_PROG_EGREP])
+
+  dnl Persuade glibc <sys/mman.h> to define MAP_ANONYMOUS.
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+
+  # Check for mmap(). Don't use AC_FUNC_MMAP, because it checks too much: it
+  # fails on HP-UX 11, because MAP_FIXED mappings do not work. But this is
+  # irrelevant for anonymous mappings.
+  AC_CHECK_FUNC([mmap], [gl_have_mmap=yes], [gl_have_mmap=no])
+
+  # Try to allow MAP_ANONYMOUS.
+  gl_have_mmap_anonymous=no
+  if test $gl_have_mmap = yes; then
+    AC_MSG_CHECKING([for MAP_ANONYMOUS])
+    AC_EGREP_CPP([I cant identify this map.], [
+#include <sys/mman.h>
+#ifdef MAP_ANONYMOUS
+    I cant identify this map.
+#endif
+],
+      [gl_have_mmap_anonymous=yes])
+    if test $gl_have_mmap_anonymous != yes; then
+      AC_EGREP_CPP([I cant identify this map.], [
+#include <sys/mman.h>
+#ifdef MAP_ANON
+    I cant identify this map.
+#endif
+],
+        [AC_DEFINE([MAP_ANONYMOUS], [MAP_ANON],
+          [Define to a substitute value for mmap()'s MAP_ANONYMOUS flag.])
+         gl_have_mmap_anonymous=yes])
+    fi
+    AC_MSG_RESULT([$gl_have_mmap_anonymous])
+    if test $gl_have_mmap_anonymous = yes; then
+      AC_DEFINE([HAVE_MAP_ANONYMOUS], [1],
+        [Define to 1 if mmap()'s MAP_ANONYMOUS flag is available after 
including
+         config.h and <sys/mman.h>.])
+    fi
+  fi
+])
diff --git a/m4/printf.m4 b/m4/printf.m4
new file mode 100644
index 0000000..87aa45c
--- /dev/null
+++ b/m4/printf.m4
@@ -0,0 +1,1416 @@
+# printf.m4 serial 33
+dnl Copyright (C) 2003, 2007-2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Test whether the *printf family of functions supports the 'j', 'z', 't',
+dnl 'L' size specifiers. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_sizes_c99.
+
+AC_DEFUN([gl_PRINTF_SIZES_C99],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+  AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports size specifiers as in C99],
+    [gl_cv_func_printf_sizes_c99],
+    [
+      AC_TRY_RUN([
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#if HAVE_STDINT_H_WITH_UINTMAX
+# include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H_WITH_UINTMAX
+# include <inttypes.h>
+#endif
+static char buf[100];
+int main ()
+{
+#if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX
+  buf[0] = '\0';
+  if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0
+      || strcmp (buf, "12345671 33") != 0)
+    return 1;
+#endif
+  buf[0] = '\0';
+  if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0
+      || strcmp (buf, "12345672 33") != 0)
+    return 1;
+  buf[0] = '\0';
+  if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0
+      || strcmp (buf, "12345673 33") != 0)
+    return 1;
+  buf[0] = '\0';
+  if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0
+      || strcmp (buf, "1.5 33") != 0)
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_sizes_c99=yes], [gl_cv_func_printf_sizes_c99=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_printf_sizes_c99="guessing yes";;
+                               # Guess yes on FreeBSD >= 5.
+         freebsd[1-4]*)        gl_cv_func_printf_sizes_c99="guessing no";;
+         freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_printf_sizes_c99="guessing no";;
+         darwin*)              gl_cv_func_printf_sizes_c99="guessing yes";;
+                               # Guess yes on OpenBSD >= 3.9.
+         openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
+                               gl_cv_func_printf_sizes_c99="guessing no";;
+         openbsd*)             gl_cv_func_printf_sizes_c99="guessing yes";;
+                               # Guess yes on Solaris >= 2.10.
+         solaris2.[0-9]*)      gl_cv_func_printf_sizes_c99="guessing no";;
+         solaris*)             gl_cv_func_printf_sizes_c99="guessing yes";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_printf_sizes_c99="guessing no";;
+         netbsd*)              gl_cv_func_printf_sizes_c99="guessing yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_printf_sizes_c99="guessing no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports 'long double'
+dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_long_double.
+
+AC_DEFUN([gl_PRINTF_LONG_DOUBLE],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports 'long double' arguments],
+    [gl_cv_func_printf_long_double],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[10000];
+int main ()
+{
+  buf[0] = '\0';
+  if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0
+      || strcmp (buf, "1.750000 33") != 0)
+    return 1;
+  buf[0] = '\0';
+  if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0
+      || strcmp (buf, "1.750000e+00 33") != 0)
+    return 1;
+  buf[0] = '\0';
+  if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0
+      || strcmp (buf, "1.75 33") != 0)
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_long_double=yes], [gl_cv_func_printf_long_double=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+         beos*)        gl_cv_func_printf_long_double="guessing no";;
+         mingw* | pw*) gl_cv_func_printf_long_double="guessing no";;
+         *)            gl_cv_func_printf_long_double="guessing yes";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports infinite and NaN
+dnl 'double' arguments and negative zero arguments in the %f, %e, %g
+dnl directives. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_infinite.
+
+AC_DEFUN([gl_PRINTF_INFINITE],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports infinite 'double' arguments],
+    [gl_cv_func_printf_infinite],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static int
+strisnan (const char *string, size_t start_index, size_t end_index)
+{
+  if (start_index < end_index)
+    {
+      if (string[start_index] == '-')
+        start_index++;
+      if (start_index + 3 <= end_index
+          && memcmp (string + start_index, "nan", 3) == 0)
+        {
+          start_index += 3;
+          if (start_index == end_index
+              || (string[start_index] == '(' && string[end_index - 1] == ')'))
+            return 1;
+        }
+    }
+  return 0;
+}
+static int
+have_minus_zero ()
+{
+  static double plus_zero = 0.0;
+  double minus_zero = - plus_zero;
+  return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
+}
+static char buf[10000];
+static double zero = 0.0;
+int main ()
+{
+  if (sprintf (buf, "%f", 1.0 / 0.0) < 0
+      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%f", -1.0 / 0.0) < 0
+      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%f", zero / zero) < 0
+      || !strisnan (buf, 0, strlen (buf)))
+    return 1;
+  if (sprintf (buf, "%e", 1.0 / 0.0) < 0
+      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%e", -1.0 / 0.0) < 0
+      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%e", zero / zero) < 0
+      || !strisnan (buf, 0, strlen (buf)))
+    return 1;
+  if (sprintf (buf, "%g", 1.0 / 0.0) < 0
+      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%g", -1.0 / 0.0) < 0
+      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%g", zero / zero) < 0
+      || !strisnan (buf, 0, strlen (buf)))
+    return 1;
+  /* This test fails on HP-UX 10.20.  */
+  if (have_minus_zero ())
+    if (sprintf (buf, "%g", - zero) < 0
+        || strcmp (buf, "-0") != 0)
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_infinite=yes], [gl_cv_func_printf_infinite=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_printf_infinite="guessing yes";;
+                               # Guess yes on FreeBSD >= 6.
+         freebsd[1-5]*)        gl_cv_func_printf_infinite="guessing no";;
+         freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_printf_infinite="guessing no";;
+         darwin*)              gl_cv_func_printf_infinite="guessing yes";;
+                               # Guess yes on HP-UX >= 11.
+         hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";;
+         hpux*)                gl_cv_func_printf_infinite="guessing yes";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_printf_infinite="guessing no";;
+         netbsd*)              gl_cv_func_printf_infinite="guessing yes";;
+                               # Guess yes on BeOS.
+         beos*)                gl_cv_func_printf_infinite="guessing yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_printf_infinite="guessing no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports infinite and NaN
+dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_infinite_long_double.
+
+AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE],
+[
+  AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gl_BIGENDIAN])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  dnl The user can set or unset the variable gl_printf_safe to indicate
+  dnl that he wishes a safe handling of non-IEEE-754 'long double' values.
+  if test -n "$gl_printf_safe"; then
+    AC_DEFINE([CHECK_PRINTF_SAFE], [1],
+      [Define if you wish *printf() functions that have a safe handling of
+       non-IEEE-754 'long double' values.])
+  fi
+  case "$gl_cv_func_printf_long_double" in
+    *yes)
+      AC_CACHE_CHECK([whether printf supports infinite 'long double' 
arguments],
+        [gl_cv_func_printf_infinite_long_double],
+        [
+          AC_TRY_RUN([
+]GL_NOCRASH[
+#include <float.h>
+#include <stdio.h>
+#include <string.h>
+static int
+strisnan (const char *string, size_t start_index, size_t end_index)
+{
+  if (start_index < end_index)
+    {
+      if (string[start_index] == '-')
+        start_index++;
+      if (start_index + 3 <= end_index
+          && memcmp (string + start_index, "nan", 3) == 0)
+        {
+          start_index += 3;
+          if (start_index == end_index
+              || (string[start_index] == '(' && string[end_index - 1] == ')'))
+            return 1;
+        }
+    }
+  return 0;
+}
+static char buf[10000];
+static long double zeroL = 0.0L;
+int main ()
+{
+  nocrash_init();
+  if (sprintf (buf, "%Lf", 1.0L / 0.0L) < 0
+      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%Lf", -1.0L / 0.0L) < 0
+      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%Lf", zeroL / zeroL) < 0
+      || !strisnan (buf, 0, strlen (buf)))
+    return 1;
+  if (sprintf (buf, "%Le", 1.0L / 0.0L) < 0
+      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%Le", -1.0L / 0.0L) < 0
+      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%Le", zeroL / zeroL) < 0
+      || !strisnan (buf, 0, strlen (buf)))
+    return 1;
+  if (sprintf (buf, "%Lg", 1.0L / 0.0L) < 0
+      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%Lg", -1.0L / 0.0L) < 0
+      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
+    return 1;
+  if (sprintf (buf, "%Lg", zeroL / zeroL) < 0
+      || !strisnan (buf, 0, strlen (buf)))
+    return 1;
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined 
__x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || 
defined _I386 || defined _M_IX86 || defined _X86_))
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+   of 'unsigned int' words.  */
+# ifdef WORDS_BIGENDIAN
+#  define LDBL80_WORDS(exponent,manthi,mantlo) \
+     { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+       ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
+       (unsigned int) (mantlo) << 16                                        \
+     }
+# else
+#  define LDBL80_WORDS(exponent,manthi,mantlo) \
+     { mantlo, manthi, exponent }
+# endif
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    if (sprintf (buf, "%Lf", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Le", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Lg", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    if (sprintf (buf, "%Lf", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Le", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Lg", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+  }
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    if (sprintf (buf, "%Lf", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Le", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Lg", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    if (sprintf (buf, "%Lf", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Le", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Lg", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    if (sprintf (buf, "%Lf", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Le", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Lg", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    if (sprintf (buf, "%Lf", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Le", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Lg", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    if (sprintf (buf, "%Lf", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Le", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+    if (sprintf (buf, "%Lg", x.value) < 0
+        || !strisnan (buf, 0, strlen (buf)))
+      return 1;
+  }
+#endif
+  return 0;
+}],
+          [gl_cv_func_printf_infinite_long_double=yes],
+          [gl_cv_func_printf_infinite_long_double=no],
+          [
+changequote(,)dnl
+           case "$host_cpu" in
+                                   # Guess no on ia64, x86_64, i386.
+             ia64 | x86_64 | i*86) 
gl_cv_func_printf_infinite_long_double="guessing no";;
+             *)
+               case "$host_os" in
+                                       # Guess yes on glibc systems.
+                 *-gnu*)               
gl_cv_func_printf_infinite_long_double="guessing yes";;
+                                       # Guess yes on FreeBSD >= 6.
+                 freebsd[1-5]*)        
gl_cv_func_printf_infinite_long_double="guessing no";;
+                 freebsd* | kfreebsd*) 
gl_cv_func_printf_infinite_long_double="guessing yes";;
+                                       # Guess yes on MacOS X >= 10.3.
+                 darwin[1-6].*)        
gl_cv_func_printf_infinite_long_double="guessing no";;
+                 darwin*)              
gl_cv_func_printf_infinite_long_double="guessing yes";;
+                                       # Guess yes on HP-UX >= 11.
+                 hpux[7-9]* | hpux10*) 
gl_cv_func_printf_infinite_long_double="guessing no";;
+                 hpux*)                
gl_cv_func_printf_infinite_long_double="guessing yes";;
+                                       # Guess yes on NetBSD >= 3.
+                 netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | 
netbsdcoff[1-2]*)
+                                       
gl_cv_func_printf_infinite_long_double="guessing no";;
+                 netbsd*)              
gl_cv_func_printf_infinite_long_double="guessing yes";;
+                                       # If we don't know, assume the worst.
+                 *)                    
gl_cv_func_printf_infinite_long_double="guessing no";;
+               esac
+               ;;
+           esac
+changequote([,])dnl
+          ])
+        ])
+      ;;
+    *)
+      gl_cv_func_printf_infinite_long_double="irrelevant"
+      ;;
+  esac
+])
+
+dnl Test whether the *printf family of functions supports the 'a' and 'A'
+dnl conversion specifier for hexadecimal output of floating-point numbers.
+dnl (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_directive_a.
+
+AC_DEFUN([gl_PRINTF_DIRECTIVE_A],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives],
+    [gl_cv_func_printf_directive_a],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
+      || (strcmp (buf, "0x1.922p+1 33") != 0
+          && strcmp (buf, "0x3.244p+0 33") != 0
+          && strcmp (buf, "0x6.488p-1 33") != 0
+          && strcmp (buf, "0xc.91p-2 33") != 0))
+    return 1;
+  if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
+      || (strcmp (buf, "-0X1.922P+1 33") != 0
+          && strcmp (buf, "-0X3.244P+0 33") != 0
+          && strcmp (buf, "-0X6.488P-1 33") != 0
+          && strcmp (buf, "-0XC.91P-2 33") != 0))
+    return 1;
+  /* This catches a FreeBSD 6.1 bug: it doesn't round.  */
+  if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0
+      || (strcmp (buf, "0x1.83p+0 33") != 0
+          && strcmp (buf, "0x3.05p-1 33") != 0
+          && strcmp (buf, "0x6.0ap-2 33") != 0
+          && strcmp (buf, "0xc.14p-3 33") != 0))
+    return 1;
+  /* This catches a FreeBSD 6.1 bug.  See
+     <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+  if (sprintf (buf, "%010a %d", 1.0 / 0.0, 33, 44, 55) < 0
+      || buf[0] == '0')
+    return 1;
+  /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug.  */
+  if (sprintf (buf, "%.1a", 1.999) < 0
+      || (strcmp (buf, "0x1.0p+1") != 0
+          && strcmp (buf, "0x2.0p+0") != 0
+          && strcmp (buf, "0x4.0p-1") != 0
+          && strcmp (buf, "0x8.0p-2") != 0))
+    return 1;
+  /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a
+     glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
+  if (sprintf (buf, "%.1La", 1.999L) < 0
+      || (strcmp (buf, "0x1.0p+1") != 0
+          && strcmp (buf, "0x2.0p+0") != 0
+          && strcmp (buf, "0x4.0p-1") != 0
+          && strcmp (buf, "0x8.0p-2") != 0))
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_directive_a=yes], [gl_cv_func_printf_directive_a=no],
+      [
+       case "$host_os" in
+                               # Guess yes on glibc >= 2.5 systems.
+         *-gnu*)
+           AC_EGREP_CPP([BZ2908], [
+             #include <features.h>
+             #ifdef __GNU_LIBRARY__
+              #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)
+               BZ2908
+              #endif
+             #endif
+             ],
+             [gl_cv_func_printf_directive_a="guessing yes"],
+             [gl_cv_func_printf_directive_a="guessing no"])
+           ;;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_printf_directive_a="guessing no";;
+       esac
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports the %F format
+dnl directive. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_directive_f.
+
+AC_DEFUN([gl_PRINTF_DIRECTIVE_F],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the 'F' directive],
+    [gl_cv_func_printf_directive_f],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0
+      || strcmp (buf, "1234567.000000 33") != 0)
+    return 1;
+  if (sprintf (buf, "%F", 1.0 / 0.0) < 0
+      || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0))
+    return 1;
+  /* This catches a Cygwin 1.5.x bug.  */
+  if (sprintf (buf, "%.F", 1234.0) < 0
+      || strcmp (buf, "1234") != 0)
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_directive_f=yes], [gl_cv_func_printf_directive_f=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_printf_directive_f="guessing yes";;
+                               # Guess yes on FreeBSD >= 6.
+         freebsd[1-5]*)        gl_cv_func_printf_directive_f="guessing no";;
+         freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_printf_directive_f="guessing no";;
+         darwin*)              gl_cv_func_printf_directive_f="guessing yes";;
+                               # Guess yes on Solaris >= 2.10.
+         solaris2.[0-9]*)      gl_cv_func_printf_directive_f="guessing no";;
+         solaris*)             gl_cv_func_printf_directive_f="guessing yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_printf_directive_f="guessing no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports the %n format
+dnl directive. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_directive_n.
+
+AC_DEFUN([gl_PRINTF_DIRECTIVE_N],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the 'n' directive],
+    [gl_cv_func_printf_directive_n],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char fmtstring[10];
+static char buf[100];
+int main ()
+{
+  int count = -1;
+  /* Copy the format string.  Some systems (glibc with _FORTIFY_SOURCE=2)
+     support %n in format strings in read-only memory but not in writable
+     memory.  */
+  strcpy (fmtstring, "%d %n");
+  if (sprintf (buf, fmtstring, 123, &count, 33, 44, 55) < 0
+      || strcmp (buf, "123 ") != 0
+      || count != 4)
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_directive_n=yes], [gl_cv_func_printf_directive_n=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+         *)     gl_cv_func_printf_directive_n="guessing yes";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports the %ls format
+dnl directive and in particular, when a precision is specified, whether
+dnl the functions stop converting the wide string argument when the number
+dnl of bytes that have been produced by this conversion equals or exceeds
+dnl the precision.
+dnl Result is gl_cv_func_printf_directive_ls.
+
+AC_DEFUN([gl_PRINTF_DIRECTIVE_LS],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the 'ls' directive],
+    [gl_cv_func_printf_directive_ls],
+    [
+      AC_TRY_RUN([
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+#include <string.h>
+int main ()
+{
+  char buf[100];
+  /* Test whether %ls works at all.
+     This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on
+     Cygwin 1.5.  */
+  {
+    static const wchar_t wstring[] = { 'a', 'b', 'c', 0 };
+    buf[0] = '\0';
+    if (sprintf (buf, "%ls", wstring) < 0
+        || strcmp (buf, "abc") != 0)
+      return 1;
+  }
+  /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an
+     assertion failure inside libc), but not on OpenBSD 4.0.  */
+  {
+    static const wchar_t wstring[] = { 'a', 0 };
+    buf[0] = '\0';
+    if (sprintf (buf, "%ls", wstring) < 0
+        || strcmp (buf, "a") != 0)
+      return 1;
+  }
+  /* Test whether precisions in %ls are supported as specified in ISO C 99
+     section 7.19.6.1:
+       "If a precision is specified, no more than that many bytes are written
+        (including shift sequences, if any), and the array shall contain a
+        null wide character if, to equal the multibyte character sequence
+        length given by the precision, the function would need to access a
+        wide character one past the end of the array."
+     This test fails on Solaris 10.  */
+  {
+    static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 };
+    buf[0] = '\0';
+    if (sprintf (buf, "%.2ls", wstring) < 0
+        || strcmp (buf, "ab") != 0)
+      return 1;
+  }
+  return 0;
+}], [gl_cv_func_printf_directive_ls=yes], [gl_cv_func_printf_directive_ls=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+         openbsd*)        gl_cv_func_printf_directive_ls="guessing no";;
+         irix*)           gl_cv_func_printf_directive_ls="guessing no";;
+         solaris*)        gl_cv_func_printf_directive_ls="guessing no";;
+         cygwin*)         gl_cv_func_printf_directive_ls="guessing no";;
+         beos* | haiku*)  gl_cv_func_printf_directive_ls="guessing no";;
+         *)               gl_cv_func_printf_directive_ls="guessing yes";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports POSIX/XSI format
+dnl strings with positions. (POSIX:2001)
+dnl Result is gl_cv_func_printf_positions.
+
+AC_DEFUN([gl_PRINTF_POSITIONS],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with 
positions],
+    [gl_cv_func_printf_positions],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+/* The string "%2$d %1$d", with dollar characters protected from the shell's
+   dollar expansion (possibly an autoconf bug).  */
+static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
+static char buf[100];
+int main ()
+{
+  sprintf (buf, format, 33, 55);
+  return (strcmp (buf, "55 33") != 0);
+}], [gl_cv_func_printf_positions=yes], [gl_cv_func_printf_positions=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+         netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*)
+                       gl_cv_func_printf_positions="guessing no";;
+         beos*)        gl_cv_func_printf_positions="guessing no";;
+         mingw* | pw*) gl_cv_func_printf_positions="guessing no";;
+         *)            gl_cv_func_printf_positions="guessing yes";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports POSIX/XSI format
+dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001)
+dnl Result is gl_cv_func_printf_flag_grouping.
+
+AC_DEFUN([gl_PRINTF_FLAG_GROUPING],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the grouping flag],
+    [gl_cv_func_printf_flag_grouping],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  if (sprintf (buf, "%'d %d", 1234567, 99) < 0
+      || buf[strlen (buf) - 1] != '9')
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_flag_grouping=yes], 
[gl_cv_func_printf_flag_grouping=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+         cygwin*)      gl_cv_func_printf_flag_grouping="guessing no";;
+         netbsd*)      gl_cv_func_printf_flag_grouping="guessing no";;
+         mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";;
+         *)            gl_cv_func_printf_flag_grouping="guessing yes";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports the - flag correctly.
+dnl (ISO C99.) See
+dnl <http://lists.gnu.org/archive/html/bug-coreutils/2008-02/msg00035.html>
+dnl Result is gl_cv_func_printf_flag_leftadjust.
+
+AC_DEFUN([gl_PRINTF_FLAG_LEFTADJUST],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the left-adjust flag correctly],
+    [gl_cv_func_printf_flag_leftadjust],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  /* Check that a '-' flag is not annihilated by a negative width.  */
+  if (sprintf (buf, "a%-*sc", -3, "b") < 0
+      || strcmp (buf, "ab  c") != 0)
+    return 1;
+  return 0;
+}],
+        [gl_cv_func_printf_flag_leftadjust=yes],
+        [gl_cv_func_printf_flag_leftadjust=no],
+        [
+changequote(,)dnl
+         case "$host_os" in
+                    # Guess yes on HP-UX 11.
+           hpux11*) gl_cv_func_printf_flag_leftadjust="guessing yes";;
+                    # Guess no on HP-UX 10 and older.
+           hpux*)   gl_cv_func_printf_flag_leftadjust="guessing no";;
+                    # Guess yes otherwise.
+           *)       gl_cv_func_printf_flag_leftadjust="guessing yes";;
+         esac
+changequote([,])dnl
+        ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports padding of non-finite
+dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See
+dnl <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html>
+dnl Result is gl_cv_func_printf_flag_zero.
+
+AC_DEFUN([gl_PRINTF_FLAG_ZERO],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports the zero flag correctly],
+    [gl_cv_func_printf_flag_zero],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  if (sprintf (buf, "%010f", 1.0 / 0.0, 33, 44, 55) < 0
+      || (strcmp (buf, "       inf") != 0
+          && strcmp (buf, "  infinity") != 0))
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_flag_zero=yes], [gl_cv_func_printf_flag_zero=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                 # Guess yes on glibc systems.
+         *-gnu*) gl_cv_func_printf_flag_zero="guessing yes";;
+                 # Guess yes on BeOS.
+         beos*)  gl_cv_func_printf_flag_zero="guessing yes";;
+                 # If we don't know, assume the worst.
+         *)      gl_cv_func_printf_flag_zero="guessing no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions supports large precisions.
+dnl On mingw, precisions larger than 512 are treated like 512, in integer,
+dnl floating-point or pointer output. On BeOS, precisions larger than 1044
+dnl crash the program.
+dnl Result is gl_cv_func_printf_precision.
+
+AC_DEFUN([gl_PRINTF_PRECISION],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf supports large precisions],
+    [gl_cv_func_printf_precision],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[5000];
+int main ()
+{
+#ifdef __BEOS__
+  /* On BeOS, this would crash and show a dialog box.  Avoid the crash.  */
+  return 1;
+#endif
+  if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3)
+    return 1;
+  return 0;
+}], [gl_cv_func_printf_precision=yes], [gl_cv_func_printf_precision=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+         # Guess no only on native Win32 and BeOS systems.
+         mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;;
+         beos*)        gl_cv_func_printf_precision="guessing no" ;;
+         *)            gl_cv_func_printf_precision="guessing yes" ;;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the *printf family of functions recovers gracefully in case
+dnl of an out-of-memory condition, or whether it crashes the entire program.
+dnl Result is gl_cv_func_printf_enomem.
+
+AC_DEFUN([gl_PRINTF_ENOMEM],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gl_MULTIARCH])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether printf survives out-of-memory conditions],
+    [gl_cv_func_printf_enomem],
+    [
+      gl_cv_func_printf_enomem="guessing no"
+      if test "$cross_compiling" = no; then
+        if test $APPLE_UNIVERSAL_BUILD = 0; then
+          AC_LANG_CONFTEST([AC_LANG_SOURCE([
+]GL_NOCRASH[
+changequote(,)dnl
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <errno.h>
+int main()
+{
+  struct rlimit limit;
+  int ret;
+  nocrash_init ();
+  /* Some printf implementations allocate temporary space with malloc.  */
+  /* On BSD systems, malloc() is limited by RLIMIT_DATA.  */
+#ifdef RLIMIT_DATA
+  if (getrlimit (RLIMIT_DATA, &limit) < 0)
+    return 77;
+  if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
+    limit.rlim_max = 5000000;
+  limit.rlim_cur = limit.rlim_max;
+  if (setrlimit (RLIMIT_DATA, &limit) < 0)
+    return 77;
+#endif
+  /* On Linux systems, malloc() is limited by RLIMIT_AS.  */
+#ifdef RLIMIT_AS
+  if (getrlimit (RLIMIT_AS, &limit) < 0)
+    return 77;
+  if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
+    limit.rlim_max = 5000000;
+  limit.rlim_cur = limit.rlim_max;
+  if (setrlimit (RLIMIT_AS, &limit) < 0)
+    return 77;
+#endif
+  /* Some printf implementations allocate temporary space on the stack.  */
+#ifdef RLIMIT_STACK
+  if (getrlimit (RLIMIT_STACK, &limit) < 0)
+    return 77;
+  if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
+    limit.rlim_max = 5000000;
+  limit.rlim_cur = limit.rlim_max;
+  if (setrlimit (RLIMIT_STACK, &limit) < 0)
+    return 77;
+#endif
+  ret = printf ("%.5000000f", 1.0);
+  return !(ret == 5000002 || (ret < 0 && errno == ENOMEM));
+}
+changequote([,])dnl
+          ])])
+          if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then
+            (./conftest
+             result=$?
+             if test $result != 0 && test $result != 77; then result=1; fi
+             exit $result
+            ) >/dev/null 2>/dev/null
+            case $? in
+              0) gl_cv_func_printf_enomem="yes" ;;
+              77) gl_cv_func_printf_enomem="guessing no" ;;
+              *) gl_cv_func_printf_enomem="no" ;;
+            esac
+          else
+            gl_cv_func_printf_enomem="guessing no"
+          fi
+          rm -fr conftest*
+        else
+          dnl A universal build on Apple MacOS X platforms.
+          dnl The result would be 'no' in 32-bit mode and 'yes' in 64-bit mode.
+          dnl But we need a configuration result that is valid in both modes.
+          gl_cv_func_printf_enomem="guessing no"
+        fi
+      fi
+      if test "$gl_cv_func_printf_enomem" = "guessing no"; then
+changequote(,)dnl
+        case "$host_os" in
+                    # Guess yes on glibc systems.
+          *-gnu*)   gl_cv_func_printf_enomem="guessing yes";;
+                    # Guess yes on Solaris.
+          solaris*) gl_cv_func_printf_enomem="guessing yes";;
+                    # Guess yes on AIX.
+          aix*)     gl_cv_func_printf_enomem="guessing yes";;
+                    # Guess yes on HP-UX/hppa.
+          hpux*)    case "$host_cpu" in
+                      hppa*) gl_cv_func_printf_enomem="guessing yes";;
+                      *)     gl_cv_func_printf_enomem="guessing no";;
+                    esac
+                    ;;
+                    # Guess yes on IRIX.
+          irix*)    gl_cv_func_printf_enomem="guessing yes";;
+                    # Guess yes on OSF/1.
+          osf*)     gl_cv_func_printf_enomem="guessing yes";;
+                    # Guess yes on BeOS.
+          beos*)    gl_cv_func_printf_enomem="guessing yes";;
+                    # Guess yes on Haiku.
+          haiku*)   gl_cv_func_printf_enomem="guessing yes";;
+                    # If we don't know, assume the worst.
+          *)        gl_cv_func_printf_enomem="guessing no";;
+        esac
+changequote([,])dnl
+      fi
+    ])
+])
+
+dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
+dnl Result is ac_cv_func_snprintf.
+
+AC_DEFUN([gl_SNPRINTF_PRESENCE],
+[
+  AC_CHECK_FUNCS_ONCE([snprintf])
+])
+
+dnl Test whether the string produced by the snprintf function is always NUL
+dnl terminated. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_snprintf_truncation_c99.
+
+AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether snprintf truncates the result as in C99],
+    [gl_cv_func_snprintf_truncation_c99],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  strcpy (buf, "ABCDEF");
+  snprintf (buf, 3, "%d %d", 4567, 89);
+  if (memcmp (buf, "45\0DEF", 6) != 0)
+    return 1;
+  return 0;
+}], [gl_cv_func_snprintf_truncation_c99=yes], 
[gl_cv_func_snprintf_truncation_c99=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on FreeBSD >= 5.
+         freebsd[1-4]*)        gl_cv_func_snprintf_truncation_c99="guessing 
no";;
+         freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_snprintf_truncation_c99="guessing 
no";;
+         darwin*)              gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on OpenBSD >= 3.9.
+         openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
+                               gl_cv_func_snprintf_truncation_c99="guessing 
no";;
+         openbsd*)             gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on Solaris >= 2.6.
+         solaris2.[0-5]*)      gl_cv_func_snprintf_truncation_c99="guessing 
no";;
+         solaris*)             gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on AIX >= 4.
+         aix[1-3]*)            gl_cv_func_snprintf_truncation_c99="guessing 
no";;
+         aix*)                 gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on HP-UX >= 11.
+         hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing 
no";;
+         hpux*)                gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on IRIX >= 6.5.
+         irix6.5)              gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on OSF/1 >= 5.
+         osf[3-4]*)            gl_cv_func_snprintf_truncation_c99="guessing 
no";;
+         osf*)                 gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_snprintf_truncation_c99="guessing 
no";;
+         netbsd*)              gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # Guess yes on BeOS.
+         beos*)                gl_cv_func_snprintf_truncation_c99="guessing 
yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_snprintf_truncation_c99="guessing 
no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the return value of the snprintf function is the number
+dnl of bytes (excluding the terminating NUL) that would have been produced
+dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
+dnl For example, this test program fails on IRIX 6.5:
+dnl     ---------------------------------------------------------------------
+dnl     #include <stdio.h>
+dnl     int main()
+dnl     {
+dnl       static char buf[8];
+dnl       int retval = snprintf (buf, 3, "%d", 12345);
+dnl       return retval >= 0 && retval < 3;
+dnl     }
+dnl     ---------------------------------------------------------------------
+dnl Result is gl_cv_func_snprintf_retval_c99.
+
+AC_DEFUN([gl_SNPRINTF_RETVAL_C99],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
+    [gl_cv_func_snprintf_retval_c99],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+  strcpy (buf, "ABCDEF");
+  if (snprintf (buf, 3, "%d %d", 4567, 89) != 7)
+    return 1;
+  return 0;
+}], [gl_cv_func_snprintf_retval_c99=yes], [gl_cv_func_snprintf_retval_c99=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on FreeBSD >= 5.
+         freebsd[1-4]*)        gl_cv_func_snprintf_retval_c99="guessing no";;
+         freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_snprintf_retval_c99="guessing no";;
+         darwin*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on OpenBSD >= 3.9.
+         openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
+                               gl_cv_func_snprintf_retval_c99="guessing no";;
+         openbsd*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on Solaris >= 2.6.
+         solaris2.[0-5]*)      gl_cv_func_snprintf_retval_c99="guessing no";;
+         solaris*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on AIX >= 4.
+         aix[1-3]*)            gl_cv_func_snprintf_retval_c99="guessing no";;
+         aix*)                 gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_snprintf_retval_c99="guessing no";;
+         netbsd*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # Guess yes on BeOS.
+         beos*)                gl_cv_func_snprintf_retval_c99="guessing yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_snprintf_retval_c99="guessing no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the snprintf function supports the %n format directive
+dnl also in truncated portions of the format string. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_snprintf_directive_n.
+
+AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive],
+    [gl_cv_func_snprintf_directive_n],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char fmtstring[10];
+static char buf[100];
+int main ()
+{
+  int count = -1;
+  /* Copy the format string.  Some systems (glibc with _FORTIFY_SOURCE=2)
+     support %n in format strings in read-only memory but not in writable
+     memory.  */
+  strcpy (fmtstring, "%d %n");
+  snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55);
+  if (count != 6)
+    return 1;
+  return 0;
+}], [gl_cv_func_snprintf_directive_n=yes], 
[gl_cv_func_snprintf_directive_n=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on FreeBSD >= 5.
+         freebsd[1-4]*)        gl_cv_func_snprintf_directive_n="guessing no";;
+         freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_snprintf_directive_n="guessing no";;
+         darwin*)              gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on Solaris >= 2.6.
+         solaris2.[0-5]*)      gl_cv_func_snprintf_directive_n="guessing no";;
+         solaris*)             gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on AIX >= 4.
+         aix[1-3]*)            gl_cv_func_snprintf_directive_n="guessing no";;
+         aix*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on IRIX >= 6.5.
+         irix6.5)              gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on OSF/1 >= 5.
+         osf[3-4]*)            gl_cv_func_snprintf_directive_n="guessing no";;
+         osf*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_snprintf_directive_n="guessing no";;
+         netbsd*)              gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # Guess yes on BeOS.
+         beos*)                gl_cv_func_snprintf_directive_n="guessing yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_snprintf_directive_n="guessing no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl Test whether the snprintf function, when passed a size = 1, writes any
+dnl output without bounds in this case, behaving like sprintf. This is the
+dnl case on Linux libc5.
+dnl Result is gl_cv_func_snprintf_size1.
+
+AC_DEFUN([gl_SNPRINTF_SIZE1],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_CACHE_CHECK([whether snprintf respects a size of 1],
+    [gl_cv_func_snprintf_size1],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+int main()
+{
+  static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
+  snprintf (buf, 1, "%d", 12345);
+  return buf[1] != 'E';
+}],
+      [gl_cv_func_snprintf_size1=yes],
+      [gl_cv_func_snprintf_size1=no],
+      [gl_cv_func_snprintf_size1="guessing yes"])
+    ])
+])
+
+dnl Test whether the vsnprintf function, when passed a zero size, produces no
+dnl output. (ISO C99, POSIX:2001)
+dnl For example, snprintf nevertheless writes a NUL byte in this case
+dnl on OSF/1 5.1:
+dnl     ---------------------------------------------------------------------
+dnl     #include <stdio.h>
+dnl     int main()
+dnl     {
+dnl       static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
+dnl       snprintf (buf, 0, "%d", 12345);
+dnl       return buf[0] != 'D';
+dnl     }
+dnl     ---------------------------------------------------------------------
+dnl And vsnprintf writes any output without bounds in this case, behaving like
+dnl vsprintf, on HP-UX 11 and OSF/1 5.1:
+dnl     ---------------------------------------------------------------------
+dnl     #include <stdarg.h>
+dnl     #include <stdio.h>
+dnl     static int my_snprintf (char *buf, int size, const char *format, ...)
+dnl     {
+dnl       va_list args;
+dnl       int ret;
+dnl       va_start (args, format);
+dnl       ret = vsnprintf (buf, size, format, args);
+dnl       va_end (args);
+dnl       return ret;
+dnl     }
+dnl     int main()
+dnl     {
+dnl       static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
+dnl       my_snprintf (buf, 0, "%d", 12345);
+dnl       return buf[0] != 'D';
+dnl     }
+dnl     ---------------------------------------------------------------------
+dnl Result is gl_cv_func_vsnprintf_zerosize_c99.
+
+AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99],
+    [gl_cv_func_vsnprintf_zerosize_c99],
+    [
+      AC_TRY_RUN([
+#include <stdarg.h>
+#include <stdio.h>
+static int my_snprintf (char *buf, int size, const char *format, ...)
+{
+  va_list args;
+  int ret;
+  va_start (args, format);
+  ret = vsnprintf (buf, size, format, args);
+  va_end (args);
+  return ret;
+}
+int main()
+{
+  static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
+  my_snprintf (buf, 0, "%d", 12345);
+  return buf[0] != 'D';
+}],
+      [gl_cv_func_vsnprintf_zerosize_c99=yes],
+      [gl_cv_func_vsnprintf_zerosize_c99=no],
+      [
+changequote(,)dnl
+       case "$host_os" in
+                               # Guess yes on glibc systems.
+         *-gnu*)               gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # Guess yes on FreeBSD >= 5.
+         freebsd[1-4]*)        gl_cv_func_vsnprintf_zerosize_c99="guessing 
no";;
+         freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # Guess yes on MacOS X >= 10.3.
+         darwin[1-6].*)        gl_cv_func_vsnprintf_zerosize_c99="guessing 
no";;
+         darwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # Guess yes on Cygwin.
+         cygwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # Guess yes on Solaris >= 2.6.
+         solaris2.[0-5]*)      gl_cv_func_vsnprintf_zerosize_c99="guessing 
no";;
+         solaris*)             gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # Guess yes on AIX >= 4.
+         aix[1-3]*)            gl_cv_func_vsnprintf_zerosize_c99="guessing 
no";;
+         aix*)                 gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # Guess yes on IRIX >= 6.5.
+         irix6.5)              gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # Guess yes on NetBSD >= 3.
+         netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
+                               gl_cv_func_vsnprintf_zerosize_c99="guessing 
no";;
+         netbsd*)              gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # Guess yes on BeOS.
+         beos*)                gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # Guess yes on mingw.
+         mingw* | pw*)         gl_cv_func_vsnprintf_zerosize_c99="guessing 
yes";;
+                               # If we don't know, assume the worst.
+         *)                    gl_cv_func_vsnprintf_zerosize_c99="guessing 
no";;
+       esac
+changequote([,])dnl
+      ])
+    ])
+])
+
+dnl The results of these tests on various platforms are:
+dnl
+dnl 1 = gl_PRINTF_SIZES_C99
+dnl 2 = gl_PRINTF_LONG_DOUBLE
+dnl 3 = gl_PRINTF_INFINITE
+dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE
+dnl 5 = gl_PRINTF_DIRECTIVE_A
+dnl 6 = gl_PRINTF_DIRECTIVE_F
+dnl 7 = gl_PRINTF_DIRECTIVE_N
+dnl 8 = gl_PRINTF_DIRECTIVE_LS
+dnl 9 = gl_PRINTF_POSITIONS
+dnl 10 = gl_PRINTF_FLAG_GROUPING
+dnl 11 = gl_PRINTF_FLAG_LEFTADJUST
+dnl 12 = gl_PRINTF_FLAG_ZERO
+dnl 13 = gl_PRINTF_PRECISION
+dnl 14 = gl_PRINTF_ENOMEM
+dnl 15 = gl_SNPRINTF_PRESENCE
+dnl 16 = gl_SNPRINTF_TRUNCATION_C99
+dnl 17 = gl_SNPRINTF_RETVAL_C99
+dnl 18 = gl_SNPRINTF_DIRECTIVE_N
+dnl 19 = gl_SNPRINTF_SIZE1
+dnl 20 = gl_VSNPRINTF_ZEROSIZE_C99
+dnl
+dnl 1 = checking whether printf supports size specifiers as in C99...
+dnl 2 = checking whether printf supports 'long double' arguments...
+dnl 3 = checking whether printf supports infinite 'double' arguments...
+dnl 4 = checking whether printf supports infinite 'long double' arguments...
+dnl 5 = checking whether printf supports the 'a' and 'A' directives...
+dnl 6 = checking whether printf supports the 'F' directive...
+dnl 7 = checking whether printf supports the 'n' directive...
+dnl 8 = checking whether printf supports the 'ls' directive...
+dnl 9 = checking whether printf supports POSIX/XSI format strings with 
positions...
+dnl 10 = checking whether printf supports the grouping flag...
+dnl 11 = checking whether printf supports the left-adjust flag correctly...
+dnl 12 = checking whether printf supports the zero flag correctly...
+dnl 13 = checking whether printf supports large precisions...
+dnl 14 = checking whether printf survives out-of-memory conditions...
+dnl 15 = checking for snprintf...
+dnl 16 = checking whether snprintf truncates the result as in C99...
+dnl 17 = checking whether snprintf returns a byte count as in C99...
+dnl 18 = checking whether snprintf fully supports the 'n' directive...
+dnl 19 = checking whether snprintf respects a size of 1...
+dnl 20 = checking whether vsnprintf respects a zero size as in C99...
+dnl
+dnl . = yes, # = no.
+dnl
+dnl                                  1  2  3  4  5  6  7  8  9 10 11 12 13 14 
15 16 17 18 19 20
+dnl   glibc 2.5                      .  .  .  .  .  .  .  .  .  .  .  .  .  .  
.  .  .  .  .  .
+dnl   glibc 2.3.6                    .  .  .  .  #  .  .  .  .  .  .  .  .  .  
.  .  .  .  .  .
+dnl   FreeBSD 5.4, 6.1               .  .  .  .  #  .  .  .  .  .  .  #  .  #  
.  .  .  .  .  .
+dnl   MacOS X 10.3.9                 .  .  .  .  #  .  .  .  .  .  .  #  .  #  
.  .  .  .  .  .
+dnl   OpenBSD 3.9, 4.0               .  .  #  #  #  #  .  #  .  #  .  #  .  #  
.  .  .  .  .  .
+dnl   Cygwin 1.7.0 (2009)            .  .  .  #  .  .  .  ?  .  .  .  .  .  ?  
.  .  .  .  .  .
+dnl   Cygwin 1.5.25 (2008)           .  .  .  #  #  .  .  #  .  .  .  .  .  #  
.  .  .  .  .  .
+dnl   Cygwin 1.5.19 (2006)           #  .  .  #  #  #  .  #  .  #  .  #  #  #  
.  .  .  .  .  .
+dnl   Solaris 10                     .  .  #  #  #  .  .  #  .  .  .  #  .  .  
.  .  .  .  .  .
+dnl   Solaris 2.6 ... 9              #  .  #  #  #  #  .  #  .  .  .  #  .  .  
.  .  .  .  .  .
+dnl   Solaris 2.5.1                  #  .  #  #  #  #  .  #  .  .  .  #  .  .  
#  #  #  #  #  #
+dnl   AIX 5.2                        .  .  #  #  #  .  .  .  .  .  .  #  .  .  
.  .  .  .  .  .
+dnl   AIX 4.3.2, 5.1                 #  .  #  #  #  #  .  .  .  .  .  #  .  .  
.  .  .  .  .  .
+dnl   HP-UX 11.31                    .  .  .  .  #  .  .  .  .  .  .  #  .  .  
.  .  #  #  .  .
+dnl   HP-UX 11.{00,11,23}            #  .  .  .  #  #  .  .  .  .  .  #  .  .  
.  .  #  #  .  #
+dnl   HP-UX 10.20                    #  .  #  .  #  #  .  ?  .  .  #  #  .  .  
.  .  #  #  ?  #
+dnl   IRIX 6.5                       #  .  #  #  #  #  .  #  .  .  .  #  .  .  
.  .  #  .  .  .
+dnl   OSF/1 5.1                      #  .  #  #  #  #  .  .  .  .  .  #  .  .  
.  .  #  .  .  #
+dnl   OSF/1 4.0d                     #  .  #  #  #  #  .  .  .  .  .  #  .  .  
#  #  #  #  #  #
+dnl   NetBSD 4.0                     .  ?  ?  ?  ?  ?  .  ?  .  ?  ?  ?  ?  ?  
.  .  .  ?  ?  ?
+dnl   NetBSD 3.0                     .  .  .  .  #  #  .  ?  #  #  ?  #  .  #  
.  .  .  .  .  .
+dnl   Haiku                          .  .  .  #  #  #  .  #  .  .  .  .  .  ?  
.  .  .  .  .  .
+dnl   BeOS                           #  #  .  #  #  #  .  ?  #  .  ?  .  #  ?  
.  .  .  .  .  .
+dnl   mingw                          #  #  #  #  #  #  .  .  #  #  .  #  #  ?  
.  #  #  #  .  .
diff --git a/m4/size_max.m4 b/m4/size_max.m4
new file mode 100644
index 0000000..35bd3d6
--- /dev/null
+++ b/m4/size_max.m4
@@ -0,0 +1,75 @@
+# size_max.m4 serial 9
+dnl Copyright (C) 2003, 2005-2006, 2008-2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([gl_SIZE_MAX],
+[
+  AC_CHECK_HEADERS([stdint.h])
+  dnl First test whether the system already has SIZE_MAX.
+  AC_CACHE_CHECK([for SIZE_MAX], [gl_cv_size_max], [
+    gl_cv_size_max=
+    AC_EGREP_CPP([Found it], [
+#include <limits.h>
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef SIZE_MAX
+Found it
+#endif
+], [gl_cv_size_max=yes])
+    if test -z "$gl_cv_size_max"; then
+      dnl Define it ourselves. Here we assume that the type 'size_t' is not 
wider
+      dnl than the type 'unsigned long'. Try hard to find a definition that can
+      dnl be used in a preprocessor #if, i.e. doesn't contain a cast.
+      AC_COMPUTE_INT([size_t_bits_minus_1], [sizeof (size_t) * CHAR_BIT - 1],
+        [#include <stddef.h>
+#include <limits.h>], [size_t_bits_minus_1=])
+      AC_COMPUTE_INT([fits_in_uint], [sizeof (size_t) <= sizeof (unsigned 
int)],
+        [#include <stddef.h>], [fits_in_uint=])
+      if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then
+        if test $fits_in_uint = 1; then
+          dnl Even though SIZE_MAX fits in an unsigned int, it must be of type
+          dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned 
long'.
+          AC_TRY_COMPILE([#include <stddef.h>
+            extern size_t foo;
+            extern unsigned long foo;
+            ], [], [fits_in_uint=0])
+        fi
+        dnl We cannot use 'expr' to simplify this expression, because 'expr'
+        dnl works only with 'long' integers in the host environment, while we
+        dnl might be cross-compiling from a 32-bit platform to a 64-bit 
platform.
+        if test $fits_in_uint = 1; then
+          gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)"
+        else
+          gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)"
+        fi
+      else
+        dnl Shouldn't happen, but who knows...
+        gl_cv_size_max='((size_t)~(size_t)0)'
+      fi
+    fi
+  ])
+  if test "$gl_cv_size_max" != yes; then
+    AC_DEFINE_UNQUOTED([SIZE_MAX], [$gl_cv_size_max],
+      [Define as the maximum value of type 'size_t', if the system doesn't 
define it.])
+  fi
+  dnl Don't redefine SIZE_MAX in config.h if config.h is re-included after
+  dnl <stdint.h>. Remember that the #undef in AH_VERBATIM gets replaced with
+  dnl #define by AC_DEFINE_UNQUOTED.
+  AH_VERBATIM([SIZE_MAX],
+[/* Define as the maximum value of type 'size_t', if the system doesn't define
+   it. */
+#ifndef SIZE_MAX
+# undef SIZE_MAX
+#endif])
+])
+
+dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in.
+dnl Remove this when we can assume autoconf >= 2.61.
+m4_ifdef([AC_COMPUTE_INT], [], [
+  AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])])
+])
diff --git a/m4/stdint_h.m4 b/m4/stdint_h.m4
new file mode 100644
index 0000000..82f0c24
--- /dev/null
+++ b/m4/stdint_h.m4
@@ -0,0 +1,26 @@
+# stdint_h.m4 serial 8
+dnl Copyright (C) 1997-2004, 2006, 2008, 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_STDINT_H_WITH_UINTMAX if <stdint.h> exists,
+# doesn't clash with <sys/types.h>, and declares uintmax_t.
+
+AC_DEFUN([gl_AC_HEADER_STDINT_H],
+[
+  AC_CACHE_CHECK([for stdint.h], [gl_cv_header_stdint_h],
+  [AC_TRY_COMPILE(
+    [#include <sys/types.h>
+#include <stdint.h>],
+    [uintmax_t i = (uintmax_t) -1; return !i;],
+    [gl_cv_header_stdint_h=yes],
+    [gl_cv_header_stdint_h=no])])
+  if test $gl_cv_header_stdint_h = yes; then
+    AC_DEFINE_UNQUOTED([HAVE_STDINT_H_WITH_UINTMAX], [1],
+      [Define if <stdint.h> exists, doesn't clash with <sys/types.h>,
+       and declares uintmax_t. ])
+  fi
+])
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
new file mode 100644
index 0000000..fcbe68f
--- /dev/null
+++ b/m4/stdio_h.m4
@@ -0,0 +1,136 @@
+# stdio_h.m4 serial 16
+dnl Copyright (C) 2007-2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_STDIO_H],
+[
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  gl_CHECK_NEXT_HEADERS([stdio.h])
+  dnl No need to create extra modules for these functions. Everyone who uses
+  dnl <stdio.h> likely needs them.
+  GNULIB_FPRINTF=1
+  GNULIB_PRINTF=1
+  GNULIB_VFPRINTF=1
+  GNULIB_VPRINTF=1
+  GNULIB_FPUTC=1
+  GNULIB_PUTC=1
+  GNULIB_PUTCHAR=1
+  GNULIB_FPUTS=1
+  GNULIB_PUTS=1
+  GNULIB_FWRITE=1
+  dnl This ifdef is just an optimization, to avoid performing a configure
+  dnl check whose result is not used. It does not make the test of
+  dnl GNULIB_STDIO_H_SIGPIPE or GNULIB_SIGPIPE redundant.
+  m4_ifdef([gl_SIGNAL_SIGPIPE], [
+    gl_SIGNAL_SIGPIPE
+    if test $gl_cv_header_signal_h_SIGPIPE != yes; then
+      REPLACE_STDIO_WRITE_FUNCS=1
+      AC_LIBOBJ([stdio-write])
+    fi
+  ])
+])
+
+AC_DEFUN([gl_STDIO_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  
GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1
+])
+
+AC_DEFUN([gl_STDIO_H_DEFAULTS],
+[
+  GNULIB_FPRINTF=0;              AC_SUBST([GNULIB_FPRINTF])
+  GNULIB_FPRINTF_POSIX=0;        AC_SUBST([GNULIB_FPRINTF_POSIX])
+  GNULIB_PRINTF=0;               AC_SUBST([GNULIB_PRINTF])
+  GNULIB_PRINTF_POSIX=0;         AC_SUBST([GNULIB_PRINTF_POSIX])
+  GNULIB_SNPRINTF=0;             AC_SUBST([GNULIB_SNPRINTF])
+  GNULIB_SPRINTF_POSIX=0;        AC_SUBST([GNULIB_SPRINTF_POSIX])
+  GNULIB_VFPRINTF=0;             AC_SUBST([GNULIB_VFPRINTF])
+  GNULIB_VFPRINTF_POSIX=0;       AC_SUBST([GNULIB_VFPRINTF_POSIX])
+  GNULIB_VPRINTF=0;              AC_SUBST([GNULIB_VPRINTF])
+  GNULIB_VPRINTF_POSIX=0;        AC_SUBST([GNULIB_VPRINTF_POSIX])
+  GNULIB_VSNPRINTF=0;            AC_SUBST([GNULIB_VSNPRINTF])
+  GNULIB_VSPRINTF_POSIX=0;       AC_SUBST([GNULIB_VSPRINTF_POSIX])
+  GNULIB_DPRINTF=0;              AC_SUBST([GNULIB_DPRINTF])
+  GNULIB_VDPRINTF=0;             AC_SUBST([GNULIB_VDPRINTF])
+  GNULIB_VASPRINTF=0;            AC_SUBST([GNULIB_VASPRINTF])
+  GNULIB_OBSTACK_PRINTF=0;       AC_SUBST([GNULIB_OBSTACK_PRINTF])
+  GNULIB_OBSTACK_PRINTF_POSIX=0; AC_SUBST([GNULIB_OBSTACK_PRINTF_POSIX])
+  GNULIB_FOPEN=0;                AC_SUBST([GNULIB_FOPEN])
+  GNULIB_FREOPEN=0;              AC_SUBST([GNULIB_FREOPEN])
+  GNULIB_FSEEK=0;                AC_SUBST([GNULIB_FSEEK])
+  GNULIB_FSEEKO=0;               AC_SUBST([GNULIB_FSEEKO])
+  GNULIB_FTELL=0;                AC_SUBST([GNULIB_FTELL])
+  GNULIB_FTELLO=0;               AC_SUBST([GNULIB_FTELLO])
+  GNULIB_FFLUSH=0;               AC_SUBST([GNULIB_FFLUSH])
+  GNULIB_FPURGE=0;               AC_SUBST([GNULIB_FPURGE])
+  GNULIB_FCLOSE=0;               AC_SUBST([GNULIB_FCLOSE])
+  GNULIB_FPUTC=0;                AC_SUBST([GNULIB_FPUTC])
+  GNULIB_PUTC=0;                 AC_SUBST([GNULIB_PUTC])
+  GNULIB_PUTCHAR=0;              AC_SUBST([GNULIB_PUTCHAR])
+  GNULIB_FPUTS=0;                AC_SUBST([GNULIB_FPUTS])
+  GNULIB_PUTS=0;                 AC_SUBST([GNULIB_PUTS])
+  GNULIB_FWRITE=0;               AC_SUBST([GNULIB_FWRITE])
+  GNULIB_GETDELIM=0;             AC_SUBST([GNULIB_GETDELIM])
+  GNULIB_GETLINE=0;              AC_SUBST([GNULIB_GETLINE])
+  GNULIB_PERROR=0;               AC_SUBST([GNULIB_PERROR])
+  GNULIB_STDIO_H_SIGPIPE=0;      AC_SUBST([GNULIB_STDIO_H_SIGPIPE])
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  REPLACE_STDIO_WRITE_FUNCS=0;   AC_SUBST([REPLACE_STDIO_WRITE_FUNCS])
+  REPLACE_FPRINTF=0;             AC_SUBST([REPLACE_FPRINTF])
+  REPLACE_VFPRINTF=0;            AC_SUBST([REPLACE_VFPRINTF])
+  REPLACE_PRINTF=0;              AC_SUBST([REPLACE_PRINTF])
+  REPLACE_VPRINTF=0;             AC_SUBST([REPLACE_VPRINTF])
+  REPLACE_SNPRINTF=0;            AC_SUBST([REPLACE_SNPRINTF])
+  HAVE_DECL_SNPRINTF=1;          AC_SUBST([HAVE_DECL_SNPRINTF])
+  REPLACE_VSNPRINTF=0;           AC_SUBST([REPLACE_VSNPRINTF])
+  HAVE_DECL_VSNPRINTF=1;         AC_SUBST([HAVE_DECL_VSNPRINTF])
+  REPLACE_SPRINTF=0;             AC_SUBST([REPLACE_SPRINTF])
+  REPLACE_VSPRINTF=0;            AC_SUBST([REPLACE_VSPRINTF])
+  HAVE_DPRINTF=1;                AC_SUBST([HAVE_DPRINTF])
+  REPLACE_DPRINTF=0;             AC_SUBST([REPLACE_DPRINTF])
+  HAVE_VDPRINTF=1;               AC_SUBST([HAVE_VDPRINTF])
+  REPLACE_VDPRINTF=0;            AC_SUBST([REPLACE_VDPRINTF])
+  HAVE_VASPRINTF=1;              AC_SUBST([HAVE_VASPRINTF])
+  REPLACE_VASPRINTF=0;           AC_SUBST([REPLACE_VASPRINTF])
+  HAVE_DECL_OBSTACK_PRINTF=1;    AC_SUBST([HAVE_DECL_OBSTACK_PRINTF])
+  REPLACE_OBSTACK_PRINTF=0;      AC_SUBST([REPLACE_OBSTACK_PRINTF])
+  REPLACE_FOPEN=0;               AC_SUBST([REPLACE_FOPEN])
+  REPLACE_FREOPEN=0;             AC_SUBST([REPLACE_FREOPEN])
+  HAVE_FSEEKO=1;                 AC_SUBST([HAVE_FSEEKO])
+  REPLACE_FSEEKO=0;              AC_SUBST([REPLACE_FSEEKO])
+  REPLACE_FSEEK=0;               AC_SUBST([REPLACE_FSEEK])
+  HAVE_FTELLO=1;                 AC_SUBST([HAVE_FTELLO])
+  REPLACE_FTELLO=0;              AC_SUBST([REPLACE_FTELLO])
+  REPLACE_FTELL=0;               AC_SUBST([REPLACE_FTELL])
+  REPLACE_FFLUSH=0;              AC_SUBST([REPLACE_FFLUSH])
+  REPLACE_FPURGE=0;              AC_SUBST([REPLACE_FPURGE])
+  HAVE_DECL_FPURGE=1;            AC_SUBST([HAVE_DECL_FPURGE])
+  REPLACE_FCLOSE=0;              AC_SUBST([REPLACE_FCLOSE])
+  HAVE_DECL_GETDELIM=1;          AC_SUBST([HAVE_DECL_GETDELIM])
+  HAVE_DECL_GETLINE=1;           AC_SUBST([HAVE_DECL_GETLINE])
+  REPLACE_GETLINE=0;             AC_SUBST([REPLACE_GETLINE])
+  REPLACE_PERROR=0;              AC_SUBST([REPLACE_PERROR])
+])
+
+dnl Code shared by fseeko and ftello.  Determine if large files are supported,
+dnl but stdin does not start as a large file by default.
+AC_DEFUN([gl_STDIN_LARGE_OFFSET],
+  [
+    AC_CACHE_CHECK([whether stdin defaults to large file offsets],
+      [gl_cv_var_stdin_large_offset],
+      [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]],
+[[#if defined __SL64 && defined __SCLE /* cygwin */
+  /* Cygwin 1.5.24 and earlier fail to put stdin in 64-bit mode, making
+     fseeko/ftello needlessly fail.  This bug was fixed in 1.5.25, and
+     it is easier to do a version check than building a runtime test.  */
+# include <cygwin/version.h>
+# if CYGWIN_VERSION_DLL_COMBINED < CYGWIN_VERSION_DLL_MAKE_COMBINED (1005, 25)
+  choke me
+# endif
+#endif]])],
+       [gl_cv_var_stdin_large_offset=yes],
+       [gl_cv_var_stdin_large_offset=no])])
+])
diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4
new file mode 100644
index 0000000..3a1d1e0
--- /dev/null
+++ b/m4/vasnprintf.m4
@@ -0,0 +1,276 @@
+# vasnprintf.m4 serial 29
+dnl Copyright (C) 2002-2004, 2006-2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VASNPRINTF],
+[
+  AC_CHECK_FUNCS_ONCE([vasnprintf])
+  if test $ac_cv_func_vasnprintf = no; then
+    gl_REPLACE_VASNPRINTF
+  fi
+])
+
+AC_DEFUN([gl_REPLACE_VASNPRINTF],
+[
+  AC_CHECK_FUNCS_ONCE([vasnprintf])
+  AC_LIBOBJ([vasnprintf])
+  AC_LIBOBJ([printf-args])
+  AC_LIBOBJ([printf-parse])
+  AC_LIBOBJ([asnprintf])
+  if test $ac_cv_func_vasnprintf = yes; then
+    AC_DEFINE([REPLACE_VASNPRINTF], [1],
+      [Define if vasnprintf exists but is overridden by gnulib.])
+  fi
+  gl_PREREQ_PRINTF_ARGS
+  gl_PREREQ_PRINTF_PARSE
+  gl_PREREQ_VASNPRINTF
+  gl_PREREQ_ASNPRINTF
+])
+
+# Prequisites of lib/printf-args.h, lib/printf-args.c.
+AC_DEFUN([gl_PREREQ_PRINTF_ARGS],
+[
+  AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+  AC_REQUIRE([gt_TYPE_WCHAR_T])
+  AC_REQUIRE([gt_TYPE_WINT_T])
+])
+
+# Prequisites of lib/printf-parse.h, lib/printf-parse.c.
+AC_DEFUN([gl_PREREQ_PRINTF_PARSE],
+[
+  AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+  AC_REQUIRE([gt_TYPE_WCHAR_T])
+  AC_REQUIRE([gt_TYPE_WINT_T])
+  AC_REQUIRE([AC_TYPE_SIZE_T])
+  AC_CHECK_TYPE([ptrdiff_t], ,
+    [AC_DEFINE([ptrdiff_t], [long],
+       [Define as the type of the result of subtracting two pointers, if the 
system doesn't define it.])
+    ])
+  AC_REQUIRE([gt_AC_TYPE_INTMAX_T])
+])
+
+# Prerequisites of lib/vasnprintf.c.
+AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF],
+[
+  AC_REQUIRE([AC_FUNC_ALLOCA])
+  AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+  AC_REQUIRE([gt_TYPE_WCHAR_T])
+  AC_REQUIRE([gt_TYPE_WINT_T])
+  AC_CHECK_FUNCS([snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb])
+  dnl Use the _snprintf function only if it is declared (because on NetBSD it
+  dnl is defined as a weak alias of snprintf; we prefer to use the latter).
+  AC_CHECK_DECLS([_snprintf], , , [#include <stdio.h>])
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting 'long double'
+# arguments.
+AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF_LONG_DOUBLE],
+[
+  AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
+  case "$gl_cv_func_printf_long_double" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1],
+        [Define if the vasnprintf implementation needs special code for
+         'long double' arguments.])
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting infinite 'double'
+# arguments.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE],
+[
+  AC_REQUIRE([gl_PRINTF_INFINITE])
+  case "$gl_cv_func_printf_infinite" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_INFINITE_DOUBLE], [1],
+        [Define if the vasnprintf implementation needs special code for
+         infinite 'double' arguments.])
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting infinite 'long double'
+# arguments.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE],
+[
+  AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
+  dnl There is no need to set NEED_PRINTF_INFINITE_LONG_DOUBLE if
+  dnl NEED_PRINTF_LONG_DOUBLE is already set.
+  AC_REQUIRE([gl_PREREQ_VASNPRINTF_LONG_DOUBLE])
+  case "$gl_cv_func_printf_long_double" in
+    *yes)
+      case "$gl_cv_func_printf_infinite_long_double" in
+        *yes)
+          ;;
+        *)
+          AC_DEFINE([NEED_PRINTF_INFINITE_LONG_DOUBLE], [1],
+            [Define if the vasnprintf implementation needs special code for
+             infinite 'long double' arguments.])
+          ;;
+      esac
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting the 'a' directive.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_A],
+[
+  AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+  case "$gl_cv_func_printf_directive_a" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], [1],
+        [Define if the vasnprintf implementation needs special code for
+         the 'a' and 'A' directives.])
+      AC_CHECK_FUNCS([nl_langinfo])
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting the 'F' directive.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_F],
+[
+  AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
+  case "$gl_cv_func_printf_directive_f" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_DIRECTIVE_F], [1],
+        [Define if the vasnprintf implementation needs special code for
+         the 'F' directive.])
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting the 'ls' directive.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_LS],
+[
+  AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
+  case "$gl_cv_func_printf_directive_ls" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_DIRECTIVE_LS], [1],
+        [Define if the vasnprintf implementation needs special code for
+         the 'ls' directive.])
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting the ' flag.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING],
+[
+  AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
+  case "$gl_cv_func_printf_flag_grouping" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1],
+        [Define if the vasnprintf implementation needs special code for the
+         ' flag.])
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting the '-' flag.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST],
+[
+  AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
+  case "$gl_cv_func_printf_flag_leftadjust" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_FLAG_LEFTADJUST], [1],
+        [Define if the vasnprintf implementation needs special code for the
+         '-' flag.])
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting the 0 flag.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_ZERO],
+[
+  AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
+  case "$gl_cv_func_printf_flag_zero" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_FLAG_ZERO], [1],
+        [Define if the vasnprintf implementation needs special code for the
+         0 flag.])
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for supporting large precisions.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_PRECISION],
+[
+  AC_REQUIRE([gl_PRINTF_PRECISION])
+  case "$gl_cv_func_printf_precision" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_UNBOUNDED_PRECISION], [1],
+        [Define if the vasnprintf implementation needs special code for
+         supporting large precisions without arbitrary bounds.])
+      AC_DEFINE([NEED_PRINTF_DOUBLE], [1],
+        [Define if the vasnprintf implementation needs special code for
+         'double' arguments.])
+      AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1],
+        [Define if the vasnprintf implementation needs special code for
+         'long double' arguments.])
+      ;;
+  esac
+])
+
+# Extra prerequisites of lib/vasnprintf.c for surviving out-of-memory
+# conditions.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_ENOMEM],
+[
+  AC_REQUIRE([gl_PRINTF_ENOMEM])
+  case "$gl_cv_func_printf_enomem" in
+    *yes)
+      ;;
+    *)
+      AC_DEFINE([NEED_PRINTF_ENOMEM], [1],
+        [Define if the vasnprintf implementation needs special code for
+         surviving out-of-memory conditions.])
+      AC_DEFINE([NEED_PRINTF_DOUBLE], [1],
+        [Define if the vasnprintf implementation needs special code for
+         'double' arguments.])
+      AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1],
+        [Define if the vasnprintf implementation needs special code for
+         'long double' arguments.])
+      ;;
+  esac
+])
+
+# Prerequisites of lib/vasnprintf.c including all extras for POSIX compliance.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS],
+[
+  AC_REQUIRE([gl_PREREQ_VASNPRINTF])
+  gl_PREREQ_VASNPRINTF_LONG_DOUBLE
+  gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
+  gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
+  gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+  gl_PREREQ_VASNPRINTF_DIRECTIVE_F
+  gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
+  gl_PREREQ_VASNPRINTF_FLAG_GROUPING
+  gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
+  gl_PREREQ_VASNPRINTF_FLAG_ZERO
+  gl_PREREQ_VASNPRINTF_PRECISION
+  gl_PREREQ_VASNPRINTF_ENOMEM
+])
+
+# Prerequisites of lib/asnprintf.c.
+AC_DEFUN([gl_PREREQ_ASNPRINTF],
+[
+])
diff --git a/m4/vsnprintf.m4 b/m4/vsnprintf.m4
new file mode 100644
index 0000000..3b37d46
--- /dev/null
+++ b/m4/vsnprintf.m4
@@ -0,0 +1,40 @@
+# vsnprintf.m4 serial 5
+dnl Copyright (C) 2002-2004, 2007-2008 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VSNPRINTF],
+[
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  gl_cv_func_vsnprintf_usable=no
+  AC_CHECK_FUNCS([vsnprintf])
+  if test $ac_cv_func_vsnprintf = yes; then
+    gl_SNPRINTF_SIZE1
+    case "$gl_cv_func_snprintf_size1" in
+      *yes)
+        gl_cv_func_vsnprintf_usable=yes
+        ;;
+    esac
+  fi
+  if test $gl_cv_func_vsnprintf_usable = no; then
+    gl_REPLACE_VSNPRINTF
+  fi
+  AC_CHECK_DECLS_ONCE([vsnprintf])
+  if test $ac_cv_have_decl_vsnprintf = no; then
+    HAVE_DECL_VSNPRINTF=0
+  fi
+])
+
+AC_DEFUN([gl_REPLACE_VSNPRINTF],
+[
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  AC_LIBOBJ([vsnprintf])
+  if test $ac_cv_func_vsnprintf = yes; then
+    REPLACE_VSNPRINTF=1
+  fi
+  gl_PREREQ_VSNPRINTF
+])
+
+# Prerequisites of lib/vsnprintf.c.
+AC_DEFUN([gl_PREREQ_VSNPRINTF], [:])
diff --git a/m4/wchar_t.m4 b/m4/wchar_t.m4
new file mode 100644
index 0000000..fb27a7f
--- /dev/null
+++ b/m4/wchar_t.m4
@@ -0,0 +1,20 @@
+# wchar_t.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2002-2003, 2008, 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether <stddef.h> has the 'wchar_t' type.
+dnl Prerequisite: AC_PROG_CC
+
+AC_DEFUN([gt_TYPE_WCHAR_T],
+[
+  AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t],
+    [AC_TRY_COMPILE([#include <stddef.h>
+       wchar_t foo = (wchar_t)'\0';], ,
+       [gt_cv_c_wchar_t=yes], [gt_cv_c_wchar_t=no])])
+  if test $gt_cv_c_wchar_t = yes; then
+    AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.])
+  fi
+])
diff --git a/m4/xsize.m4 b/m4/xsize.m4
new file mode 100644
index 0000000..631893c
--- /dev/null
+++ b/m4/xsize.m4
@@ -0,0 +1,13 @@
+# xsize.m4 serial 4
+dnl Copyright (C) 2003-2004, 2008 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_XSIZE],
+[
+  dnl Prerequisites of lib/xsize.h.
+  AC_REQUIRE([gl_SIZE_MAX])
+  AC_REQUIRE([AC_C_INLINE])
+  AC_CHECK_HEADERS([stdint.h])
+])


hooks/post-receive
-- 
GNU Guile




reply via email to

[Prev in Thread] Current Thread [Next in Thread]