From d464708e0dc6a758523c57a088aea56efb463b1f Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 18 Jan 2009 02:48:41 +0100 Subject: [PATCH] New modules 'vdprintf', 'vdprintf-posix'. --- ChangeLog | 15 +++++ doc/posix-functions/vdprintf.texi | 36 ++++++++++-- lib/stdio.in.h | 16 ++++++ lib/vdprintf.c | 64 +++++++++++++++++++++ m4/stdio_h.m4 | 7 ++- m4/vdprintf-posix.m4 | 95 +++++++++++++++++++++++++++++++ m4/vdprintf.m4 | 28 +++++++++ modules/stdio | 3 + modules/vdprintf | 28 +++++++++ modules/vdprintf-posix | 37 ++++++++++++ 10 files changed, 322 insertions(+), 7 deletions(-) create mode 100644 lib/vdprintf.c create mode 100644 m4/vdprintf-posix.m4 create mode 100644 m4/vdprintf.m4 create mode 100644 modules/vdprintf create mode 100644 modules/vdprintf-posix diff --git a/ChangeLog b/ChangeLog index 5986110d13..e8b99de79b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2009-01-17 Bruno Haible + + 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. + 2009-01-17 Bruno Haible Fix replacement of fopen on mingw. diff --git a/doc/posix-functions/vdprintf.texi b/doc/posix-functions/vdprintf.texi index 55d0447470..8947d07b0e 100644 --- a/doc/posix-functions/vdprintf.texi +++ b/doc/posix-functions/vdprintf.texi @@ -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 diff --git a/lib/stdio.in.h b/lib/stdio.in.h index 0e12d94530..a3a5e7af5b 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -216,6 +216,22 @@ extern int vsprintf (char *str, const char *format, va_list args) 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 diff --git a/lib/vdprintf.c b/lib/vdprintf.c new file mode 100644 index 0000000000..37512ed745 --- /dev/null +++ b/lib/vdprintf.c @@ -0,0 +1,64 @@ +/* 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 +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; +} diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 index 60b4bd791a..635258a443 100644 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -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 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], 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 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], 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]) diff --git a/m4/vdprintf-posix.m4 b/m4/vdprintf-posix.m4 new file mode 100644 index 0000000000..70536b4b50 --- /dev/null +++ b/m4/vdprintf-posix.m4 @@ -0,0 +1,95 @@ +# 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 +]) diff --git a/m4/vdprintf.m4 b/m4/vdprintf.m4 new file mode 100644 index 0000000000..813bfd7b23 --- /dev/null +++ b/m4/vdprintf.m4 @@ -0,0 +1,28 @@ +# 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], [:]) diff --git a/modules/stdio b/modules/stdio index 5daae68b97..47ec02f742 100644 --- a/modules/stdio +++ b/modules/stdio @@ -37,6 +37,7 @@ stdio.h: stdio.in.h -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 @@ stdio.h: stdio.in.h -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' \ diff --git a/modules/vdprintf b/modules/vdprintf new file mode 100644 index 0000000000..3ddda20d13 --- /dev/null +++ b/modules/vdprintf @@ -0,0 +1,28 @@ +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: + + +License: +LGPL + +Maintainer: +Bruno Haible + diff --git a/modules/vdprintf-posix b/modules/vdprintf-posix new file mode 100644 index 0000000000..bc1cb88928 --- /dev/null +++ b/modules/vdprintf-posix @@ -0,0 +1,37 @@ +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: + + +License: +LGPL + +Maintainer: +Bruno Haible + -- 2.30.2