From ce486056ecd28050f367894a2b5aad3656d37511 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Thu, 21 Aug 2014 09:56:44 +0300
Subject: [PATCH] Add #define INT64_MODIFIER for the printf length modifier for
 64-bit ints.

We have had INT64_FORMAT and UINT64_FORMAT for a long time, but that's not
good enough if you want something more exotic, like "%20lld".

Abhijit Menon-Sen, per Andres Freund's suggestion.
---
 config/c-library.m4           | 32 ++++++++++++-------------
 configure                     | 44 ++++++++++++++---------------------
 configure.in                  | 21 +++++++----------
 src/include/c.h               |  3 +++
 src/include/pg_config.h.in    |  7 ++----
 src/include/pg_config.h.win32 |  8 ++-----
 6 files changed, 49 insertions(+), 66 deletions(-)

diff --git a/config/c-library.m4 b/config/c-library.m4
index 8f450105937..4821a612921 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -221,22 +221,22 @@ HAVE_POSIX_SIGNALS=$pgac_cv_func_posix_signals
 AC_SUBST(HAVE_POSIX_SIGNALS)])# PGAC_FUNC_POSIX_SIGNALS
 
 
-# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT
+# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_MODIFIER
 # ---------------------------------------
-# Determine which format snprintf uses for long long int.  We handle
-# %lld, %qd, %I64d.  The result is in shell variable
-# LONG_LONG_INT_FORMAT.
+# Determine which length modifier snprintf uses for long long int.  We
+# handle ll, q, and I64.  The result is in shell variable
+# LONG_LONG_INT_MODIFIER.
 #
 # MinGW uses '%I64d', though gcc throws an warning with -Wall,
 # while '%lld' doesn't generate a warning, but doesn't work.
 #
-AC_DEFUN([PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT],
-[AC_MSG_CHECKING([snprintf format for long long int])
-AC_CACHE_VAL(pgac_cv_snprintf_long_long_int_format,
-[for pgac_format in '%lld' '%qd' '%I64d'; do
+AC_DEFUN([PGAC_FUNC_SNPRINTF_LONG_LONG_INT_MODIFIER],
+[AC_MSG_CHECKING([snprintf length modifier for long long int])
+AC_CACHE_VAL(pgac_cv_snprintf_long_long_int_modifier,
+[for pgac_modifier in 'll' 'q' 'I64'; do
 AC_TRY_RUN([#include <stdio.h>
 typedef long long int ac_int64;
-#define INT64_FORMAT "$pgac_format"
+#define INT64_FORMAT "%${pgac_modifier}d"
 
 ac_int64 a = 20000001;
 ac_int64 b = 40000005;
@@ -258,19 +258,19 @@ int does_int64_snprintf_work()
 main() {
   exit(! does_int64_snprintf_work());
 }],
-[pgac_cv_snprintf_long_long_int_format=$pgac_format; break],
+[pgac_cv_snprintf_long_long_int_modifier=$pgac_modifier; break],
 [],
-[pgac_cv_snprintf_long_long_int_format=cross; break])
+[pgac_cv_snprintf_long_long_int_modifier=cross; break])
 done])dnl AC_CACHE_VAL
 
-LONG_LONG_INT_FORMAT=''
+LONG_LONG_INT_MODIFIER=''
 
-case $pgac_cv_snprintf_long_long_int_format in
+case $pgac_cv_snprintf_long_long_int_modifier in
   cross) AC_MSG_RESULT([cannot test (not on host machine)]);;
-  ?*)    AC_MSG_RESULT([$pgac_cv_snprintf_long_long_int_format])
-         LONG_LONG_INT_FORMAT=$pgac_cv_snprintf_long_long_int_format;;
+  ?*)    AC_MSG_RESULT([$pgac_cv_snprintf_long_long_int_modifier])
+         LONG_LONG_INT_MODIFIER=$pgac_cv_snprintf_long_long_int_modifier;;
   *)     AC_MSG_RESULT(none);;
-esac])# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT
+esac])# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_MODIFIER
 
 
 # PGAC_FUNC_SNPRINTF_ARG_CONTROL
diff --git a/configure b/configure
index 0f435b5c946..25dc9befe6b 100755
--- a/configure
+++ b/configure
@@ -13095,20 +13095,20 @@ fi
 
 if test "$HAVE_LONG_LONG_INT_64" = yes ; then
   if test $pgac_need_repl_snprintf = no; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking snprintf format for long long int" >&5
-$as_echo_n "checking snprintf format for long long int... " >&6; }
-if ${pgac_cv_snprintf_long_long_int_format+:} false; then :
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking snprintf length modifier for long long int" >&5
+$as_echo_n "checking snprintf length modifier for long long int... " >&6; }
+if ${pgac_cv_snprintf_long_long_int_modifier+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  for pgac_format in '%lld' '%qd' '%I64d'; do
+  for pgac_modifier in 'll' 'q' 'I64'; do
 if test "$cross_compiling" = yes; then :
-  pgac_cv_snprintf_long_long_int_format=cross; break
+  pgac_cv_snprintf_long_long_int_modifier=cross; break
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdio.h>
 typedef long long int ac_int64;
-#define INT64_FORMAT "$pgac_format"
+#define INT64_FORMAT "%${pgac_modifier}d"
 
 ac_int64 a = 20000001;
 ac_int64 b = 40000005;
@@ -13132,7 +13132,7 @@ main() {
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
-  pgac_cv_snprintf_long_long_int_format=$pgac_format; break
+  pgac_cv_snprintf_long_long_int_modifier=$pgac_modifier; break
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
@@ -13141,44 +13141,36 @@ fi
 done
 fi
 
-LONG_LONG_INT_FORMAT=''
+LONG_LONG_INT_MODIFIER=''
 
-case $pgac_cv_snprintf_long_long_int_format in
+case $pgac_cv_snprintf_long_long_int_modifier in
   cross) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cannot test (not on host machine)" >&5
 $as_echo "cannot test (not on host machine)" >&6; };;
-  ?*)    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_snprintf_long_long_int_format" >&5
-$as_echo "$pgac_cv_snprintf_long_long_int_format" >&6; }
-         LONG_LONG_INT_FORMAT=$pgac_cv_snprintf_long_long_int_format;;
+  ?*)    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_snprintf_long_long_int_modifier" >&5
+$as_echo "$pgac_cv_snprintf_long_long_int_modifier" >&6; }
+         LONG_LONG_INT_MODIFIER=$pgac_cv_snprintf_long_long_int_modifier;;
   *)     { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
 $as_echo "none" >&6; };;
 esac
-    if test "$LONG_LONG_INT_FORMAT" = ""; then
+    if test "$LONG_LONG_INT_MODIFIER" = ""; then
       # Force usage of our own snprintf, since system snprintf is broken
       pgac_need_repl_snprintf=yes
-      LONG_LONG_INT_FORMAT='%lld'
+      LONG_LONG_INT_MODIFIER='ll'
     fi
   else
     # Here if we previously decided we needed to use our own snprintf
-    LONG_LONG_INT_FORMAT='%lld'
+    LONG_LONG_INT_MODIFIER='ll'
   fi
-  LONG_LONG_UINT_FORMAT=`echo "$LONG_LONG_INT_FORMAT" | sed 's/d$/u/'`
-  INT64_FORMAT="\"$LONG_LONG_INT_FORMAT\""
-  UINT64_FORMAT="\"$LONG_LONG_UINT_FORMAT\""
 else
   # Here if we are not using 'long long int' at all
-  INT64_FORMAT='"%ld"'
-  UINT64_FORMAT='"%lu"'
+  LONG_LONG_INT_MODIFIER='l'
 fi
 
-
-cat >>confdefs.h <<_ACEOF
-#define INT64_FORMAT $INT64_FORMAT
-_ACEOF
-
+INT64_MODIFIER="\"$LONG_LONG_INT_MODIFIER\""
 
 
 cat >>confdefs.h <<_ACEOF
-#define UINT64_FORMAT $UINT64_FORMAT
+#define INT64_MODIFIER $INT64_MODIFIER
 _ACEOF
 
 
diff --git a/configure.in b/configure.in
index f8a45070634..6393fffcf3b 100644
--- a/configure.in
+++ b/configure.in
@@ -1642,30 +1642,25 @@ fi
 
 if test "$HAVE_LONG_LONG_INT_64" = yes ; then
   if test $pgac_need_repl_snprintf = no; then
-    PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT
-    if test "$LONG_LONG_INT_FORMAT" = ""; then
+    PGAC_FUNC_SNPRINTF_LONG_LONG_INT_MODIFIER
+    if test "$LONG_LONG_INT_MODIFIER" = ""; then
       # Force usage of our own snprintf, since system snprintf is broken
       pgac_need_repl_snprintf=yes
-      LONG_LONG_INT_FORMAT='%lld'
+      LONG_LONG_INT_MODIFIER='ll'
     fi
   else
     # Here if we previously decided we needed to use our own snprintf
-    LONG_LONG_INT_FORMAT='%lld'
+    LONG_LONG_INT_MODIFIER='ll'
   fi
-  LONG_LONG_UINT_FORMAT=`echo "$LONG_LONG_INT_FORMAT" | sed 's/d$/u/'`
-  INT64_FORMAT="\"$LONG_LONG_INT_FORMAT\""
-  UINT64_FORMAT="\"$LONG_LONG_UINT_FORMAT\""
 else
   # Here if we are not using 'long long int' at all
-  INT64_FORMAT='"%ld"'
-  UINT64_FORMAT='"%lu"'
+  LONG_LONG_INT_MODIFIER='l'
 fi
 
-AC_DEFINE_UNQUOTED(INT64_FORMAT, $INT64_FORMAT,
-                   [Define to the appropriate snprintf format for 64-bit ints.])
+INT64_MODIFIER="\"$LONG_LONG_INT_MODIFIER\""
 
-AC_DEFINE_UNQUOTED(UINT64_FORMAT, $UINT64_FORMAT,
-                   [Define to the appropriate snprintf format for unsigned 64-bit ints.])
+AC_DEFINE_UNQUOTED(INT64_MODIFIER, $INT64_MODIFIER,
+                   [Define to the appropriate snprintf length modifier for 64-bit ints.])
 
 # Also force use of our snprintf if the system's doesn't support the %z flag.
 if test "$pgac_need_repl_snprintf" = no; then
diff --git a/src/include/c.h b/src/include/c.h
index a48a57a42b3..2ceaaf6c1d7 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -288,6 +288,9 @@ typedef unsigned long long int uint64;
 #define UINT64CONST(x) ((uint64) x)
 #endif
 
+/* snprintf format strings to use for 64-bit integers */
+#define INT64_FORMAT "%" INT64_MODIFIER "d"
+#define UINT64_FORMAT "%" INT64_MODIFIER "u"
 
 /* Select timestamp representation (float8 or int64) */
 #ifdef USE_INTEGER_DATETIMES
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 5bdfa470dcf..1ce37c8765b 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -653,8 +653,8 @@
 /* Define to 1 if your compiler understands __VA_ARGS__ in macros. */
 #undef HAVE__VA_ARGS
 
-/* Define to the appropriate snprintf format for 64-bit ints. */
-#undef INT64_FORMAT
+/* Define to the appropriate snprintf length modifier for 64-bit ints. */
+#undef INT64_MODIFIER
 
 /* Define to 1 if `locale_t' requires <xlocale.h>. */
 #undef LOCALE_T_IN_XLOCALE
@@ -744,9 +744,6 @@
 /* Define to 1 if your <sys/time.h> declares `struct tm'. */
 #undef TM_IN_SYS_TIME
 
-/* Define to the appropriate snprintf format for unsigned 64-bit ints. */
-#undef UINT64_FORMAT
-
 /* Define to 1 to build with assertion checks. (--enable-cassert) */
 #undef USE_ASSERT_CHECKING
 
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 00be15f230e..bce67a2b492 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -532,8 +532,8 @@
 /* Define to 1 if your compiler understands __VA_ARGS__ in macros. */
 #define HAVE__VA_ARGS 1
 
-/* Define to the appropriate snprintf format for 64-bit ints, if any. */
-#define INT64_FORMAT "%lld"
+/* Define to the appropriate snprintf length modifier for 64-bit ints. */
+#define INT64_MODIFIER "ll"
 
 /* Define to 1 if `locale_t' requires <xlocale.h>. */
 /* #undef LOCALE_T_IN_XLOCALE */
@@ -604,10 +604,6 @@
 /* Define to 1 if your <sys/time.h> declares `struct tm'. */
 /* #undef TM_IN_SYS_TIME */
 
-/* Define to the appropriate snprintf format for unsigned 64-bit ints, if any.
-   */
-#define UINT64_FORMAT "%llu"
-
 /* Define to 1 to build with assertion checks. (--enable-cassert) */
 /* #undef USE_ASSERT_CHECKING */
 
-- 
GitLab