summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2010-11-19 14:36:12 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2010-11-19 14:41:15 -0800
commit52e7df4a7f92778282b1025f72047e36dc929063 (patch)
tree1c7418a73156e570db1b78c609c3629a9fd2d5ce
parentdb37bb3e918ce69fd0bf5e45752edd07f49ae07d (diff)
downloadgnulib-52e7df4a7f92778282b1025f72047e36dc929063.tar.gz
ftoastr: don't assume snprintf
* lib/ftoastr.c (snprintf) [! GNULIB_SNPRINTF_POSIX]: Implement a subset of snprintf here, by using sprintf safely. * modules/ftoastr (Depends-on): Remove snprintf.
-rw-r--r--ChangeLog7
-rw-r--r--lib/ftoastr.c36
-rw-r--r--modules/ftoastr1
3 files changed, 43 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index e4f534df40..9dbc0c20e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-11-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ ftoastr: don't assume snprintf
+ * lib/ftoastr.c (snprintf) [! GNULIB_SNPRINTF_POSIX]:
+ Implement a subset of snprintf here, by using sprintf safely.
+ * modules/ftoastr (Depends-on): Remove snprintf.
+
2010-11-19 Jim Meyering <meyering@redhat.com>
test-rename.h: fix compilation failure
diff --git a/lib/ftoastr.c b/lib/ftoastr.c
index f74740088e..41b5aed45d 100644
--- a/lib/ftoastr.c
+++ b/lib/ftoastr.c
@@ -17,6 +17,14 @@
/* 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 "ftoastr.h"
#include "intprops.h"
@@ -56,6 +64,34 @@
# 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 performance hit. */
+#if ! GNULIB_SNPRINTF_POSIX
+# 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)
{
diff --git a/modules/ftoastr b/modules/ftoastr
index 862fb1aa21..64d0a77903 100644
--- a/modules/ftoastr
+++ b/modules/ftoastr
@@ -10,7 +10,6 @@ m4/c-strtod.m4
Depends-on:
intprops
-snprintf
configure.ac:
AC_REQUIRE([gl_C99_STRTOLD])