bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: obstack_printf


From: Bruno Haible
Subject: Re: obstack_printf
Date: Sat, 14 Jun 2008 09:33:08 +0200
User-agent: KMail/1.5.4

Eric Blake wrote:
> More than a year ago, I proposed adding obstack_printf:
> 
> http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00188.html
> 
> Well, the time finally came where I'm ready to use it in m4, so here goes.

The obligatory proofreading and nitpicking:


1) This C code

    const size_t cutoff = 1024;
    char buf[cutoff];

is understood only by gcc, Tru64 cc, IRIX cc. It fails to compile on other C
compilers:

Solaris, Sun C 5.0:
cc -O -DHAVE_CONFIG_H -I. -I..      -g -c obstack_printf.c
"obstack_printf.c", line 62: integral constant expression expected

HP-UX, "cc -Ae":
cc: "obstack_printf.c", line 62: error 1502: Array size must be a constant 
expression.

AIX, "xlc -D_ALL_SOURCE":
"obstack_printf.c", line 62.12: 1506-195 (S) Integral constant expression with 
a value greater than zero is required.

The fix is to define the array size either as a macro or as an enum value.


2) You test for the declaration of the function in <stdio.h>. Good. But in order
to minimize the danger inherent in redeclaration of a system function, it's 
better
to let <stdio.h> declare the function by itself: Define _GNU_SOURCE.


3) gl_FUNC_OBSTACK_PRINTF_POSIX assumes that if the *printf family of functions
is POSIX compliant, obstack_printf exists as well. Pretty daring :-) To fix
this, I looked at snprintf-posix.m4.


4) In the "Include" section of the module description, I find it confusing to
mention "obstack.h" before <stdio.h>. It suggests that "obstack.h" should be
included before <stdio.h>. This is not the case; actually, one does not need
to include "obstack.h" at all if a forward declaration
  struct obstack;
is present.


5) What do you mean by this comment in tests/test-obstack-printf.c ?
  /* In general, don't invoke obstack_* functions inside ASSERT, as
     not all compilers can avoid multiple side effects.  */

The ASSERT macro is ours, not the system's one. What can go wrong regarding
"multiple side effects"?


Here's the proposed fix:

2008-06-14  Bruno Haible  <address@hidden>

        * lib/obstack_printf.c (obstack_vprintf): Define the stack-allocated
        array size as a macro.
        * m4/obstack-printf.m4 (gl_FUNC_OBSTACK_PRINTF): Require
        AC_USE_SYSTEM_EXTENSIONS.
        * m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_POSIX): Likewise.
        Test whether the obstack_printf function actually exists.
        * modules/obstack-printf (Depends-on): Add extensions.
        (Include): Remove obstack.h.
        * modules/obstack-printf-posix (Depends-on): Add extensions.
        (Include): Remove obstack.h.

*** lib/obstack_printf.c.orig   2008-06-14 09:05:52.000000000 +0200
--- lib/obstack_printf.c        2008-06-14 08:43:36.000000000 +0200
***************
*** 58,73 ****
       stack-allocated buffer and copy, to reduce the likelihood of a
       small-size malloc.  Otherwise, print directly into the
       obstack.  */
!   const size_t cutoff = 1024;
!   char buf[cutoff];
    char *base = obstack_next_free (obs);
    size_t len = obstack_room (obs);
    char *str;
  
!   if (len < cutoff)
      {
        base = buf;
!       len = cutoff;
      }
    str = vasnprintf (base, &len, format, args);
    if (!str)
--- 58,73 ----
       stack-allocated buffer and copy, to reduce the likelihood of a
       small-size malloc.  Otherwise, print directly into the
       obstack.  */
! #define CUTOFF 1024
!   char buf[CUTOFF];
    char *base = obstack_next_free (obs);
    size_t len = obstack_room (obs);
    char *str;
  
!   if (len < CUTOFF)
      {
        base = buf;
!       len = CUTOFF;
      }
    str = vasnprintf (base, &len, format, args);
    if (!str)
***************
*** 89,92 ****
--- 89,93 ----
        free (str);
      }
    return len;
+ #undef CUTOFF
  }
*** m4/obstack-printf.m4.orig   2008-06-14 09:05:52.000000000 +0200
--- m4/obstack-printf.m4        2008-06-14 08:12:56.000000000 +0200
***************
*** 1,4 ****
! # obstack-printf.m4 serial 1
  dnl Copyright (C) 2008 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # obstack-printf.m4 serial 2
  dnl Copyright (C) 2008 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 10,15 ****
--- 10,18 ----
  
  AC_DEFUN([gl_FUNC_OBSTACK_PRINTF],
  [
+   dnl Persuade glibc <stdio.h> to declare obstack_printf(), obstack_vprintf().
+   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+ 
    AC_REQUIRE([gl_STDIO_H_DEFAULTS])
    AC_CHECK_FUNCS_ONCE([obstack_printf])
    if test $ac_cv_func_obstack_printf = no ; then
*** m4/obstack-printf-posix.m4.orig     2008-06-14 09:05:52.000000000 +0200
--- m4/obstack-printf-posix.m4  2008-06-14 08:24:19.000000000 +0200
***************
*** 1,4 ****
! # obstack-printf-posix.m4 serial 1
  dnl Copyright (C) 2008 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # obstack-printf-posix.m4 serial 2
  dnl Copyright (C) 2008 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 6,11 ****
--- 6,14 ----
  
  AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_POSIX],
  [
+   dnl Persuade glibc <stdio.h> to declare obstack_printf(), obstack_vprintf().
+   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+ 
    AC_REQUIRE([gl_PRINTF_SIZES_C99])
    AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
    AC_REQUIRE([gl_PRINTF_INFINITE])
***************
*** 20,80 ****
    AC_REQUIRE([gl_PRINTF_PRECISION])
    AC_REQUIRE([gl_PRINTF_ENOMEM])
    gl_cv_func_obstack_printf_posix=no
!   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)
!                                                       # obstack_printf exists 
and is
!                                                       # already POSIX 
compliant.
!                                                       
gl_cv_func_obstack_printf_posix= yes
!                                                       ;;
!                                                    esac
!                                                   ;;
!                                               esac
!                                               ;;
!                                           esac
!                                           ;;
!                                       esac
!                                       ;;
!                                   esac
!                                   ;;
!                               esac
!                               ;;
!                           esac
!                           ;;
!                       esac
!                       ;;
!                   esac
!                   ;;
!               esac
!               ;;
!           esac
!           ;;
!       esac
!       ;;
!   esac
    if test $gl_cv_func_obstack_printf_posix = no; then
      gl_PREREQ_VASNPRINTF_LONG_DOUBLE
      gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
--- 23,86 ----
    AC_REQUIRE([gl_PRINTF_PRECISION])
    AC_REQUIRE([gl_PRINTF_ENOMEM])
    gl_cv_func_obstack_printf_posix=no
!   AC_CHECK_FUNCS_ONCE([obstack_printf])
!   if test $ac_cv_func_obstack_printf = 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)
!                                                         # obstack_printf 
exists and is
!                                                         # already POSIX 
compliant.
!                                                         
gl_cv_func_obstack_printf_posix= yes
!                                                         ;;
!                                                     esac
!                                                     ;;
!                                                 esac
!                                                 ;;
!                                             esac
!                                             ;;
!                                         esac
!                                         ;;
!                                     esac
!                                     ;;
!                                 esac
!                                 ;;
!                             esac
!                             ;;
!                         esac
!                         ;;
!                     esac
!                     ;;
!                 esac
!                 ;;
!             esac
!             ;;
!         esac
!         ;;
!     esac
!   fi
    if test $gl_cv_func_obstack_printf_posix = no; then
      gl_PREREQ_VASNPRINTF_LONG_DOUBLE
      gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
*** modules/obstack-printf.orig 2008-06-14 09:05:52.000000000 +0200
--- modules/obstack-printf      2008-06-14 08:16:19.000000000 +0200
***************
*** 9,14 ****
--- 9,15 ----
  obstack
  stdio
  vasnprintf
+ extensions
  
  configure.ac:
  gl_FUNC_OBSTACK_PRINTF
***************
*** 17,23 ****
  Makefile.am:
  
  Include:
- "obstack.h"
  <stdio.h>
  
  License:
--- 18,23 ----
*** modules/obstack-printf-posix.orig   2008-06-14 09:05:52.000000000 +0200
--- modules/obstack-printf-posix        2008-06-14 08:16:23.000000000 +0200
***************
*** 10,15 ****
--- 10,16 ----
  obstack
  stdio
  vasnprintf-posix
+ extensions
  
  configure.ac:
  gl_FUNC_OBSTACK_PRINTF_POSIX
***************
*** 18,24 ****
  Makefile.am:
  
  Include:
- "obstack.h"
  <stdio.h>
  
  License:
--- 19,24 ----





reply via email to

[Prev in Thread] Current Thread [Next in Thread]