Among the new functions in POSIX:2008 is vdprintf(), which does formatted output to a file descriptor. These two modules implement it.
2009-01-17 Bruno Haible <br...@clisp.org> New modules 'vdprintf', 'vdprintf-posix'. * lib/stdio.in.h (vdprintf): New declaration. * lib/vdprintf.c: New file. * m4/vdprintf.m4: New file. * m4/vdprintf-posix.m4: New file. * modules/vdprintf: New file. * modules/vdprintf-posix: New file. * m4/stdio_h.m4 (gl_STDIO_H_DEFAULTS): Initialize GNULIB_VDPRINTF, HAVE_VDPRINTF, REPLACE_VDPRINTF. * modules/stdio (Makefile.am): Substitute also GNULIB_VDPRINTF, HAVE_VDPRINTF, REPLACE_VDPRINTF. * doc/posix-functions/vdprintf.texi: Mention the new modules. ==================================== lib/vdprintf.c =========================== /* Formatted output to a file descriptor. Copyright (C) 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H # include <config.h> #endif /* Specification. */ #include <stdio.h> #include <errno.h> #include <limits.h> #include <stdarg.h> #include <stdlib.h> #include "full-write.h" #include "vasnprintf.h" int vdprintf (int fd, const char *format, va_list args) { char buf[2000]; char *output; size_t len; size_t lenbuf = sizeof (buf); output = vasnprintf (buf, &lenbuf, format, args); len = lenbuf; if (!output) return -1; if (full_write (fd, output, len) < len) { if (output != buf) { int saved_errno = errno; free (output); errno = saved_errno; } return -1; } if (len > INT_MAX) { errno = EOVERFLOW; return -1; } return len; } ==================================== m4/vdprintf.m4 =========================== # vdprintf.m4 serial 1 dnl Copyright (C) 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_VDPRINTF], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) AC_CHECK_FUNCS_ONCE([vdprintf]) if test $ac_cv_func_vdprintf = no; then HAVE_VDPRINTF=0 gl_REPLACE_VDPRINTF fi ]) AC_DEFUN([gl_REPLACE_VDPRINTF], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) AC_LIBOBJ([vdprintf]) if test $ac_cv_func_vdprintf = yes; then REPLACE_VDPRINTF=1 fi gl_PREREQ_VDPRINTF ]) # Prerequisites of lib/vdprintf.c. AC_DEFUN([gl_PREREQ_VDPRINTF], [:]) ================================= m4/vdprintf-posix.m4 ======================== # vdprintf-posix.m4 serial 1 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_VDPRINTF_POSIX], [ AC_REQUIRE([gl_PRINTF_SIZES_C99]) AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_INFINITE]) AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_N]) AC_REQUIRE([gl_PRINTF_POSITIONS]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST]) AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) AC_REQUIRE([gl_PRINTF_PRECISION]) AC_REQUIRE([gl_PRINTF_ENOMEM]) gl_cv_func_vdprintf_posix=no AC_CHECK_FUNCS_ONCE([vdprintf]) if test $ac_cv_func_vdprintf = yes; then case "$gl_cv_func_printf_sizes_c99" in *yes) case "$gl_cv_func_printf_long_double" in *yes) case "$gl_cv_func_printf_infinite" in *yes) case "$gl_cv_func_printf_infinite_long_double" in *yes) case "$gl_cv_func_printf_directive_a" in *yes) case "$gl_cv_func_printf_directive_f" in *yes) case "$gl_cv_func_printf_directive_n" in *yes) case "$gl_cv_func_printf_positions" in *yes) case "$gl_cv_func_printf_flag_grouping" in *yes) case "$gl_cv_func_printf_flag_leftadjust" in *yes) case "$gl_cv_func_printf_flag_zero" in *yes) case "$gl_cv_func_printf_precision" in *yes) case "$gl_cv_func_printf_enomem" in *yes) # vdprintf exists and is # already POSIX compliant. gl_cv_func_vdprintf_posix=yes ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac fi if test $gl_cv_func_vdprintf_posix = no; then gl_PREREQ_VASNPRINTF_LONG_DOUBLE gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST gl_PREREQ_VASNPRINTF_FLAG_ZERO gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_ENOMEM gl_REPLACE_VASNPRINTF gl_REPLACE_VDPRINTF fi ]) =================================== modules/vdprintf ========================== Description: vdprintf() function: print formatted output to a file descriptor Files: lib/vdprintf.c m4/vdprintf.m4 Depends-on: stdio vasnprintf full-write errno configure.ac: gl_FUNC_VDPRINTF gl_STDIO_MODULE_INDICATOR([vdprintf]) Makefile.am: Include: <stdio.h> License: LGPL Maintainer: Bruno Haible ================================ modules/vdprintf-posix ======================= Description: POSIX compatible vdprintf() function: print formatted output to a file descriptor Files: m4/vdprintf-posix.m4 m4/printf.m4 Depends-on: vdprintf vasnprintf isnand-nolibm isnanl-nolibm frexp-nolibm frexpl-nolibm printf-frexp printf-frexpl signbit fpucw nocrash printf-safe multiarch configure.ac: gl_FUNC_VDPRINTF_POSIX Makefile.am: Include: <stdio.h> License: LGPL Maintainer: Bruno Haible =============================================================================== --- lib/stdio.in.h.orig 2009-01-18 02:41:06.000000000 +0100 +++ lib/stdio.in.h 2009-01-18 02:11:00.000000000 +0100 @@ -216,6 +216,22 @@ vsprintf (b, f, a)) #endif +#if @GNULIB_VDPRINTF@ +# if @REPLACE_VDPRINTF@ +# define vdprintf rpl_vdprintf +# endif +# if @REPLACE_VDPRINTF@ || !...@have_vdprintf@ +extern int vdprintf (int fd, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))); +# endif +#elif defined GNULIB_POSIXCHECK +# undef vdprintf +# define vdprintf(d,f,a) \ + (GL_LINK_WARNING ("vdprintf is unportable - " \ + "use gnulib module vdprintf for portability"), \ + vdprintf (d, f, a)) +#endif + #if @GNULIB_VASPRINTF@ # if @REPLACE_VASPRINTF@ # define asprintf rpl_asprintf --- m4/stdio_h.m4.orig 2009-01-18 02:41:06.000000000 +0100 +++ m4/stdio_h.m4 2009-01-18 02:11:54.000000000 +0100 @@ -1,5 +1,5 @@ -# stdio_h.m4 serial 14 -dnl Copyright (C) 2007-2008 Free Software Foundation, Inc. +# stdio_h.m4 serial 15 +dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -53,6 +53,7 @@ GNULIB_VPRINTF_POSIX=0; AC_SUBST([GNULIB_VPRINTF_POSIX]) GNULIB_VSNPRINTF=0; AC_SUBST([GNULIB_VSNPRINTF]) GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX]) + GNULIB_VDPRINTF=0; AC_SUBST([GNULIB_VDPRINTF]) GNULIB_VASPRINTF=0; AC_SUBST([GNULIB_VASPRINTF]) GNULIB_OBSTACK_PRINTF=0; AC_SUBST([GNULIB_OBSTACK_PRINTF]) GNULIB_OBSTACK_PRINTF_POSIX=0; AC_SUBST([GNULIB_OBSTACK_PRINTF_POSIX]) @@ -86,6 +87,8 @@ HAVE_DECL_VSNPRINTF=1; AC_SUBST([HAVE_DECL_VSNPRINTF]) REPLACE_SPRINTF=0; AC_SUBST([REPLACE_SPRINTF]) REPLACE_VSPRINTF=0; AC_SUBST([REPLACE_VSPRINTF]) + HAVE_VDPRINTF=1; AC_SUBST([HAVE_VDPRINTF]) + REPLACE_VDPRINTF=0; AC_SUBST([REPLACE_VDPRINTF]) HAVE_VASPRINTF=1; AC_SUBST([HAVE_VASPRINTF]) REPLACE_VASPRINTF=0; AC_SUBST([REPLACE_VASPRINTF]) HAVE_DECL_OBSTACK_PRINTF=1; AC_SUBST([HAVE_DECL_OBSTACK_PRINTF]) --- modules/stdio.orig 2009-01-18 02:41:06.000000000 +0100 +++ modules/stdio 2009-01-18 02:11:30.000000000 +0100 @@ -37,6 +37,7 @@ -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \ -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \ -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VDPRINTF''@|$(GNULIB_VDPRINTF)|g' \ -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \ -e 's|@''GNULIB_OBSTACK_PRINTF_POSIX''@|$(GNULIB_OBSTACK_PRINTF_POSIX)|g' \ @@ -69,6 +70,8 @@ -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \ -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \ + -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \ + -e 's|@''REPLACE_VDPRINTF''@|$(REPLACE_VDPRINTF)|g' \ -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ -e 's|@''HAVE_DECL_OBSTACK_PRINTF''@|$(HAVE_DECL_OBSTACK_PRINTF)|g' \ --- doc/posix-functions/vdprintf.texi.orig 2009-01-18 02:41:06.000000000 +0100 +++ doc/posix-functions/vdprintf.texi 2009-01-18 02:39:48.000000000 +0100 @@ -4,15 +4,41 @@ POSIX specification: @url{http://www.opengroup.org/onlinepubs/9699919799/functions/vdprintf.html} -Gnulib module: --- +Gnulib module: vdprintf or vdprintf-posix -Portability problems fixed by Gnulib: +Portability problems fixed by either Gnulib module @code{vdprintf} or @code{vdprintf-posix}: @itemize +...@item +This function is missing on some platforms: +MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin, mingw, Interix 3.5. @end itemize -Portability problems not fixed by Gnulib: +Portability problems fixed by Gnulib module @code{vdprintf-posix}: @itemize @item -This function is missing on some platforms: -MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin, mingw, Interix 3.5. +This function does not support size specifiers as in C99 (@code{hh}, @code{ll}, +...@code{j}, @code{t}, @code{z}) on some platforms: +BeOS. +...@item +printf of @samp{long double} numbers is unsupported on some platforms: +BeOS. +...@item +This function does not support the @samp{a} and @samp{A} directives on some +platforms: +glibc-2.3.6, BeOS. +...@item +This function does not support the @samp{F} directive on some platforms: +BeOS. +...@item +This function does not support format directives that access arguments in an +arbitrary order, such as @code{"%2$s"}, on some platforms: +BeOS. +...@item +This function does not support precisions larger than 512 or 1024 in integer, +floating-point and pointer output on some platforms: +BeOS. +...@end itemize + +Portability problems not fixed by Gnulib: +...@itemize @end itemize