From 261e15fe6d07e8385ac6dcce1422b59dc6d5171d Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Sun, 18 Dec 2022 00:38:01 +0200
Subject: [PATCH 38/38] Add configure check for C23 nullptr

- Adjust existing C++ nullptr arrangements so that they don't conflict
- Add meson build handling for both C23 and C++ nullptrs

See osdn #45486

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 Makefile.am                           |  1 +
 configure.ac                          |  2 ++
 gen_headers/freeciv_config.h.in       |  6 ++++++
 gen_headers/meson_freeciv_config.h.in |  6 ++++++
 m4/c++11.m4                           |  6 +++---
 m4/c23.m4                             | 20 ++++++++++++++++++++
 meson.build                           | 13 +++++++++++++
 utility/support.h                     | 10 ++++++++++
 8 files changed, 61 insertions(+), 3 deletions(-)
 create mode 100644 m4/c23.m4

diff --git a/Makefile.am b/Makefile.am
index 9e236b5ba2..2ff97900d3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,6 +31,7 @@ EXTRA_DIST =	autogen.sh 			\
 		m4/ax_cxx_compile_stdcxx.m4	\
 		m4/c99.m4			\
 		m4/c11.m4			\
+		m4/c23.m4			\
 		m4/c++11.m4			\
 		m4/codeset.m4			\
 		m4/compiler.m4			\
diff --git a/configure.ac b/configure.ac
index 521b128abe..b7b36cb516 100644
--- a/configure.ac
+++ b/configure.ac
@@ -773,6 +773,8 @@ FC_C11_AT_QUICK_EXIT
 
 FC_STATIC_STRLEN
 
+FC_C23_NULLPTR
+
 FC_CXX11_STATIC_ASSERT
 FC_CXX11_NULLPTR
 
diff --git a/gen_headers/freeciv_config.h.in b/gen_headers/freeciv_config.h.in
index fbadeb6562..322073491a 100644
--- a/gen_headers/freeciv_config.h.in
+++ b/gen_headers/freeciv_config.h.in
@@ -36,6 +36,12 @@
 /* Month next version will be released */
 #undef FREECIV_RELEASE_MONTH
 
+/* nullptr available at C */
+#undef FREECIV_HAVE_C23_NULLPTR
+
+/* nullptr available at C++ */
+#undef FREECIV_HAVE_CXX_NULLPTR
+
 /* Use C11 threads as thread implementation */
 #undef FREECIV_HAVE_C11_THREADS
 
diff --git a/gen_headers/meson_freeciv_config.h.in b/gen_headers/meson_freeciv_config.h.in
index d47c58ed80..2ad90fa6e8 100644
--- a/gen_headers/meson_freeciv_config.h.in
+++ b/gen_headers/meson_freeciv_config.h.in
@@ -27,6 +27,12 @@
 /* Is this freeciv-web instead of regular build */
 #mesondefine FREECIV_WEB
 
+/* nullptr available at C */
+#mesondefine FREECIV_HAVE_C23_NULLPTR
+
+/* nullptr available at C++ */
+#mesondefine FREECIV_HAVE_CXX_NULLPTR
+
 /* Use pthreads as thread implementation */
 #mesondefine FREECIV_HAVE_PTHREAD
 
diff --git a/m4/c++11.m4 b/m4/c++11.m4
index 989fc0c72c..c720462d21 100644
--- a/m4/c++11.m4
+++ b/m4/c++11.m4
@@ -17,7 +17,7 @@ AC_DEFUN([FC_CXX11_STATIC_ASSERT],
   fi
 ])
 
-# Check for C++11 nullptr, and define nullptr as '0' if it's missing
+# Check for C++11 nullptr, and define FREECIV_HAVE_CXX_NULLPTR if it's available
 #
 AC_DEFUN([FC_CXX11_NULLPTR],
 [
@@ -31,8 +31,8 @@ AC_DEFUN([FC_CXX11_NULLPTR],
 #endif]],
  [[ int *var = nullptr; ]])],
 [ac_cv_cxx11_nullptr=yes], [ac_cv_cxx11_nullptr=no])])
-    if test "x${ac_cv_cxx11_nullptr}" != "xyes" ; then
-      AC_DEFINE([nullptr], [0], [Fallback since C++11 nullptr not available])
+    if test "x${ac_cv_cxx11_nullptr}" = "xyes" ; then
+      AC_DEFINE([FREECIV_HAVE_CXX_NULLPTR], [1], [C++11 nullptr available])
     fi
     AC_LANG_POP([C++])
   fi
diff --git a/m4/c23.m4 b/m4/c23.m4
new file mode 100644
index 0000000000..63c2027b9a
--- /dev/null
+++ b/m4/c23.m4
@@ -0,0 +1,20 @@
+# Check for the presence of C23 features.
+
+# Check for C23 nullptr, and define FREECIV_HAVE_CXX_NULLPTR if it's available
+#
+AC_DEFUN([FC_C23_NULLPTR],
+[
+  AC_LANG_PUSH([C])
+  AC_CHECK_HEADERS([stddef])
+  AC_CACHE_CHECK([for C23 nullptr], [ac_cv_c23_nullptr],
+    [AC_LINK_IFELSE([AC_LANG_PROGRAM(
+[[#ifdef HAVE_STDDEF
+#include <stddef>
+#endif]],
+ [[ int *var = nullptr; ]])],
+[ac_cv_c23_nullptr=yes], [ac_cv_c23_nullptr=no])])
+  if test "x${ac_cv_c23_nullptr}" != "xyes" ; then
+    AC_DEFINE([FREECIV_HAVE_C23_NULLPTR], [1], [C23 nullptr available])
+  fi
+  AC_LANG_POP([C])
+])
diff --git a/meson.build b/meson.build
index 1cf13d6cd7..1ebee17f3c 100644
--- a/meson.build
+++ b/meson.build
@@ -2,6 +2,7 @@
 project('freeciv', ['c', 'cpp'], meson_version: '>= 0.57.0')
 
 c_compiler = meson.get_compiler('c')
+cxx_compiler = meson.get_compiler('cpp')
 
 if c_compiler.has_argument('-Wno-nonnull-compare')
   add_global_arguments('-Wno-nonnull-compare', language : 'c')
@@ -429,6 +430,18 @@ else
   mw_dep = []
 endif
 
+if c_compiler.compiles('''
+#include <stddef>
+int main(void) { int *var = nullptr; return 0; }''')
+  pub_conf_data.set('FREECIV_HAVE_C23_NULLPTR', 1)
+endif
+
+if cxx_compiler.compiles('''
+#include <cstddef>
+int main(void) { int *var = nullptr; return 0; }''')
+  pub_conf_data.set('FREECIV_HAVE_CXX_NULLPTR', 1)
+endif
+
 icu_dep = dependency('icu-uc')
 
 syslua = get_option('syslua')
diff --git a/utility/support.h b/utility/support.h
index a3cbb393bd..a5654addf6 100644
--- a/utility/support.h
+++ b/utility/support.h
@@ -46,6 +46,16 @@ extern "C" {
 #define TRUE true
 #define FALSE false
 
+#ifdef __cplusplus
+#ifndef FREECIV_HAVE_CXX_NULLPTR
+#define nullptr 0
+#endif
+#else
+#ifndef FREECIV_HAVE_C23_NULLPTR
+#define nullptr NULL
+#endif
+#endif
+
 #ifndef __cplusplus
 #if __BEOS__
 #include <posix/be_prim.h>
-- 
2.35.1