summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-01-08 17:20:28 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2011-01-08 17:20:28 -0800
commita451f14b09368f4b9f96d61ddb2ee69ac048c414 (patch)
treed4076c67607428c2bd10d0d69bf763504c42ef06 /lib
parentfa2c4f5619481856c8cdf33be987d5785f51b750 (diff)
downloademacs-a451f14b09368f4b9f96d61ddb2ee69ac048c414.tar.gz
Regenerate.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.in19
-rw-r--r--lib/dtoastr.c2
-rw-r--r--lib/dummy.c42
-rw-r--r--lib/ftoastr.c136
-rw-r--r--lib/ftoastr.h144
-rw-r--r--lib/gnulib.mk15
-rw-r--r--lib/intprops.h86
-rw-r--r--lib/ldtoastr.c2
8 files changed, 393 insertions, 53 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 0fff5b2c813..d1d6e4f8417 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -24,7 +24,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=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files dummy
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files ftoastr
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
@@ -49,8 +49,10 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/gnulib.mk
subdir = lib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/gnulib-comp.m4 \
- $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \
+ $(top_srcdir)/m4/c-strtod.m4 $(top_srcdir)/m4/gnulib-common.m4 \
+ $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/getopt.m4 \
+ $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -62,7 +64,8 @@ AR = ar
ARFLAGS = cru
libgnu_a_AR = $(AR) $(ARFLAGS)
am__DEPENDENCIES_1 =
-am_libgnu_a_OBJECTS = dummy.$(OBJEXT)
+am_libgnu_a_OBJECTS = ftoastr.$(OBJEXT) dtoastr.$(OBJEXT) \
+ ldtoastr.$(OBJEXT)
libgnu_a_OBJECTS = $(am_libgnu_a_OBJECTS)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -311,11 +314,11 @@ top_srcdir = @top_srcdir@
version = @version@
x_default_search_path = @x_default_search_path@
BUILT_SOURCES =
-EXTRA_DIST =
+EXTRA_DIST = intprops.h
MOSTLYCLEANFILES = core *.stackdump
noinst_LIBRARIES = libgnu.a
DEFAULT_INCLUDES = -I. -I../src -I$(top_srcdir)/src
-libgnu_a_SOURCES = dummy.c
+libgnu_a_SOURCES = ftoastr.h ftoastr.c dtoastr.c ldtoastr.c
libgnu_a_LIBADD = $(gl_LIBOBJS)
libgnu_a_DEPENDENCIES = $(gl_LIBOBJS)
EXTRA_libgnu_a_SOURCES =
@@ -368,7 +371,9 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtoastr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftoastr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldtoastr.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/lib/dtoastr.c b/lib/dtoastr.c
new file mode 100644
index 00000000000..aed181d66b1
--- /dev/null
+++ b/lib/dtoastr.c
@@ -0,0 +1,2 @@
+#define LENGTH 2
+#include "ftoastr.c"
diff --git a/lib/dummy.c b/lib/dummy.c
deleted file mode 100644
index c958ea05d86..00000000000
--- a/lib/dummy.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* A dummy file, to prevent empty libraries from breaking builds.
- Copyright (C) 2004, 2007, 2009-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-/* Some systems, reportedly OpenBSD and Mac OS X, refuse to create
- libraries without any object files. You might get an error like:
-
- > ar cru .libs/libgl.a
- > ar: no archive members specified
-
- Compiling this file, and adding its object file to the library, will
- prevent the library from being empty. */
-
-/* Some systems, such as Solaris with cc 5.0, refuse to work with libraries
- that don't export any symbol. You might get an error like:
-
- > cc ... libgnu.a
- > ild: (bad file) garbled symbol table in archive ../gllib/libgnu.a
-
- Compiling this file, and adding its object file to the library, will
- prevent the library from exporting no symbols. */
-
-#ifdef __sun
-/* This declaration ensures that the library will export at least 1 symbol. */
-int gl_dummy_symbol;
-#else
-/* This declaration is solely to ensure that after preprocessing
- this file is never empty. */
-typedef int dummy;
-#endif
diff --git a/lib/ftoastr.c b/lib/ftoastr.c
new file mode 100644
index 00000000000..ff3d87ce22d
--- /dev/null
+++ b/lib/ftoastr.c
@@ -0,0 +1,136 @@
+/* floating point to accurate string
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert. */
+
+/* This code can misbehave on some buggy or older platforms, when
+ operating on arguments on floating types other than 'double', or
+ when given unusual combinations of options. Gnulib's
+ snprintf-posix module works around many of these problems.
+
+ This code relies on sprintf, strtod, etc. operating accurately;
+ otherwise, the resulting strings could be inaccurate or too long. */
+
+#include <config.h>
+
+#include "ftoastr.h"
+
+#include "intprops.h"
+#include <float.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if LENGTH == 3
+# define FLOAT long double
+# define FLOAT_DIG LDBL_DIG
+# define FLOAT_MIN LDBL_MIN
+# define FLOAT_PREC_BOUND _GL_LDBL_PREC_BOUND
+# define FTOASTR ldtoastr
+# define STRTOF strtold
+#elif LENGTH == 2
+# define FLOAT double
+# define FLOAT_DIG DBL_DIG
+# define FLOAT_MIN DBL_MIN
+# define FLOAT_PREC_BOUND _GL_DBL_PREC_BOUND
+# define FTOASTR dtoastr
+# define STRTOF strtod
+#else
+# define LENGTH 1
+# define FLOAT float
+# define FLOAT_DIG FLT_DIG
+# define FLOAT_MIN FLT_MIN
+# define FLOAT_PREC_BOUND _GL_FLT_PREC_BOUND
+# define FTOASTR ftoastr
+# define STRTOF strtof
+#endif
+
+/* On pre-C99 hosts, approximate strtof and strtold with strtod. This
+ may generate one or two extra digits, but that's better than not
+ working at all. Assume that strtof works if strtold does. */
+#if LENGTH != 2 && ! HAVE_C99_STRTOLD
+# undef STRTOF
+# define STRTOF strtod
+#endif
+
+/* On hosts where it's not known that snprintf works, use sprintf to
+ implement the subset needed here. Typically BUFSIZE is big enough
+ and there's little or no performance hit. */
+#if ! GNULIB_SNPRINTF
+# undef snprintf
+# define snprintf ftoastr_snprintf
+static int
+ftoastr_snprintf (char *buf, size_t bufsize, char const *format,
+ int width, int prec, FLOAT x)
+{
+ char width_0_buffer[LENGTH == 1 ? FLT_BUFSIZE_BOUND
+ : LENGTH == 2 ? DBL_BUFSIZE_BOUND
+ : LDBL_BUFSIZE_BOUND];
+ int n = width;
+ if (bufsize < sizeof width_0_buffer)
+ {
+ n = sprintf (width_0_buffer, format, 0, prec, x);
+ if (n < 0)
+ return n;
+ if (n < width)
+ n = width;
+ }
+ if (n < bufsize)
+ n = sprintf (buf, format, width, prec, x);
+ return n;
+}
+#endif
+
+int
+FTOASTR (char *buf, size_t bufsize, int flags, int width, FLOAT x)
+{
+ /* The following method is simple but slow.
+ For ideas about speeding things up, please see:
+
+ Florian Loitsch, Printing floating-point numbers quickly and accurately
+ with integers. ACM SIGPLAN notices 46, 6 (June 2010), 233-243
+ <http://dx.doi.org/10.1145/1809028.1806623>; also see the
+ 2010-03-21 draft <http://florian.loitsch.com/tmp/article.pdf>. */
+
+ char format[sizeof "%-+ 0*.*Lg"];
+ FLOAT abs_x = x < 0 ? -x : x;
+ int prec;
+
+ char *p = format;
+ *p++ = '%';
+
+ /* Support flags that generate output parsable by strtof. */
+ *p = '-'; p += (flags & FTOASTR_LEFT_JUSTIFY ) != 0;
+ *p = '+'; p += (flags & FTOASTR_ALWAYS_SIGNED ) != 0;
+ *p = ' '; p += (flags & FTOASTR_SPACE_POSITIVE) != 0;
+ *p = '0'; p += (flags & FTOASTR_ZERO_PAD ) != 0;
+
+ *p++ = '*';
+ *p++ = '.';
+ *p++ = '*';
+ *p = 'L'; p += 2 < LENGTH;
+ *p++ = flags & FTOASTR_UPPER_E ? 'G' : 'g';
+ *p = '\0';
+
+ for (prec = abs_x < FLOAT_MIN ? 1 : FLOAT_DIG; ; prec++)
+ {
+ int n = snprintf (buf, bufsize, format, width, prec, x);
+ if (n < 0
+ || FLOAT_PREC_BOUND <= prec
+ || (n < bufsize && STRTOF (buf, NULL) == x))
+ return n;
+ }
+}
diff --git a/lib/ftoastr.h b/lib/ftoastr.h
new file mode 100644
index 00000000000..6264952e8e9
--- /dev/null
+++ b/lib/ftoastr.h
@@ -0,0 +1,144 @@
+/* floating point to accurate string
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert. */
+
+#ifndef _GL_FTOASTR_H
+
+#include "intprops.h"
+#include <float.h>
+#include <stddef.h>
+
+/* Store into BUF (of size BUFSIZE) an accurate minimal-precision
+ string representation of a floating point number. FLAGS affect the
+ formatting of the number. Pad the output string with spaces as
+ necessary to width WIDTH bytes, in the style of printf. WIDTH must
+ be nonnegative. X is the floating-point number to be converted.
+
+ Return the number of bytes stored into BUF, not counting the
+ terminating null. However, do not overrun BUF: if BUF is too
+ small, return a fairly tight (but not necessarily exact) upper
+ bound on the value that would have been returned if BUF had been
+ big enough. If SIZE is zero, BUF may be a null pointer. On error
+ (e.g., returned value would exceed INT_MAX), return -1 and set
+ errno.
+
+ Example:
+
+ char buf[DBL_BUFSIZE_BOUND];
+ int r = dtoastr (buf, sizeof buf, 0, 0, 0.1);
+
+ In the C locale, this sets R to 3 and stores "0.1" into BUF. */
+
+int ftoastr (char *buf, size_t bufsize, int flags, int width, float x);
+int dtoastr (char *buf, size_t bufsize, int flags, int width, double x);
+int ldtoastr (char *buf, size_t bufsize, int flags, int width, long double x);
+
+/* Flag values for ftoastr etc. These can be ORed together. */
+enum
+ {
+ /* Left justify within the width; the default is right justification. */
+ FTOASTR_LEFT_JUSTIFY = 1,
+
+ /* Output "+" before positive numbers; the default outputs nothing. */
+ FTOASTR_ALWAYS_SIGNED = 2,
+
+ /* Output " " before positive numbers; ignored if
+ FTOASTER_ALWAYS_SIGNED is also given. */
+ FTOASTR_SPACE_POSITIVE = 4,
+
+ /* Pad with zeros instead of spaces; ignored if FTOASTR_LEFT_JUSTIFY
+ is also given. */
+ FTOASTR_ZERO_PAD = 8,
+
+ /* Use 'E' instead of 'e' before the exponent. */
+ FTOASTR_UPPER_E = 16
+ };
+
+
+/* _GL_FLT_PREC_BOUND is an upper bound on the precision needed to
+ represent a float value without losing information. Likewise for
+ _GL_DBL_PREC_BOUND and double, and _GL_LDBL_PREC_BOUND and long double. */
+
+#if FLT_RADIX == 10 /* decimal floating point */
+ enum { _GL_FLT_PREC_BOUND = FLT_MANT_DIG };
+ enum { _GL_DBL_PREC_BOUND = DBL_MANT_DIG };
+ enum { _GL_LDBL_PREC_BOUND = LDBL_MANT_DIG };
+#else
+
+/* An upper bound on the number of bits needed to represent a single
+ digit in a floating-point fraction. */
+# if FLT_RADIX == 2 /* IEEE 754 floating point, VAX floating point, etc. */
+# define _GL_FLOAT_DIG_BITS_BOUND 1
+# elif FLT_RADIX <= 16 /* IBM hex floating point has FLT_RADIX == 16. */
+# define _GL_FLOAT_DIG_BITS_BOUND 4
+# else /* no machine is this bad, but let's be complete */
+# define _GL_FLOAT_DIG_BITS_BOUND (CHAR_BIT * (int) sizeof (int) - 1)
+# endif
+
+/* An upper bound on the number of decimal digits needed to represent
+ a floating point number accurately, assuming a fraction contains
+ DIG digits. For why the "+ 1" is needed, see "Binary to Decimal
+ Conversion" in David Goldberg's paper "What Every Computer
+ Scientist Should Know About Floating-Point Arithmetic"
+ <http://docs.sun.com/source/806-3568/ncg_goldberg.html>. */
+# define _GL_FLOAT_PREC_BOUND(dig) \
+ (INT_BITS_STRLEN_BOUND ((dig) * _GL_FLOAT_DIG_BITS_BOUND) + 1)
+
+ enum { _GL_FLT_PREC_BOUND = _GL_FLOAT_PREC_BOUND ( FLT_MANT_DIG) };
+ enum { _GL_DBL_PREC_BOUND = _GL_FLOAT_PREC_BOUND ( DBL_MANT_DIG) };
+ enum { _GL_LDBL_PREC_BOUND = _GL_FLOAT_PREC_BOUND (LDBL_MANT_DIG) };
+#endif
+
+
+/* Bound on the number of bytes printed for an exponent in the range
+ MIN..MAX, where MIN < 0 < MAX; printf always prints a sign and at
+ least 2 digits. Although the maximum known exponent is 4932 for
+ IEEE 754 binary128, support tight bounds for exponents up to a
+ million, just in case. */
+#define _GL_FLOAT_EXPONENT_STRLEN_BOUND(min, max) \
+ ( -100 < (min) && (max) < 100 ? 3 \
+ : -1000 < (min) && (max) < 1000 ? 4 \
+ : -10000 < (min) && (max) < 10000 ? 5 \
+ : -100000 < (min) && (max) < 100000 ? 6 \
+ : -1000000 < (min) && (max) < 1000000 ? 7 \
+ : INT_STRLEN_BOUND (int) /* not a tight bound */)
+
+/* A reasonably tight bound on the length of a type-T floating value
+ formatted with ftoastr etc. Room is needed for sign, fraction
+ digits, decimal point, "e", and exponent. POINTLEN should be a
+ reasonably tight bound on the string length of the decimal
+ point. */
+#define _GL_FLOAT_STRLEN_BOUND_L(t, pointlen) \
+ (1 + _GL_##t##_PREC_BOUND + pointlen + 1 \
+ + _GL_FLOAT_EXPONENT_STRLEN_BOUND (t##_MIN_10_EXP, t##_MAX_10_EXP))
+#define FLT_STRLEN_BOUND_L(pointlen) _GL_FLOAT_STRLEN_BOUND_L ( FLT, pointlen)
+#define DBL_STRLEN_BOUND_L(pointlen) _GL_FLOAT_STRLEN_BOUND_L ( DBL, pointlen)
+#define LDBL_STRLEN_BOUND_L(pointlen) _GL_FLOAT_STRLEN_BOUND_L (LDBL, pointlen)
+
+/* Looser bounds that are locale-independent and are integral constant
+ expressions. */
+#define FLT_STRLEN_BOUND FLT_STRLEN_BOUND_L (MB_LEN_MAX)
+#define DBL_STRLEN_BOUND DBL_STRLEN_BOUND_L (MB_LEN_MAX)
+#define LDBL_STRLEN_BOUND LDBL_STRLEN_BOUND_L (MB_LEN_MAX)
+
+/* Looser, locale-independent bounds that include the trailing null byte. */
+#define FLT_BUFSIZE_BOUND ( FLT_STRLEN_BOUND + 1)
+#define DBL_BUFSIZE_BOUND ( DBL_STRLEN_BOUND + 1)
+#define LDBL_BUFSIZE_BOUND (LDBL_STRLEN_BOUND + 1)
+
+#endif /* _GL_FTOASTR_H */
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 1f5efc12e86..78d89d99281 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -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=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files dummy
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files ftoastr
MOSTLYCLEANFILES += core *.stackdump
@@ -21,11 +21,18 @@ libgnu_a_LIBADD = $(gl_LIBOBJS)
libgnu_a_DEPENDENCIES = $(gl_LIBOBJS)
EXTRA_libgnu_a_SOURCES =
-## begin gnulib module dummy
+## begin gnulib module ftoastr
-libgnu_a_SOURCES += dummy.c
+libgnu_a_SOURCES += ftoastr.h ftoastr.c dtoastr.c ldtoastr.c
-## end gnulib module dummy
+## end gnulib module ftoastr
+
+## begin gnulib module intprops
+
+
+EXTRA_DIST += intprops.h
+
+## end gnulib module intprops
mostlyclean-local: mostlyclean-generic
diff --git a/lib/intprops.h b/lib/intprops.h
new file mode 100644
index 00000000000..511a5aa9890
--- /dev/null
+++ b/lib/intprops.h
@@ -0,0 +1,86 @@
+/* intprops.h -- properties of integer types
+
+ Copyright (C) 2001-2005, 2009-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert. */
+
+#ifndef GL_INTPROPS_H
+# define GL_INTPROPS_H
+
+# include <limits.h>
+
+/* The extra casts in the following macros work around compiler bugs,
+ e.g., in Cray C 5.0.3.0. */
+
+/* True if the arithmetic type T is an integer type. bool counts as
+ an integer. */
+# define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
+
+/* True if negative values of the signed integer type T use two's
+ complement, ones' complement, or signed magnitude representation,
+ respectively. Much GNU code assumes two's complement, but some
+ people like to be portable to all possible C hosts. */
+# define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
+# define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
+# define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
+
+/* True if the arithmetic type T is signed. */
+# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+
+/* The maximum and minimum values for the integer type T. These
+ macros have undefined behavior if T is signed and has padding bits.
+ If this is a problem for you, please let us know how to fix it for
+ your host. */
+# define TYPE_MINIMUM(t) \
+ ((t) (! TYPE_SIGNED (t) \
+ ? (t) 0 \
+ : TYPE_SIGNED_MAGNITUDE (t) \
+ ? ~ (t) 0 \
+ : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
+# define TYPE_MAXIMUM(t) \
+ ((t) (! TYPE_SIGNED (t) \
+ ? (t) -1 \
+ : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
+
+/* Return zero if T can be determined to be an unsigned type.
+ Otherwise, return 1.
+ When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a
+ tighter bound. Otherwise, it overestimates the true bound by one byte
+ when applied to unsigned types of size 2, 4, 16, ... bytes.
+ The symbol signed_type_or_expr__ is private to this header file. */
+# if __GNUC__ >= 2
+# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t))
+# else
+# define signed_type_or_expr__(t) 1
+# endif
+
+/* Bound on length of the string representing an unsigned integer
+ value representable in B bits. log10 (2.0) < 146/485. The
+ smallest value of B where this bound is not tight is 2621. */
+# define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)
+
+/* Bound on length of the string representing an integer type or expression T.
+ Subtract 1 for the sign bit if T is signed, and then add 1 more for
+ a minus sign if needed. */
+# define INT_STRLEN_BOUND(t) \
+ (INT_BITS_STRLEN_BOUND (sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) \
+ + signed_type_or_expr__ (t))
+
+/* Bound on buffer size needed to represent an integer type or expression T,
+ including the terminating null. */
+# define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
+
+#endif /* GL_INTPROPS_H */
diff --git a/lib/ldtoastr.c b/lib/ldtoastr.c
new file mode 100644
index 00000000000..bf54a3582e3
--- /dev/null
+++ b/lib/ldtoastr.c
@@ -0,0 +1,2 @@
+#define LENGTH 3
+#include "ftoastr.c"