Fix ecpglib.h to declare bool consistently with c.h.
authorTom Lane <[email protected]>
Tue, 12 Nov 2019 18:00:04 +0000 (13:00 -0500)
committerTom Lane <[email protected]>
Tue, 12 Nov 2019 18:00:04 +0000 (13:00 -0500)
This completes the task begun in commit 1408d5d86, to synchronize
ECPG's exported definitions with the definition of bool used by
c.h (and, therefore, the one actually in use in the ECPG library).
On practically all modern platforms, ecpglib.h will now just
include <stdbool.h>, which should surprise nobody anymore.
That removes a header-inclusion-order hazard for ECPG clients,
who previously might get build failures or unexpected behavior
depending on whether they'd included <stdbool.h> themselves,
and if so, whether before or after ecpglib.h.

On platforms where sizeof(_Bool) is not 1 (only old PPC-based
Mac systems, as far as I know), things are still messy, as
inclusion of <stdbool.h> could still break ECPG client code.
There doesn't seem to be any clean fix for that, and given the
probably-negligible population of users who would care anymore,
it's not clear we should go far out of our way to cope with it.
This change at least fixes some header-inclusion-order hazards
for our own code, since c.h and ecpglib.h previously disagreed
on whether bool should be char or unsigned char.

To implement this with minimal invasion of ECPG client namespace,
move the choice of whether to rely on <stdbool.h> into configure,
and have it export a configuration symbol PG_USE_STDBOOL.

ecpglib.h no longer exports definitions for TRUE and FALSE,
only their lowercase brethren.  We could undo that if we get
push-back about it.

Ideally we'd back-patch this as far as v11, which is where c.h
started to rely on <stdbool.h>.  But the odds of creating problems
for formerly-working ECPG client code seem about as large as the
odds of fixing any non-working cases, so we'll just do this in HEAD.

Discussion: https://postgr.es/m/CAA4eK1LmaKO7Du9M9Lo=kxGU8sB6aL8fa3sF6z6d5yYYVe3BuQ@mail.gmail.com

configure
configure.in
src/backend/utils/fmgr/dfmgr.c
src/include/c.h
src/include/pg_config.h.in
src/include/pg_config.h.win32
src/interfaces/ecpg/include/ecpg_config.h.in
src/interfaces/ecpg/include/ecpglib.h
src/pl/plperl/plperl.h
src/tools/msvc/Solution.pm

index d6ce39452561b6b7dca04d1a00aafa8d6c05d437..629fe8ecf03215091817a63ebc04d65871ee2a45 100755 (executable)
--- a/configure
+++ b/configure
@@ -14786,6 +14786,12 @@ _ACEOF
 
 
 
+if test "$ac_cv_header_stdbool_h" = yes -a "$ac_cv_sizeof_bool" = 1; then
+
+$as_echo "#define PG_USE_STDBOOL 1" >>confdefs.h
+
+fi
+
 
 ##
 ## Functions, global variables
index 5bd31a876e8cfc23ad01336ffc572dffbd64b9f4..1ea1c465504427e2e51d4d87f99ea3d4f8c5ab18 100644 (file)
@@ -1593,6 +1593,13 @@ AC_CHECK_SIZEOF([bool], [],
 #include <stdbool.h>
 #endif])
 
+dnl We use <stdbool.h> if we have it and it declares type bool as having
+dnl size 1.  Otherwise, c.h will fall back to declaring bool as unsigned char.
+if test "$ac_cv_header_stdbool_h" = yes -a "$ac_cv_sizeof_bool" = 1; then
+  AC_DEFINE([PG_USE_STDBOOL], 1,
+            [Define to 1 to use <stdbool.h> to define type bool.])
+fi
+
 
 ##
 ## Functions, global variables
index be684786d640734faf4d304ec1b57a2e7fda9801..c8d2cef35fffed0c43b1fdad3c518ac7449a8896 100644 (file)
@@ -23,7 +23,7 @@
  * On macOS, <dlfcn.h> insists on including <stdbool.h>.  If we're not
  * using stdbool, undef bool to undo the damage.
  */
-#ifndef USE_STDBOOL
+#ifndef PG_USE_STDBOOL
 #ifdef bool
 #undef bool
 #endif
index c95acd35f7fec8a2eea082a8cb605ecba75044a9..802a731267f337931e56c806590bc13193fc8a93 100644 (file)
  * bool
  *             Boolean value, either true or false.
  *
- * Use stdbool.h if available and its bool has size 1.  That's useful for
+ * We use stdbool.h if available and its bool has size 1.  That's useful for
  * better compiler and debugger output and for compatibility with third-party
  * libraries.  But PostgreSQL currently cannot deal with bool of other sizes;
  * there are static assertions around the code to prevent that.
  *
  * For C++ compilers, we assume the compiler has a compatible built-in
  * definition of bool.
+ *
+ * See also the version of this code in src/interfaces/ecpg/include/ecpglib.h.
  */
 
 #ifndef __cplusplus
 
-#if defined(HAVE_STDBOOL_H) && SIZEOF_BOOL == 1
+#ifdef PG_USE_STDBOOL
 #include <stdbool.h>
-#define USE_STDBOOL 1
 #else
 
 #ifndef bool
@@ -316,7 +317,7 @@ typedef unsigned char bool;
 #define false  ((bool) 0)
 #endif
 
-#endif
+#endif                                                 /* not PG_USE_STDBOOL */
 #endif                                                 /* not C++ */
 
 
index 25a48d3ba78f07461a344547803f3b39f940ad31..fc22526b7e399021dd5cd52bb667f09ae2875478 100644 (file)
 /* Define to best printf format archetype, usually gnu_printf if available. */
 #undef PG_PRINTF_ATTRIBUTE
 
+/* Define to 1 to use <stdbool.h> to define type bool. */
+#undef PG_USE_STDBOOL
+
 /* PostgreSQL version as a string */
 #undef PG_VERSION
 
index 6b67fb06308f47d0b7cd0fa95e6150e6a6dfeaf9..6c98ef4916293a8c5f4900703552901e7ce102bc 100644 (file)
    (--with-krb-srvnam=NAME) */
 #define PG_KRB_SRVNAM "postgres"
 
+/* Define to 1 to use <stdbool.h> to define type bool. */
+#define PG_USE_STDBOOL 1
+
 /* A string containing the version number, platform, and C compiler */
 #define PG_VERSION_STR "Uninitialized version string (win32)"
 
index c18556130efce7c1f1ece9c8b8e0b3b2066ca9a9..17e93c40dbbad6900587c072eea49ce45f85c950 100644 (file)
@@ -10,6 +10,9 @@
 /* Define to 1 if `long long int' works and is 64 bits. */
 #undef HAVE_LONG_LONG_INT_64
 
+/* Define to 1 to use <stdbool.h> to define type bool. */
+#undef PG_USE_STDBOOL
+
 /* Define to 1 to build client libraries as thread-safe code.
  *    (--enable-thread-safety) */
 #undef ENABLE_THREAD_SAFETY
index de9c76aefc3f3ecc9f498afecb36a4e7c43c2991..c65073f15acc149e5605859a28337a4f307577c1 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * this is a small part of c.h since we don't want to leak all postgres
- * definitions into ecpg programs
+ * Client-visible declarations for ecpglib
+ *
  * src/interfaces/ecpg/include/ecpglib.h
  */
 
@@ -8,30 +8,40 @@
 #define _ECPGLIB_H
 
 #include "libpq-fe.h"
+#include "ecpg_config.h"
 #include "ecpgtype.h"
 #include "sqlca.h"
 #include <string.h>
 
+/*
+ * This is a small extract from c.h since we don't want to leak all postgres
+ * definitions into ecpg programs; but we need to know what bool is.
+ */
 #ifndef __cplusplus
-#ifndef bool
-#define bool char
-#endif                                                 /* ndef bool */
+
+#ifdef PG_USE_STDBOOL
+#include <stdbool.h>
+#else
+
+/*
+ * We assume bool has been defined if true and false are.  This avoids
+ * duplicate-typedef errors if this file is included after c.h.
+ */
+#if !(defined(true) && defined(false))
+typedef unsigned char bool;
+#endif
 
 #ifndef true
 #define true   ((bool) 1)
-#endif                                                 /* ndef true */
+#endif
+
 #ifndef false
 #define false  ((bool) 0)
-#endif                                                 /* ndef false */
-#endif                                                 /* not C++ */
+#endif
 
-#ifndef TRUE
-#define TRUE   1
-#endif                                                 /* TRUE */
+#endif                                                 /* not PG_USE_STDBOOL */
+#endif                                                 /* not C++ */
 
-#ifndef FALSE
-#define FALSE  0
-#endif                                                 /* FALSE */
 
 #ifdef __cplusplus
 extern "C"
index 3748158a86d857e4eb4425dc5cf5f47f5c3cd506..7ae3c69c0860bba297688bdb063dc05cd6a29411 100644 (file)
@@ -64,7 +64,7 @@
  * warnings.  If PostgreSQL does not but Perl does, we need to undefine bool
  * after we include the Perl headers; see below.
  */
-#ifdef USE_STDBOOL
+#ifdef PG_USE_STDBOOL
 #define HAS_BOOL 1
 #endif
 
  * makes bool a macro, but our own replacement is a typedef, so the undef
  * makes ours visible again).
  */
-#ifndef USE_STDBOOL
+#ifndef PG_USE_STDBOOL
 #ifdef bool
 #undef bool
 #endif
index a6958273ac12525f16cc323d57765d5908784517..7f179f194be641bde846b470b27641ee45cdb2b6 100644 (file)
@@ -513,6 +513,7 @@ sub GenerateFiles
                print $o <<EOF;
 #define HAVE_LONG_LONG_INT 1
 #define HAVE_LONG_LONG_INT_64 1
+#define PG_USE_STDBOOL 1
 #define ENABLE_THREAD_SAFETY 1
 EOF
                close($o);