From 52e7df4a7f92778282b1025f72047e36dc929063 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 19 Nov 2010 14:36:12 -0800 Subject: [PATCH] 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. --- ChangeLog | 7 +++++++ lib/ftoastr.c | 36 ++++++++++++++++++++++++++++++++++++ modules/ftoastr | 1 - 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e4f534df4..9dbc0c20e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-11-19 Paul Eggert + + 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 test-rename.h: fix compilation failure diff --git a/lib/ftoastr.c b/lib/ftoastr.c index f74740088..41b5aed45 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 862fb1aa2..64d0a7790 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]) -- 2.11.0