Re: Allowing printf("%m") only where it actually works - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Allowing printf("%m") only where it actually works
Date
Msg-id 16785.1539046036@sss.pgh.pa.us
Whole thread Raw
In response to Re: Allowing printf("%m") only where it actually works  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
So, circling back to the very beginning of this thread where I worried
about all the compile warnings we get on NetBSD-current, I'm pleased
to report that HEAD compiles warning-free so long as you define
PG_PRINTF_ATTRIBUTE to "__syslog__" rather than "gnu_printf".

So attached is a proposed patch to make configure check whether %m
works without a warning, and try "__syslog__" if "gnu_printf" does
not work for that.  (I did it in that order so that if NetBSD get
their heads screwed back on straight and stop complaining about
perfectly GNU-compliant code, we'll go back to selecting "gnu_printf".)

Any objections?

            regards, tom lane

diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index fb58c94..af2dea1 100644
*** a/config/c-compiler.m4
--- b/config/c-compiler.m4
*************** fi])# PGAC_C_SIGNED
*** 21,41 ****
  # -----------------------
  # Select the format archetype to be used by gcc to check printf-type functions.
  # We prefer "gnu_printf", as that most closely matches the features supported
! # by src/port/snprintf.c (particularly the %m conversion spec).
  AC_DEFUN([PGAC_PRINTF_ARCHETYPE],
  [AC_CACHE_CHECK([for printf format archetype], pgac_cv_printf_archetype,
  [ac_save_c_werror_flag=$ac_c_werror_flag
  ac_c_werror_flag=yes
  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
! [extern int
! pgac_write(int ignore, const char *fmt,...)
! __attribute__((format(gnu_printf, 2, 3)));], [])],
!                   [pgac_cv_printf_archetype=gnu_printf],
!                   [pgac_cv_printf_archetype=printf])
! ac_c_werror_flag=$ac_save_c_werror_flag])
! AC_DEFINE_UNQUOTED([PG_PRINTF_ATTRIBUTE], [$pgac_cv_printf_archetype],
!                    [Define to gnu_printf if compiler supports it, else printf.])
! ])# PGAC_PRINTF_ARCHETYPE


  # PGAC_TYPE_64BIT_INT(TYPE)
--- 21,56 ----
  # -----------------------
  # Select the format archetype to be used by gcc to check printf-type functions.
  # We prefer "gnu_printf", as that most closely matches the features supported
! # by src/port/snprintf.c (particularly the %m conversion spec).  However,
! # on some NetBSD versions, that doesn't work while "__syslog__" does.
! # If all else fails, use "printf".
  AC_DEFUN([PGAC_PRINTF_ARCHETYPE],
  [AC_CACHE_CHECK([for printf format archetype], pgac_cv_printf_archetype,
+ [pgac_cv_printf_archetype=gnu_printf
+ PGAC_TEST_PRINTF_ARCHETYPE
+ if [[ "$ac_archetype_ok" = no ]]; then
+   pgac_cv_printf_archetype=__syslog__
+   PGAC_TEST_PRINTF_ARCHETYPE
+   if [[ "$ac_archetype_ok" = no ]]; then
+     pgac_cv_printf_archetype=printf
+   fi
+ fi])
+ AC_DEFINE_UNQUOTED([PG_PRINTF_ATTRIBUTE], [$pgac_cv_printf_archetype],
+ [Define to best printf format archetype, usually gnu_printf if available.])
+ ])# PGAC_PRINTF_ARCHETYPE
+
+ # Subroutine: test $pgac_cv_printf_archetype, set $ac_archetype_ok to yes or no
+ AC_DEFUN([PGAC_TEST_PRINTF_ARCHETYPE],
  [ac_save_c_werror_flag=$ac_c_werror_flag
  ac_c_werror_flag=yes
  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
! [extern void pgac_write(int ignore, const char *fmt,...)
! __attribute__((format($pgac_cv_printf_archetype, 2, 3)));],
! [pgac_write(0, "error %s: %m", "foo");])],
!                   [ac_archetype_ok=yes],
!                   [ac_archetype_ok=no])
! ac_c_werror_flag=$ac_save_c_werror_flag
! ])# PGAC_TEST_PRINTF_ARCHETYPE


  # PGAC_TYPE_64BIT_INT(TYPE)
diff --git a/configure b/configure
index 0448c6b..b7250d7 100755
*** a/configure
--- b/configure
*************** $as_echo_n "checking for printf format a
*** 13583,13610 ****
  if ${pgac_cv_printf_archetype+:} false; then :
    $as_echo_n "(cached) " >&6
  else
!   ac_save_c_werror_flag=$ac_c_werror_flag
  ac_c_werror_flag=yes
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  /* end confdefs.h.  */
! extern int
! pgac_write(int ignore, const char *fmt,...)
! __attribute__((format(gnu_printf, 2, 3)));
  int
  main ()
  {

    ;
    return 0;
  }
  _ACEOF
  if ac_fn_c_try_compile "$LINENO"; then :
!   pgac_cv_printf_archetype=gnu_printf
  else
!   pgac_cv_printf_archetype=printf
  fi
  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  ac_c_werror_flag=$ac_save_c_werror_flag
  fi
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_printf_archetype" >&5
  $as_echo "$pgac_cv_printf_archetype" >&6; }
--- 13583,13639 ----
  if ${pgac_cv_printf_archetype+:} false; then :
    $as_echo_n "(cached) " >&6
  else
!   pgac_cv_printf_archetype=gnu_printf
! ac_save_c_werror_flag=$ac_c_werror_flag
  ac_c_werror_flag=yes
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  /* end confdefs.h.  */
! extern void pgac_write(int ignore, const char *fmt,...)
! __attribute__((format($pgac_cv_printf_archetype, 2, 3)));
  int
  main ()
  {
+ pgac_write(0, "error %s: %m", "foo");
+   ;
+   return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+   ac_archetype_ok=yes
+ else
+   ac_archetype_ok=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag

+ if [ "$ac_archetype_ok" = no ]; then
+   pgac_cv_printf_archetype=__syslog__
+   ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ extern void pgac_write(int ignore, const char *fmt,...)
+ __attribute__((format($pgac_cv_printf_archetype, 2, 3)));
+ int
+ main ()
+ {
+ pgac_write(0, "error %s: %m", "foo");
    ;
    return 0;
  }
  _ACEOF
  if ac_fn_c_try_compile "$LINENO"; then :
!   ac_archetype_ok=yes
  else
!   ac_archetype_ok=no
  fi
  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  ac_c_werror_flag=$ac_save_c_werror_flag
+
+   if [ "$ac_archetype_ok" = no ]; then
+     pgac_cv_printf_archetype=printf
+   fi
+ fi
  fi
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_printf_archetype" >&5
  $as_echo "$pgac_cv_printf_archetype" >&6; }
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 7894caa..9798bd2 100644
*** a/src/include/pg_config.h.in
--- b/src/include/pg_config.h.in
***************
*** 804,810 ****
  /* PostgreSQL major version as a string */
  #undef PG_MAJORVERSION

! /* Define to gnu_printf if compiler supports it, else printf. */
  #undef PG_PRINTF_ATTRIBUTE

  /* PostgreSQL version as a string */
--- 804,810 ----
  /* PostgreSQL major version as a string */
  #undef PG_MAJORVERSION

! /* Define to best printf format archetype, usually gnu_printf if available. */
  #undef PG_PRINTF_ATTRIBUTE

  /* PostgreSQL version as a string */

pgsql-hackers by date:

Previous
From: Thomas Munro
Date:
Subject: Re: DSM segment handle generation in background workers
Next
From: "Iwata, Aya"
Date:
Subject: RE: Function for listing archive_status directory