changeset 13882:a6c2ab095e9b

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.
author Paul Eggert <eggert@cs.ucla.edu>
date Fri, 19 Nov 2010 14:36:12 -0800
parents b692389b222f
children 92b602471ee0
files ChangeLog lib/ftoastr.c modules/ftoastr
diffstat 3 files changed, 43 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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)
 {
--- a/modules/ftoastr
+++ b/modules/ftoastr
@@ -10,7 +10,6 @@
 
 Depends-on:
 intprops
-snprintf
 
 configure.ac:
 AC_REQUIRE([gl_C99_STRTOLD])