This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH,RFC] Change __convert_from_v to use snprintf and use it


Paolo Carlini <pcarlini@unitus.it> writes:

> I know that (I wrote something about this yesterday). However, from a
> practical point of view, IMHO it does'nt matter much if a function named
> "snprintf" is available. In order to implement "my" scheme (that
> suggested by glibc docs, indeed) we need exactly the C99-version, that
> returning the actual number of chars needed.

snprintf and vsnprintf are frequently available in a broken form.  Here's
the test we use in INN (this code is short and obvious enough that I don't
consider it covered by copyright, and I've also released it into the
equivalent of the public domain and am the sole author, but I don't have
signed papers with the FSF).

The other thing that's often broken is accepting NULL as the first
argument.

Note that this adds snprintf.o to LIBOBJS if snprintf doesn't work, a la
AC_REPLACE_FUNC, which may not be what you want.

dnl Source used by INN_FUNC_SNPRINTF.
define([_INN_FUNC_SNPRINTF_SOURCE],
[[#include <stdio.h>
#include <stdarg.h>

char buf[2];

int
test (char *format, ...)
{
  va_list args;
  int count;

  va_start (args, format);
  count = vsnprintf (buf, sizeof buf, format, args);
  va_end (args);
  return count;
}

int
main ()
{
  return ((test ("%s", "abcd") == 4 && buf[0] == 'a' && buf[1] == '\0'
           && snprintf(NULL, 0, "%s", "abcd") == 4) ? 0 : 1);
}]])

dnl Check for a working snprintf.  Some systems have snprintf, but it doesn't
dnl null-terminate if the buffer isn't large enough or it returns -1 if the
dnl string doesn't fit instead of returning the number of characters that
dnl would have been formatted.
AC_DEFUN([INN_FUNC_SNPRINTF],
[AC_CACHE_CHECK(for working snprintf, inn_cv_func_snprintf_works,
[AC_TRY_RUN(_INN_FUNC_SNPRINTF_SOURCE(),
            [inn_cv_func_snprintf_works=yes],
            [inn_cv_func_snprintf_works=no],
            [inn_cv_func_snprintf_works=no])])
if test "$inn_cv_func_snprintf_works" = yes ; then
    AC_DEFINE([HAVE_SNPRINTF], 1,
        [Define if your system has a working snprintf function.])
else
    LIBOBJS="$LIBOBJS snprintf.${ac_objext}"
fi])
INN_FUNC_SNPRINTF

-- 
Russ Allbery (rra@stanford.edu)             <http://www.eyrie.org/~eagle/>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]