ftoastr: don't assume snprintf
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 19 Nov 2010 22:36:12 +0000 (14:36 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 19 Nov 2010 22:41:15 +0000 (14:41 -0800)
* lib/ftoastr.c (snprintf) [! GNULIB_SNPRINTF_POSIX]:
Implement a subset of snprintf here, by using sprintf safely.
* modules/ftoastr (Depends-on): Remove snprintf.

ChangeLog
lib/ftoastr.c
modules/ftoastr

index e4f534d..9dbc0c2 100644 (file)
--- 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
index f747400..41b5aed 100644 (file)
 
 /* 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"
 # 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)
 {
index 862fb1a..64d0a77 100644 (file)
@@ -10,7 +10,6 @@ m4/c-strtod.m4
 
 Depends-on:
 intprops
-snprintf
 
 configure.ac:
 AC_REQUIRE([gl_C99_STRTOLD])