dprintf is similar to vdprintf. Implemented like this: 2009-01-17 Bruno Haible <br...@clisp.org>
New modules 'dprintf', 'dprintf-posix'. * lib/stdio.in.h (dprintf): New declaration. * lib/dprintf.c: New file. * m4/dprintf.m4: New file. * m4/dprintf-posix.m4: New file. * modules/dprintf: New file. * modules/dprintf-posix: New file. * m4/stdio_h.m4 (gl_STDIO_H_DEFAULTS): Initialize GNULIB_DPRINTF, HAVE_DPRINTF, REPLACE_DPRINTF. * modules/stdio (Makefile.am): Substitute also GNULIB_DPRINTF, HAVE_DPRINTF, REPLACE_DPRINTF. * doc/posix-functions/dprintf.texi: Mention the new modules. ================================ lib/dprintf.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 dprintf (int fd, const char *format, ...) { char buf[2000]; char *output; size_t len; size_t lenbuf = sizeof (buf); va_list args; va_start (args, format); output = vasnprintf (buf, &lenbuf, format, args); len = lenbuf; va_end (args); 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/dprintf.m4 ================================ # dprintf.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_DPRINTF], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) AC_CHECK_FUNCS_ONCE([dprintf]) if test $ac_cv_func_dprintf = no; then HAVE_DPRINTF=0 gl_REPLACE_DPRINTF fi ]) AC_DEFUN([gl_REPLACE_DPRINTF], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) AC_LIBOBJ([dprintf]) if test $ac_cv_func_dprintf = yes; then REPLACE_DPRINTF=1 fi gl_PREREQ_DPRINTF ]) # Prerequisites of lib/dprintf.c. AC_DEFUN([gl_PREREQ_DPRINTF], [:]) ============================= m4/dprintf-posix.m4 ============================= # dprintf-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_DPRINTF_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_dprintf_posix=no AC_CHECK_FUNCS_ONCE([dprintf]) if test $ac_cv_func_dprintf = 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) # dprintf exists and is # already POSIX compliant. gl_cv_func_dprintf_posix=yes ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac ;; esac fi if test $gl_cv_func_dprintf_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_DPRINTF fi ]) =============================== modules/dprintf =============================== Description: dprintf() function: print formatted output to a file descriptor Files: lib/dprintf.c m4/dprintf.m4 Depends-on: stdio vasnprintf full-write errno configure.ac: gl_FUNC_DPRINTF gl_STDIO_MODULE_INDICATOR([dprintf]) Makefile.am: Include: <stdio.h> License: LGPL Maintainer: Bruno Haible ============================ modules/dprintf-posix ============================ Description: POSIX compatible dprintf() function: print formatted output to a file descriptor Files: m4/dprintf-posix.m4 m4/printf.m4 Depends-on: dprintf vasnprintf isnand-nolibm isnanl-nolibm frexp-nolibm frexpl-nolibm printf-frexp printf-frexpl signbit fpucw nocrash printf-safe multiarch configure.ac: gl_FUNC_DPRINTF_POSIX Makefile.am: Include: <stdio.h> License: LGPL Maintainer: Bruno Haible =============================================================================== --- lib/stdio.in.h.orig 2009-01-18 03:18:38.000000000 +0100 +++ lib/stdio.in.h 2009-01-18 02:55:52.000000000 +0100 @@ -216,6 +216,22 @@ vsprintf (b, f, a)) #endif +#if @GNULIB_DPRINTF@ +# if @REPLACE_DPRINTF@ +# define dprintf rpl_dprintf +# endif +# if @REPLACE_DPRINTF@ || !...@have_dprintf@ +extern int dprintf (int fd, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +# endif +#elif defined GNULIB_POSIXCHECK +# undef dprintf +# define dprintf(d,f,a) \ + (GL_LINK_WARNING ("dprintf is unportable - " \ + "use gnulib module dprintf for portability"), \ + dprintf (d, f, a)) +#endif + #if @GNULIB_VDPRINTF@ # if @REPLACE_VDPRINTF@ # define vdprintf rpl_vdprintf --- m4/stdio_h.m4.orig 2009-01-18 03:18:39.000000000 +0100 +++ m4/stdio_h.m4 2009-01-18 03:01:08.000000000 +0100 @@ -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_DPRINTF=0; AC_SUBST([GNULIB_DPRINTF]) GNULIB_VDPRINTF=0; AC_SUBST([GNULIB_VDPRINTF]) GNULIB_VASPRINTF=0; AC_SUBST([GNULIB_VASPRINTF]) GNULIB_OBSTACK_PRINTF=0; AC_SUBST([GNULIB_OBSTACK_PRINTF]) @@ -87,6 +88,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_DPRINTF=1; AC_SUBST([HAVE_DPRINTF]) + REPLACE_DPRINTF=0; AC_SUBST([REPLACE_DPRINTF]) HAVE_VDPRINTF=1; AC_SUBST([HAVE_VDPRINTF]) REPLACE_VDPRINTF=0; AC_SUBST([REPLACE_VDPRINTF]) HAVE_VASPRINTF=1; AC_SUBST([HAVE_VASPRINTF]) --- modules/stdio.orig 2009-01-18 03:18:39.000000000 +0100 +++ modules/stdio 2009-01-18 03:02:11.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_DPRINTF''@|$(GNULIB_DPRINTF)|g' \ -e 's|@''GNULIB_VDPRINTF''@|$(GNULIB_VDPRINTF)|g' \ -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \ @@ -70,6 +71,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_DPRINTF''@|$(HAVE_DPRINTF)|g' \ + -e 's|@''REPLACE_DPRINTF''@|$(REPLACE_DPRINTF)|g' \ -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \ -e 's|@''REPLACE_VDPRINTF''@|$(REPLACE_VDPRINTF)|g' \ -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ --- doc/posix-functions/dprintf.texi.orig 2009-01-18 03:18:38.000000000 +0100 +++ doc/posix-functions/dprintf.texi 2009-01-18 03:04:09.000000000 +0100 @@ -4,15 +4,23 @@ POSIX specification: @url{http://www.opengroup.org/onlinepubs/9699919799/functions/dprintf.html} -Gnulib module: --- +Gnulib module: dprintf or dprintf-posix -Portability problems fixed by Gnulib: +Portability problems fixed by either Gnulib module @code{dprintf} or @code{dprintf-posix}: @itemize +...@item +This function is missing on all non-glibc 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, BeOS. @end itemize -Portability problems not fixed by Gnulib: +Portability problems fixed by Gnulib module @code{dprintf-posix}: @itemize @item -This function is missing on all non-glibc 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, BeOS. +This function does not support the @samp{a} and @samp{A} directives on some +platforms: +glibc-2.3.6. +...@end itemize + +Portability problems not fixed by Gnulib: +...@itemize @end itemize