# HG changeset patch # User Bruno Haible # Date 1232245328 -3600 # Node ID bf21f4597784201ca61d180a2ec16183dd16d6ff # Parent c1aeb2f8dd656122ee05099fe5c2363ff9f138cc New modules 'dprintf', 'dprintf-posix'. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2009-01-17 Bruno Haible + + 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. + 2009-01-17 Bruno Haible * modules/vdprintf-posix-tests: New file. diff --git a/doc/posix-functions/dprintf.texi b/doc/posix-functions/dprintf.texi --- a/doc/posix-functions/dprintf.texi +++ b/doc/posix-functions/dprintf.texi @@ -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: -@itemize -@end itemize - -Portability problems not 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 fixed by Gnulib module @code{dprintf-posix}: +@itemize +@item +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 diff --git a/lib/dprintf.c b/lib/dprintf.c new file mode 100644 --- /dev/null +++ b/lib/dprintf.c @@ -0,0 +1,67 @@ +/* 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Specification. */ +#include + +#include +#include +#include +#include + +#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; +} diff --git a/lib/stdio.in.h b/lib/stdio.in.h --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -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 diff --git a/m4/dprintf-posix.m4 b/m4/dprintf-posix.m4 new file mode 100644 --- /dev/null +++ b/m4/dprintf-posix.m4 @@ -0,0 +1,95 @@ +# 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 +]) diff --git a/m4/dprintf.m4 b/m4/dprintf.m4 new file mode 100644 --- /dev/null +++ b/m4/dprintf.m4 @@ -0,0 +1,28 @@ +# 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], [:]) diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -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]) diff --git a/modules/dprintf b/modules/dprintf new file mode 100644 --- /dev/null +++ b/modules/dprintf @@ -0,0 +1,28 @@ +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: + + +License: +LGPL + +Maintainer: +Bruno Haible + diff --git a/modules/dprintf-posix b/modules/dprintf-posix new file mode 100644 --- /dev/null +++ b/modules/dprintf-posix @@ -0,0 +1,37 @@ +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: + + +License: +LGPL + +Maintainer: +Bruno Haible + diff --git a/modules/stdio b/modules/stdio --- a/modules/stdio +++ b/modules/stdio @@ -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' \