summaryrefslogtreecommitdiff
path: root/lgl
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2007-12-09 22:41:36 +0100
committerSimon Josefsson <simon@josefsson.org>2007-12-09 22:41:36 +0100
commit28d95172009ac844566e0dfdb63505832cbf05d9 (patch)
treefa11062be1df5e00405385d3b5cebd71b73ac1b4 /lgl
parent3d5af6621fb49e326be35b99cec8556d8c8315ca (diff)
downloadgnutls-28d95172009ac844566e0dfdb63505832cbf05d9.tar.gz
Update gnulib.
Diffstat (limited to 'lgl')
-rw-r--r--lgl/Makefile.am8
-rw-r--r--lgl/m4/gettext.m44
-rw-r--r--lgl/m4/gnulib-comp.m43
-rw-r--r--lgl/m4/iconv.m42
-rw-r--r--lgl/m4/intdiv0.m42
-rw-r--r--lgl/m4/intl.m420
-rw-r--r--lgl/m4/intlmacosx.m42
-rw-r--r--lgl/m4/intmax_t.m412
-rw-r--r--lgl/m4/lib-link.m42
-rw-r--r--lgl/m4/lock.m42
-rw-r--r--lgl/m4/longlong.m475
-rw-r--r--lgl/m4/po.m425
-rw-r--r--lgl/m4/printf-posix.m42
-rw-r--r--lgl/m4/stdio_h.m415
-rw-r--r--lgl/m4/stdlib_h.m44
-rw-r--r--lgl/m4/string_h.m42
-rw-r--r--lgl/m4/uintmax_t.m48
-rw-r--r--lgl/m4/ulonglong.m451
-rw-r--r--lgl/m4/unistd_h.m46
-rw-r--r--lgl/m4/vasnprintf.m452
-rw-r--r--lgl/m4/wint_t.m42
-rw-r--r--lgl/printf-parse.c23
-rw-r--r--lgl/realloc.c33
-rw-r--r--lgl/stdlib.in.h9
-rw-r--r--lgl/string.in.h45
-rw-r--r--lgl/unistd.in.h55
-rw-r--r--lgl/vasnprintf.c888
27 files changed, 1090 insertions, 262 deletions
diff --git a/lgl/Makefile.am b/lgl/Makefile.am
index c71919e1f6..af1d330ac0 100644
--- a/lgl/Makefile.am
+++ b/lgl/Makefile.am
@@ -423,12 +423,14 @@ stdlib.h: stdlib.in.h
-e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \
-e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \
-e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \
+ -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \
-e 's|@''HAVE_CALLOC_POSIX''@|$(HAVE_CALLOC_POSIX)|g' \
-e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \
-e 's|@''HAVE_MALLOC_POSIX''@|$(HAVE_MALLOC_POSIX)|g' \
-e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \
-e 's|@''HAVE_REALLOC_POSIX''@|$(HAVE_REALLOC_POSIX)|g' \
-e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+ -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
-e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
< $(srcdir)/stdlib.in.h; \
} > $@-t
@@ -483,8 +485,6 @@ string.h: string.in.h
-e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \
-e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \
-e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \
- -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \
- -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \
-e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \
-e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \
-e 's|@''HAVE_STRNDUP''@|$(HAVE_STRNDUP)|g' \
@@ -617,15 +617,19 @@ unistd.h: unistd.in.h
-e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \
-e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \
-e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \
+ -e 's|@''GNULIB_GETPAGESIZE''@|$(GNULIB_GETPAGESIZE)|g' \
-e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \
-e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \
-e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \
-e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \
-e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \
-e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \
+ -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
-e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \
-e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \
-e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \
+ -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \
+ -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \
-e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \
-e 's|@''REPLACE_FCHDIR''@|$(REPLACE_FCHDIR)|g' \
-e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \
diff --git a/lgl/m4/gettext.m4 b/lgl/m4/gettext.m4
index 7f3e4e283c..c9ae1f7de8 100644
--- a/lgl/m4/gettext.m4
+++ b/lgl/m4/gettext.m4
@@ -1,5 +1,5 @@
-# gettext.m4 serial 59a (gettext-0.16.1)
-dnl Copyright (C) 1995-2006 Free Software Foundation, Inc.
+# gettext.m4 serial 60 (gettext-0.17)
+dnl Copyright (C) 1995-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.
diff --git a/lgl/m4/gnulib-comp.m4 b/lgl/m4/gnulib-comp.m4
index 38c8f6c5f8..b6ade09e21 100644
--- a/lgl/m4/gnulib-comp.m4
+++ b/lgl/m4/gnulib-comp.m4
@@ -73,7 +73,7 @@ AC_DEFUN([lgl_INIT],
gl_MD2
gl_FLOAT_H
dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac.
- AM_GNU_GETTEXT_VERSION([0.16.1])
+ AM_GNU_GETTEXT_VERSION([0.17])
AC_SUBST([LIBINTL])
AC_SUBST([LTLIBINTL])
gl_FUNC_MEMMEM
@@ -300,7 +300,6 @@ AC_DEFUN([lgl_FILE_LIST], [
m4/time_h.m4
m4/time_r.m4
m4/uintmax_t.m4
- m4/ulonglong.m4
m4/unistd_h.m4
m4/vasnprintf.m4
m4/vasprintf.m4
diff --git a/lgl/m4/iconv.m4 b/lgl/m4/iconv.m4
index 8e36b52d4d..66bc76f48c 100644
--- a/lgl/m4/iconv.m4
+++ b/lgl/m4/iconv.m4
@@ -1,4 +1,4 @@
-# iconv.m4 serial AM6 (gettext-0.16.2)
+# iconv.m4 serial AM6 (gettext-0.17)
dnl Copyright (C) 2000-2002, 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,
diff --git a/lgl/m4/intdiv0.m4 b/lgl/m4/intdiv0.m4
index 534134ac33..8c8a67084f 100644
--- a/lgl/m4/intdiv0.m4
+++ b/lgl/m4/intdiv0.m4
@@ -1,4 +1,4 @@
-# intdiv0.m4 serial 2 (gettext-0.16.2)
+# intdiv0.m4 serial 2 (gettext-0.17)
dnl Copyright (C) 2002, 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,
diff --git a/lgl/m4/intl.m4 b/lgl/m4/intl.m4
index e0771d2a04..934408bb90 100644
--- a/lgl/m4/intl.m4
+++ b/lgl/m4/intl.m4
@@ -1,4 +1,4 @@
-# intl.m4 serial 5 (gettext-0.16.2)
+# intl.m4 serial 8 (gettext-0.17)
dnl Copyright (C) 1995-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,
@@ -97,7 +97,7 @@ AC_DEFUN([AM_INTL_SUBDIR],
dnl exported variables _also_ in the static library.
if test "$enable_shared" = yes; then
case "$host_os" in
- cygwin*) is_woe32dll=yes ;;
+ mingw* | cygwin*) is_woe32dll=yes ;;
*) is_woe32dll=no ;;
esac
else
@@ -119,6 +119,18 @@ AC_DEFUN([AM_INTL_SUBDIR],
AC_CHECK_TOOL([WINDRES], [windres])
fi
+ dnl Determine whether when creating a library, "-lc" should be passed to
+ dnl libtool or not. On many platforms, it is required for the libtool option
+ dnl -no-undefined to work. On HP-UX, however, the -lc - stored by libtool
+ dnl in the *.la files - makes it impossible to create multithreaded programs,
+ dnl because libtool also reorders the -lc to come before the -pthread, and
+ dnl this disables pthread_create() <http://docs.hp.com/en/1896/pthreads.html>.
+ case "$host_os" in
+ hpux*) LTLIBC="" ;;
+ *) LTLIBC="-lc" ;;
+ esac
+ AC_SUBST([LTLIBC])
+
dnl Rename some macros and functions used for locking.
AH_BOTTOM([
#define __libc_lock_t gl_lock_t
@@ -209,7 +221,9 @@ AC_DEFUN([gt_INTL_SUBDIR_CORE],
AC_CACHE_CHECK([for NL_LOCALE_NAME macro], gt_cv_nl_locale_name,
[AC_TRY_LINK([#include <langinfo.h>
#include <locale.h>],
- [char* cs = nl_langinfo(_NL_LOCALE_NAME(LC_MESSAGES));],
+ [char* cs = nl_langinfo(_NL_LOCALE_NAME(LC_MESSAGES));
+ return !cs;
+ ],
gt_cv_nl_locale_name=yes,
gt_cv_nl_locale_name=no)
])
diff --git a/lgl/m4/intlmacosx.m4 b/lgl/m4/intlmacosx.m4
index 6019bbfa24..d3f0d904d2 100644
--- a/lgl/m4/intlmacosx.m4
+++ b/lgl/m4/intlmacosx.m4
@@ -1,4 +1,4 @@
-# intlmacosx.m4 serial 1 (gettext-0.16.2)
+# intlmacosx.m4 serial 1 (gettext-0.17)
dnl Copyright (C) 2004-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,
diff --git a/lgl/m4/intmax_t.m4 b/lgl/m4/intmax_t.m4
index 17c7b0ae88..50ae35d223 100644
--- a/lgl/m4/intmax_t.m4
+++ b/lgl/m4/intmax_t.m4
@@ -1,5 +1,5 @@
-# intmax_t.m4 serial 5
-dnl Copyright (C) 1997-2004, 2006 Free Software Foundation, Inc.
+# intmax_t.m4 serial 6
+dnl Copyright (C) 1997-2004, 2006-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.
@@ -18,8 +18,8 @@ AC_DEFUN([gl_AC_TYPE_INTMAX_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([gl_AC_TYPE_LONG_LONG])
- test $ac_cv_type_long_long = yes \
+ 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,
@@ -51,8 +51,8 @@ AC_DEFUN([gt_AC_TYPE_INTMAX_T],
AC_DEFINE(HAVE_INTMAX_T, 1,
[Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>.])
else
- AC_REQUIRE([gl_AC_TYPE_LONG_LONG])
- test $ac_cv_type_long_long = yes \
+ 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,
diff --git a/lgl/m4/lib-link.m4 b/lgl/m4/lib-link.m4
index f157d983da..e3d26fc42d 100644
--- a/lgl/m4/lib-link.m4
+++ b/lgl/m4/lib-link.m4
@@ -1,4 +1,4 @@
-# lib-link.m4 serial 13 (gettext-0.16.2)
+# lib-link.m4 serial 13 (gettext-0.17)
dnl Copyright (C) 2001-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,
diff --git a/lgl/m4/lock.m4 b/lgl/m4/lock.m4
index 4cc585ea2e..9111933535 100644
--- a/lgl/m4/lock.m4
+++ b/lgl/m4/lock.m4
@@ -1,4 +1,4 @@
-# lock.m4 serial 7 (gettext-0.16.2)
+# lock.m4 serial 7 (gettext-0.17)
dnl Copyright (C) 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,
diff --git a/lgl/m4/longlong.m4 b/lgl/m4/longlong.m4
index 5799c3965a..15bf9dacad 100644
--- a/lgl/m4/longlong.m4
+++ b/lgl/m4/longlong.m4
@@ -1,4 +1,4 @@
-# longlong.m4 serial 11
+# longlong.m4 serial 13
dnl Copyright (C) 1999-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,
@@ -18,23 +18,11 @@ AC_DEFUN([AC_TYPE_LONG_LONG_INT],
[
AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int],
[AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[#if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
- error in preprocessor;
- #endif
- long long int ll = 9223372036854775807ll;
- long long int nll = -9223372036854775807LL;
- typedef int a[((-9223372036854775807LL < 0
- && 0 < 9223372036854775807ll)
- ? 1 : -1)];
- int i = 63;]],
- [[long long int llmax = 9223372036854775807ll;
- return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
- | (llmax / ll) | (llmax % ll));]])],
+ [_AC_TYPE_LONG_LONG_SNIPPET],
[dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004.
dnl If cross compiling, assume the bug isn't important, since
dnl nobody cross compiles for this platform as far as we know.
- AC_RUN_IFELSE(
+ AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[@%:@include <limits.h>
@%:@ifndef LLONG_MAX
@@ -63,13 +51,56 @@ AC_DEFUN([AC_TYPE_LONG_LONG_INT],
fi
])
-# This macro is obsolescent and should go away soon.
-AC_DEFUN([gl_AC_TYPE_LONG_LONG],
+# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
+# This fixes a bug in Autoconf 2.61, but can be removed once we
+# assume 2.62 everywhere.
+
+# Note: If the type 'unsigned long long int' exists but is only 32 bits
+# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
+# will not be defined. In this case you can treat 'unsigned long long int'
+# like 'unsigned long int'.
+
+AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
[
- AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
- ac_cv_type_long_long=$ac_cv_type_long_long_int
- if test $ac_cv_type_long_long = yes; then
- AC_DEFINE(HAVE_LONG_LONG, 1,
- [Define if you have the 'long long' type.])
+ AC_CACHE_CHECK([for unsigned long long int],
+ [ac_cv_type_unsigned_long_long_int],
+ [AC_LINK_IFELSE(
+ [_AC_TYPE_LONG_LONG_SNIPPET],
+ [ac_cv_type_unsigned_long_long_int=yes],
+ [ac_cv_type_unsigned_long_long_int=no])])
+ if test $ac_cv_type_unsigned_long_long_int = yes; then
+ AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1,
+ [Define to 1 if the system has the type `unsigned long long int'.])
fi
])
+
+# Expands to a C program that can be used to test for simultaneous support
+# of 'long long' and 'unsigned long long'. We don't want to say that
+# 'long long' is available if 'unsigned long long' is not, or vice versa,
+# because too many programs rely on the symmetry between signed and unsigned
+# integer types (excluding 'bool').
+AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
+[
+ AC_LANG_PROGRAM(
+ [[/* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;]],
+ [[/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));]])
+])
diff --git a/lgl/m4/po.m4 b/lgl/m4/po.m4
index 00133ef36f..0734762ab1 100644
--- a/lgl/m4/po.m4
+++ b/lgl/m4/po.m4
@@ -1,5 +1,5 @@
-# po.m4 serial 13 (gettext-0.15)
-dnl Copyright (C) 1995-2006 Free Software Foundation, Inc.
+# po.m4 serial 15 (gettext-0.17)
+dnl Copyright (C) 1995-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.
@@ -27,6 +27,10 @@ AC_DEFUN([AM_PO_SUBDIRS],
AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
AC_REQUIRE([AM_NLS])dnl
+ dnl Release version of the gettext macros. This is used to ensure that
+ dnl the gettext macros and po/Makefile.in.in are in sync.
+ AC_SUBST([GETTEXT_MACRO_VERSION], [0.17])
+
dnl Perform the following tests also if --disable-nls has been given,
dnl because they are needed for "make dist" to work.
@@ -84,6 +88,10 @@ changequote([,])dnl
test -n "$localedir" || localedir='${datadir}/locale'
AC_SUBST([localedir])
+ dnl Support for AM_XGETTEXT_OPTION.
+ test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
+ AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
+
AC_CONFIG_COMMANDS([po-directories], [[
for ac_file in $CONFIG_FILES; do
# Support "outfile[:infile[:infile...]]"
@@ -426,3 +434,16 @@ EOF
fi
mv "$ac_file.tmp" "$ac_file"
])
+
+dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
+AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
+[
+ XGETTEXT_EXTRA_OPTIONS=
+])
+
+dnl Registers an option to be passed to xgettext in the po subdirectory.
+AC_DEFUN([AM_XGETTEXT_OPTION],
+[
+ AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
+ XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
+])
diff --git a/lgl/m4/printf-posix.m4 b/lgl/m4/printf-posix.m4
index 33e387c6f9..14ba612839 100644
--- a/lgl/m4/printf-posix.m4
+++ b/lgl/m4/printf-posix.m4
@@ -1,4 +1,4 @@
-# printf-posix.m4 serial 3 (gettext-0.16.2)
+# printf-posix.m4 serial 3 (gettext-0.17)
dnl Copyright (C) 2003, 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,
diff --git a/lgl/m4/stdio_h.m4 b/lgl/m4/stdio_h.m4
index 45e54e2a62..a40d418041 100644
--- a/lgl/m4/stdio_h.m4
+++ b/lgl/m4/stdio_h.m4
@@ -1,4 +1,4 @@
-# stdio_h.m4 serial 8
+# stdio_h.m4 serial 9
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,
@@ -73,13 +73,12 @@ AC_DEFUN([gl_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 at the same time
- that cygwin started exporting asnprintf (cygwin 1.7.0), so we use
- that as a link-time test for cross-compiles rather than building
- a runtime test. */
- size_t s;
- if (asnprintf (NULL, &s, ""))
- return 0;
+ 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/lgl/m4/stdlib_h.m4 b/lgl/m4/stdlib_h.m4
index ea9286ef46..278df744c7 100644
--- a/lgl/m4/stdlib_h.m4
+++ b/lgl/m4/stdlib_h.m4
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 3
+# stdlib_h.m4 serial 4
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,
@@ -25,6 +25,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT])
GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP])
GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP])
+ GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_CALLOC_POSIX=1; AC_SUBST([HAVE_CALLOC_POSIX])
HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT])
@@ -32,4 +33,5 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
HAVE_MKDTEMP=1; AC_SUBST([HAVE_MKDTEMP])
HAVE_REALLOC_POSIX=1; AC_SUBST([HAVE_REALLOC_POSIX])
REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP])
+ REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV])
])
diff --git a/lgl/m4/string_h.m4 b/lgl/m4/string_h.m4
index d811e26b88..83711799a1 100644
--- a/lgl/m4/string_h.m4
+++ b/lgl/m4/string_h.m4
@@ -64,8 +64,6 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
HAVE_DECL_MEMRCHR=1; AC_SUBST([HAVE_DECL_MEMRCHR])
HAVE_STPCPY=1; AC_SUBST([HAVE_STPCPY])
HAVE_STPNCPY=1; AC_SUBST([HAVE_STPNCPY])
- HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP])
- HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP])
HAVE_STRCHRNUL=1; AC_SUBST([HAVE_STRCHRNUL])
HAVE_DECL_STRDUP=1; AC_SUBST([HAVE_DECL_STRDUP])
HAVE_STRNDUP=1; AC_SUBST([HAVE_STRNDUP])
diff --git a/lgl/m4/uintmax_t.m4 b/lgl/m4/uintmax_t.m4
index bf83ed7464..641c4898d3 100644
--- a/lgl/m4/uintmax_t.m4
+++ b/lgl/m4/uintmax_t.m4
@@ -1,5 +1,5 @@
-# uintmax_t.m4 serial 9
-dnl Copyright (C) 1997-2004 Free Software Foundation, Inc.
+# uintmax_t.m4 serial 10
+dnl Copyright (C) 1997-2004, 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.
@@ -16,8 +16,8 @@ AC_DEFUN([gl_AC_TYPE_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([gl_AC_TYPE_UNSIGNED_LONG_LONG])
- test $ac_cv_type_unsigned_long_long = yes \
+ AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
+ test $ac_cv_type_unsigned_long_long_int = yes \
&& ac_type='unsigned long long' \
|| ac_type='unsigned long'
AC_DEFINE_UNQUOTED(uintmax_t, $ac_type,
diff --git a/lgl/m4/ulonglong.m4 b/lgl/m4/ulonglong.m4
deleted file mode 100644
index 34f06e4c95..0000000000
--- a/lgl/m4/ulonglong.m4
+++ /dev/null
@@ -1,51 +0,0 @@
-# ulonglong.m4 serial 8
-dnl Copyright (C) 1999-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.
-
-dnl From Paul Eggert.
-
-# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
-# This fixes a bug in Autoconf 2.61, but can be removed once we
-# assume 2.62 everywhere.
-
-# Note: If the type 'unsigned long long int' exists but is only 32 bits
-# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
-# will not be defined. In this case you can treat 'unsigned long long int'
-# like 'unsigned long int'.
-
-AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
-[
- AC_CACHE_CHECK([for unsigned long long int],
- [ac_cv_type_unsigned_long_long_int],
- [AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[#if ! (18446744073709551615ULL <= -1ull)
- error in preprocessor;
- #endif
- unsigned long long int ull = 18446744073709551615ULL;
- typedef int a[(18446744073709551615ULL <= (unsigned long long int) -1
- ? 1 : -1)];
- int i = 63;]],
- [[unsigned long long int ullmax = 18446744073709551615ull;
- return (ull << 63 | ull >> 63 | ull << i | ull >> i
- | ullmax / ull | ullmax % ull);]])],
- [ac_cv_type_unsigned_long_long_int=yes],
- [ac_cv_type_unsigned_long_long_int=no])])
- if test $ac_cv_type_unsigned_long_long_int = yes; then
- AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1,
- [Define to 1 if the system has the type `unsigned long long int'.])
- fi
-])
-
-# This macro is obsolescent and should go away soon.
-AC_DEFUN([gl_AC_TYPE_UNSIGNED_LONG_LONG],
-[
- AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
- ac_cv_type_unsigned_long_long=$ac_cv_type_unsigned_long_long_int
- if test $ac_cv_type_unsigned_long_long = yes; then
- AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1,
- [Define if you have the 'unsigned long long' type.])
- fi
-])
diff --git a/lgl/m4/unistd_h.m4 b/lgl/m4/unistd_h.m4
index b12f84e8ec..91c02e7c83 100644
--- a/lgl/m4/unistd_h.m4
+++ b/lgl/m4/unistd_h.m4
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 9
+# unistd_h.m4 serial 10
dnl Copyright (C) 2006-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,
@@ -38,6 +38,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE])
GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD])
GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R])
+ GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE])
GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN])
GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK])
GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK])
@@ -45,9 +46,12 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_DUP2=1; AC_SUBST([HAVE_DUP2])
HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE])
+ HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE])
HAVE_READLINK=1; AC_SUBST([HAVE_READLINK])
HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP])
HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R])
+ HAVE_OS_H=0; AC_SUBST([HAVE_OS_H])
+ HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H])
REPLACE_CHOWN=0; AC_SUBST([REPLACE_CHOWN])
REPLACE_FCHDIR=0; AC_SUBST([REPLACE_FCHDIR])
REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD])
diff --git a/lgl/m4/vasnprintf.m4 b/lgl/m4/vasnprintf.m4
index ef2de787f0..6449a9c57f 100644
--- a/lgl/m4/vasnprintf.m4
+++ b/lgl/m4/vasnprintf.m4
@@ -1,4 +1,4 @@
-# vasnprintf.m4 serial 20
+# vasnprintf.m4 serial 23
dnl Copyright (C) 2002-2004, 2006-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,
@@ -45,7 +45,10 @@ AC_DEFUN([gl_PREREQ_PRINTF_PARSE],
AC_REQUIRE([gt_TYPE_WCHAR_T])
AC_REQUIRE([gt_TYPE_WINT_T])
AC_REQUIRE([AC_TYPE_SIZE_T])
- AC_CHECK_TYPES(ptrdiff_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])
])
@@ -178,6 +181,49 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_ZERO],
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],
[
@@ -189,6 +235,8 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS],
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
gl_PREREQ_VASNPRINTF_FLAG_ZERO
+ gl_PREREQ_VASNPRINTF_PRECISION
+ gl_PREREQ_VASNPRINTF_ENOMEM
])
# Prerequisites of lib/asnprintf.c.
diff --git a/lgl/m4/wint_t.m4 b/lgl/m4/wint_t.m4
index 2cac1a7108..af5ed936cc 100644
--- a/lgl/m4/wint_t.m4
+++ b/lgl/m4/wint_t.m4
@@ -1,4 +1,4 @@
-# wint_t.m4 serial 2 (gettext-0.16.2)
+# wint_t.m4 serial 2 (gettext-0.17)
dnl Copyright (C) 2003, 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,
diff --git a/lgl/printf-parse.c b/lgl/printf-parse.c
index 0b75c2860d..94c6c61328 100644
--- a/lgl/printf-parse.c
+++ b/lgl/printf-parse.c
@@ -63,6 +63,9 @@
/* malloc(), realloc(), free(). */
#include <stdlib.h>
+/* errno. */
+#include <errno.h>
+
/* Checked size_t computations. */
#include "xsize.h"
@@ -89,7 +92,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
if (d->dir == NULL)
/* Out of memory. */
- return -1;
+ goto out_of_memory_1;
a->count = 0;
a_allocated = 0;
@@ -109,13 +112,13 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
memory_size = xtimes (a_allocated, sizeof (argument)); \
if (size_overflow_p (memory_size)) \
/* Overflow, would lead to out of memory. */ \
- goto error; \
+ goto out_of_memory; \
memory = (argument *) (a->arg \
? realloc (a->arg, memory_size) \
: malloc (memory_size)); \
if (memory == NULL) \
/* Out of memory. */ \
- goto error; \
+ goto out_of_memory; \
a->arg = memory; \
} \
while (a->count <= n) \
@@ -539,11 +542,11 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
if (size_overflow_p (memory_size))
/* Overflow, would lead to out of memory. */
- goto error;
+ goto out_of_memory;
memory = (DIRECTIVE *) realloc (d->dir, memory_size);
if (memory == NULL)
/* Out of memory. */
- goto error;
+ goto out_of_memory;
d->dir = memory;
}
}
@@ -566,6 +569,16 @@ error:
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;
}
diff --git a/lgl/realloc.c b/lgl/realloc.c
index 4f6cddf537..64b7d78c57 100644
--- a/lgl/realloc.c
+++ b/lgl/realloc.c
@@ -18,18 +18,32 @@
/* written by Jim Meyering and Bruno Haible */
#include <config.h>
+
/* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h. */
#ifdef realloc
-# define NEED_REALLOC_GNU
-# undef realloc
+# define NEED_REALLOC_GNU 1
+#endif
+
+/* Infer the properties of the system's malloc function.
+ Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */
+#if GNULIB_MALLOC_GNU && !defined malloc
+# define SYSTEM_MALLOC_GLIBC_COMPATIBLE 1
#endif
+/* Below we want to call the system's malloc and realloc.
+ Undefine the symbols here so that including <stdlib.h> provides a
+ declaration of malloc(), not of rpl_malloc(), and likewise for realloc. */
+#undef malloc
+#undef realloc
+
/* Specification. */
#include <stdlib.h>
#include <errno.h>
-/* Call the system's malloc and realloc below. */
+/* Below we want to call the system's malloc and realloc.
+ Undefine the symbols, if they were defined by gnulib's <stdlib.h>
+ replacement. */
#undef malloc
#undef realloc
@@ -42,7 +56,7 @@ rpl_realloc (void *p, size_t n)
{
void *result;
-#ifdef NEED_REALLOC_GNU
+#if NEED_REALLOC_GNU
if (n == 0)
{
n = 1;
@@ -53,7 +67,16 @@ rpl_realloc (void *p, size_t n)
}
#endif
- result = (p == NULL ? malloc (n) : realloc (p, n));
+ if (p == NULL)
+ {
+#if GNULIB_REALLOC_GNU && !NEED_REALLOC_GNU && !SYSTEM_MALLOC_GLIBC_COMPATIBLE
+ if (n == 0)
+ n = 1;
+#endif
+ result = malloc (n);
+ }
+ else
+ result = realloc (p, n);
#if !HAVE_REALLOC_POSIX
if (result == NULL)
diff --git a/lgl/stdlib.in.h b/lgl/stdlib.in.h
index 7d46562414..baebcce973 100644
--- a/lgl/stdlib.in.h
+++ b/lgl/stdlib.in.h
@@ -167,6 +167,15 @@ extern int mkstemp (char * /*template*/);
#endif
+#if @GNULIB_PUTENV@
+# if @REPLACE_PUTENV@
+# undef putenv
+# define putenv rpl_putenv
+extern int putenv (char *string);
+# endif
+#endif
+
+
#ifdef __cplusplus
}
#endif
diff --git a/lgl/string.in.h b/lgl/string.in.h
index f458f4400d..a371e5c696 100644
--- a/lgl/string.in.h
+++ b/lgl/string.in.h
@@ -32,6 +32,7 @@
extern "C" {
#endif
+
/* Return the first occurrence of NEEDLE in HAYSTACK. */
#if @GNULIB_MEMMEM@
# if ! @HAVE_DECL_MEMMEM@
@@ -103,50 +104,6 @@ extern char *stpncpy (char *restrict __dst, char const *restrict __src,
stpncpy (a, b, n))
#endif
-/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
- greater than zero if S1 is lexicographically less than, equal to or greater
- than S2.
- Note: This function does not work in multibyte locales. */
-#if ! @HAVE_STRCASECMP@
-extern int strcasecmp (char const *s1, char const *s2);
-#endif
-#if defined GNULIB_POSIXCHECK
-/* strcasecmp() does not work with multibyte strings:
- POSIX says that it operates on "strings", and "string" in POSIX is defined
- as a sequence of bytes, not of characters. */
-# undef strcasecmp
-# define strcasecmp(a,b) \
- (GL_LINK_WARNING ("strcasecmp cannot work correctly on character strings " \
- "in multibyte locales - " \
- "use mbscasecmp if you care about " \
- "internationalization, or use c_strcasecmp (from " \
- "gnulib module c-strcase) if you want a locale " \
- "independent function"), \
- strcasecmp (a, b))
-#endif
-
-/* Compare no more than N bytes of strings S1 and S2, ignoring case,
- returning less than, equal to or greater than zero if S1 is
- lexicographically less than, equal to or greater than S2.
- Note: This function cannot work correctly in multibyte locales. */
-#if ! @HAVE_DECL_STRNCASECMP@
-extern int strncasecmp (char const *s1, char const *s2, size_t n);
-#endif
-#if defined GNULIB_POSIXCHECK
-/* strncasecmp() does not work with multibyte strings:
- POSIX says that it operates on "strings", and "string" in POSIX is defined
- as a sequence of bytes, not of characters. */
-# undef strncasecmp
-# define strncasecmp(a,b,n) \
- (GL_LINK_WARNING ("strncasecmp cannot work correctly on character " \
- "strings in multibyte locales - " \
- "use mbsncasecmp or mbspcasecmp if you care about " \
- "internationalization, or use c_strncasecmp (from " \
- "gnulib module c-strcase) if you want a locale " \
- "independent function"), \
- strncasecmp (a, b, n))
-#endif
-
#if defined GNULIB_POSIXCHECK
/* strchr() does not work with multibyte strings if the locale encoding is
GB18030 and the character to be searched is a digit. */
diff --git a/lgl/unistd.in.h b/lgl/unistd.in.h
index 5405baf881..4916f75ced 100644
--- a/lgl/unistd.in.h
+++ b/lgl/unistd.in.h
@@ -180,6 +180,61 @@ extern int getlogin_r (char *name, size_t size);
#endif
+#if @GNULIB_GETPAGESIZE@
+# if !@HAVE_GETPAGESIZE@
+/* This is for POSIX systems. */
+# if !defined getpagesize && defined _SC_PAGESIZE
+# if ! (defined __VMS && __VMS_VER < 70000000)
+# define getpagesize() sysconf (_SC_PAGESIZE)
+# endif
+# endif
+/* This is for older VMS. */
+# if !defined getpagesize && defined __VMS
+# ifdef __ALPHA
+# define getpagesize() 8192
+# else
+# define getpagesize() 512
+# endif
+# endif
+/* This is for BeOS. */
+# if !defined getpagesize && @HAVE_OS_H@
+# include <OS.h>
+# if defined B_PAGE_SIZE
+# define getpagesize() B_PAGE_SIZE
+# endif
+# endif
+/* This is for AmigaOS4.0. */
+# if !defined getpagesize && defined __amigaos4__
+# define getpagesize() 2048
+# endif
+/* This is for older Unix systems. */
+# if !defined getpagesize && @HAVE_SYS_PARAM_H@
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else
+# ifdef NBPG
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif
+# define getpagesize() (NBPG * CLSIZE)
+# else
+# ifdef NBPC
+# define getpagesize() NBPC
+# endif
+# endif
+# endif
+# endif
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef getpagesize
+# define getpagesize() \
+ (GL_LINK_WARNING ("getpagesize is unportable - " \
+ "use gnulib module getpagesize for portability"), \
+ getpagesize ())
+#endif
+
+
#if @GNULIB_LCHOWN@
# if @REPLACE_LCHOWN@
/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE
diff --git a/lgl/vasnprintf.c b/lgl/vasnprintf.c
index ee7c319023..6c8d5dcbdc 100644
--- a/lgl/vasnprintf.c
+++ b/lgl/vasnprintf.c
@@ -88,27 +88,30 @@
/* Checked size_t computations. */
#include "xsize.h"
-#if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
+#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
# include <math.h>
# include "float+.h"
-# include "fpucw.h"
#endif
-#if NEED_PRINTF_INFINITE_DOUBLE && !defined IN_LIBINTL
+#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
# include <math.h>
# include "isnan.h"
#endif
-#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !defined IN_LIBINTL
+#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 && !defined IN_LIBINTL
+#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
# include <math.h>
# include "isnan.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"
@@ -200,7 +203,7 @@ local_wcslen (const wchar_t *s)
/* Here we need to call the native sprintf, not rpl_sprintf. */
#undef sprintf
-#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
+#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_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
@@ -227,7 +230,7 @@ decimal_point_char ()
# endif
#endif
-#if NEED_PRINTF_INFINITE_DOUBLE && !defined IN_LIBINTL
+#if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
static int
@@ -238,7 +241,7 @@ is_infinite_or_zero (double x)
#endif
-#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !defined IN_LIBINTL
+#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
/* Equivalent to !isfinite(x), but does not require libm. */
static int
@@ -249,7 +252,7 @@ is_infinitel (long double x)
#endif
-#if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
+#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
@@ -795,6 +798,8 @@ convert_to_decimal (mpn_t a, size_t extra_zeroes)
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
@@ -823,8 +828,8 @@ decode_long_double (long double x, int *ep, mpn_t *mp)
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
+# 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));
@@ -839,7 +844,7 @@ decode_long_double (long double x, int *ep, mpn_t *mp)
abort ();
m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
}
-# else
+# else
{
mp_limb_t d;
y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
@@ -849,8 +854,8 @@ decode_long_double (long double x, int *ep, mpn_t *mp)
abort ();
m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
}
+# endif
# endif
-# endif
for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
{
mp_limb_t hi, lo;
@@ -866,8 +871,11 @@ decode_long_double (long double x, int *ep, mpn_t *mp)
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--;
@@ -876,17 +884,101 @@ decode_long_double (long double x, int *ep, mpn_t *mp)
return m.limbs;
}
-/* Assuming x is finite and >= 0, and n is an integer:
+# 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_long_double (long double x, int n)
+scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
{
- int e;
- mpn_t m;
- void *memory = decode_long_double (x, &e, &m);
int s;
size_t extra_zeroes;
unsigned int abs_n;
@@ -1066,7 +1158,7 @@ scale10_round_decimal_long_double (long double x, int n)
size_t count;
for (count = m.nlimbs; count > 0; count--)
{
- accu += (mp_twolimb_t) *sourceptr++ << s;
+ accu += (mp_twolimb_t) *sourceptr++ << s_bits;
*destptr++ = (mp_limb_t) accu;
accu = accu >> GMP_LIMB_BITS;
}
@@ -1099,6 +1191,44 @@ scale10_round_decimal_long_double (long double x, int n)
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;
+ 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;
+ 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. */
@@ -1186,6 +1316,99 @@ floorlog10l (long double x)
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;
+ /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
+ Four terms are enough to get an approximation with error < 10^-7. */
+ l -= 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
+
#endif
DCHAR_T *
@@ -1196,10 +1419,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
arguments a;
if (PRINTF_PARSE (format, &d, &a) < 0)
- {
- errno = EINVAL;
- return NULL;
- }
+ /* errno is already set. */
+ return NULL;
#define CLEANUP() \
free (d.dir); \
@@ -1819,8 +2040,19 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
#endif
-#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
- else if (dp->conversion == 'a' || dp->conversion == 'A')
+#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;
@@ -1938,6 +2170,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
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))
@@ -2057,7 +2290,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
*p++ = dp->conversion - 'A' + 'P';
-# if WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
{
static const wchar_t decimal_format[] =
{ '%', '+', 'd', '\0' };
@@ -2065,7 +2298,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
while (*p != '\0')
p++;
-# else
+# else
if (sizeof (DCHAR_T) == 1)
{
sprintf ((char *) p, "%+d", exponent);
@@ -2080,14 +2313,18 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
for (ep = expbuf; (*p = *ep) != '\0'; ep++)
p++;
}
-# endif
+# 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 (isnan (arg))
@@ -2204,7 +2441,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
*p++ = dp->conversion - 'A' + 'P';
-# if WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
{
static const wchar_t decimal_format[] =
{ '%', '+', 'd', '\0' };
@@ -2212,7 +2449,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
while (*p != '\0')
p++;
-# else
+# else
if (sizeof (DCHAR_T) == 1)
{
sprintf ((char *) p, "%+d", exponent);
@@ -2227,9 +2464,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
for (ep = expbuf; (*p = *ep) != '\0'; ep++)
p++;
}
-# endif
+# endif
}
}
+# else
+ abort ();
+# endif
}
/* The generated string now extends from tmp to p, with the
zero padding insertion point being at pad_ptr. */
@@ -2292,13 +2532,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
#endif
-#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
+#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_INFINITE_DOUBLE
+# 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.
@@ -2315,7 +2557,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
# endif
))
{
-# if NEED_PRINTF_INFINITE_DOUBLE && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
+# 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;
@@ -2398,17 +2640,21 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
precision = 6;
/* Allocate a temporary buffer of sufficient size. */
-# if NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
+# 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_INFINITE_DOUBLE
+# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
if (type == TYPE_LONGDOUBLE)
# endif
if (dp->conversion == 'f' || dp->conversion == 'F')
@@ -2423,6 +2669,22 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
# 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 (!(isnan (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);
@@ -2450,7 +2712,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
p = tmp;
# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
-# if NEED_PRINTF_INFINITE_DOUBLE
+# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
if (type == TYPE_LONGDOUBLE)
# endif
{
@@ -2810,13 +3072,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
END_LONG_DOUBLE_ROUNDING ();
}
}
-# if NEED_PRINTF_INFINITE_DOUBLE
+# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
else
# endif
# endif
-# if NEED_PRINTF_INFINITE_DOUBLE
+# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
{
- /* Simpler than above: handle only NaN, Infinity, zero. */
double arg = a.arg[dp->arg_index].a.a_double;
if (isnan (arg))
@@ -2834,7 +3095,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
int sign = 0;
- if (signbit (arg)) /* arg < 0.0L or negative zero */
+ if (signbit (arg)) /* arg < 0.0 or negative zero */
{
sign = -1;
arg = -arg;
@@ -2860,6 +3121,332 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
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. */
+ *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. */
+
+ /* 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 ();
@@ -2888,9 +3475,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
*p++ = '+';
/* Produce the same number of exponent digits as
the native printf implementation. */
-# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
*p++ = '0';
-# endif
+# endif
*p++ = '0';
*p++ = '0';
}
@@ -2908,6 +3495,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
else
abort ();
+# endif
}
}
}
@@ -2978,11 +3566,20 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
arg_type type = a.arg[dp->arg_index].type;
int flags = dp->flags;
-#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO
+#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
int has_width;
size_t width;
#endif
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO
+#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 !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
int pad_ourselves;
#else
# define pad_ourselves 0
@@ -2996,7 +3593,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
TCHAR_T *tmp;
#endif
-#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO
+#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
has_width = 0;
width = 0;
if (dp->width_start != dp->width_end)
@@ -3030,34 +3627,42 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
#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
+
#if !USE_SNPRINTF
/* Allocate a temporary buffer of sufficient size for calling
sprintf. */
{
- size_t precision;
-
- 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;
- precision = (arg < 0 ? 0 : arg);
- }
- else
- {
- const FCHAR_T *digitp = dp->precision_start + 1;
-
- precision = 0;
- while (digitp != dp->precision_end)
- precision = xsum (xtimes (precision, 10), *digitp++ - '0');
- }
- }
-
switch (dp->conversion)
{
@@ -3262,8 +3867,23 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
#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 !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO
+#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
switch (dp->conversion)
{
# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
@@ -3280,7 +3900,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
pad_ourselves = 1;
break;
default:
- pad_ourselves = 0;
+ pad_ourselves = prec_ourselves;
break;
}
#endif
@@ -3328,22 +3948,25 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
}
- if (dp->precision_start != dp->precision_end)
+ if (!prec_ourselves)
{
- 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))
+ if (dp->precision_start != dp->precision_end)
{
- 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);
+ 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);
+ }
}
}
@@ -3426,9 +4049,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
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. */
- ENSURE_ALLOCATION (xsum (length, 1));
*(TCHAR_T *) (result + length) = '\0';
#endif
@@ -3660,8 +4287,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
#if USE_SNPRINTF
- /* Handle overflow of the allocated buffer. */
- if (count >= maxlen)
+ /* 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.
@@ -3670,13 +4301,19 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
goto overflow;
else
{
- /* Need at least count * sizeof (TCHAR_T) bytes.
- But allocate proportionally, to avoid looping
+ /* 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,
- (count + TCHARS_PER_DCHAR - 1)
+ ((unsigned int) count + 2
+ + TCHARS_PER_DCHAR - 1)
/ TCHARS_PER_DCHAR),
xtimes (allocated, 2));
@@ -3686,6 +4323,69 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
#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 !DCHAR_IS_TCHAR
# if !USE_SNPRINTF
if (count >= tmp_length)
@@ -3794,7 +4494,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* Here count <= allocated - length. */
/* Perform padding. */
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO
+#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
if (pad_ourselves && has_width)
{
size_t w;
@@ -3978,9 +4678,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#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