]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Support C++0x features where possible
authorAmos Jeffries <squid3@treenet.co.nz>
Tue, 2 Aug 2011 07:31:53 +0000 (19:31 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Tue, 2 Aug 2011 07:31:53 +0000 (19:31 +1200)
This tests for and enables -std=c++0x compiler support on build.

Due to auto_ptr deprecation pieces of the code and a hack to work
around incompatible cppunit code, are converted to use unique_ptr.

When C++0x is available it also tests and uses the nullptr definition
for extra type safety.

acinclude/ax_cxx_0x_types.m4 [new file with mode: 0644]
acinclude/ax_cxx_compile_stdcxx_0x.m4 [new file with mode: 0644]
compat/GnuRegex.c
compat/Makefile.am
compat/compat.h
compat/cppunit.h [new file with mode: 0644]
compat/types.h
configure.ac
include/snmp_impl.h
src/StoreEntryStream.h
src/mgr/Inquirer.cc

diff --git a/acinclude/ax_cxx_0x_types.m4 b/acinclude/ax_cxx_0x_types.m4
new file mode 100644 (file)
index 0000000..615a7de
--- /dev/null
@@ -0,0 +1,41 @@
+## Shamelessly copied from the DUNE sources under GPL version 2
+## 
+AC_DEFUN([AX_CXX_TYPE_NULLPTR],[
+  AC_REQUIRE([AC_PROG_CXX])
+  AC_LANG_PUSH([C++])
+  AC_MSG_CHECKING([whether nullptr is supported])
+  AC_TRY_COMPILE([],[char* ch = nullptr;], [
+    HAVE_NULLPTR=yes
+    AC_MSG_RESULT(yes)], [
+    HAVE_NULLPTR=no
+    AC_MSG_RESULT(no)])
+  if test "x$HAVE_NULLPTR" = xyes; then
+    AC_DEFINE(HAVE_NULLPTR, 1, [Define to 1 if nullptr is supported])
+  fi
+  AC_MSG_CHECKING([whether nullptr_t is supported])
+  AC_TRY_COMPILE([#include <cstddef>],[typedef nullptr_t peng;], [
+    HAVE_NULLPTR_T=yes
+    AC_MSG_RESULT(yes)], [
+    HAVE_NULLPTR_T=no
+    AC_MSG_RESULT(no)])
+  if test "x$HAVE_NULLPTR_T" = xyes; then
+    AC_DEFINE(HAVE_NULLPTR_T, 1, [Define to 1 if nullptr_t is supported])
+  fi
+  AC_LANG_POP
+])
+
+## Hand crafted for Squid under GPL version 2
+AC_DEFUN([AX_CXX_TYPE_UNIQUE_PTR],[
+  AC_REQUIRE([AC_PROG_CXX])
+  AC_LANG_PUSH([C++])
+  AC_MSG_CHECKING([whether std::unique_ptr<T> is supported])
+  AC_TRY_COMPILE([#include <memory>],[std::unique_ptr<char> c;], [
+    HAVE_UNIQUE_PTR=yes
+    AC_MSG_RESULT(yes)], [
+    HAVE_UNIQUE_PTR=no
+    AC_MSG_RESULT(no)])
+  if test "x$HAVE_UNIQUE_PTR" = xyes; then
+    AC_DEFINE(HAVE_UNIQUE_PTR, 1, [Define to 1 if std::unique_ptr<T> is supported])
+  fi
+  AC_LANG_POP
+])
diff --git a/acinclude/ax_cxx_compile_stdcxx_0x.m4 b/acinclude/ax_cxx_compile_stdcxx_0x.m4
new file mode 100644 (file)
index 0000000..a4e556f
--- /dev/null
@@ -0,0 +1,107 @@
+# ============================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_0x.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_COMPILE_STDCXX_0X
+#
+# DESCRIPTION
+#
+#   Check for baseline language coverage in the compiler for the C++0x
+#   standard.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 7
+
+AU_ALIAS([AC_CXX_COMPILE_STDCXX_0X], [AX_CXX_COMPILE_STDCXX_0X])
+AC_DEFUN([AX_CXX_COMPILE_STDCXX_0X], [
+  AC_CACHE_CHECK(if g++ supports C++0x features without additional flags,
+  ax_cv_cxx_compile_cxx0x_native,
+  [AC_LANG_SAVE
+  AC_LANG_CPLUSPLUS
+  AC_TRY_COMPILE([
+  template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+    typedef check<check<bool>> right_angle_brackets;
+
+    int a;
+    decltype(a) b;
+
+    typedef check<int> check_type;
+    check_type c;
+    check_type&& cr = static_cast<check_type&&>(c);],,
+  ax_cv_cxx_compile_cxx0x_native=yes, ax_cv_cxx_compile_cxx0x_native=no)
+  AC_LANG_RESTORE
+  ])
+
+  AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x,
+  ax_cv_cxx_compile_cxx0x_cxx,
+  [AC_LANG_SAVE
+  AC_LANG_CPLUSPLUS
+  ac_save_CXXFLAGS="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAGS -std=c++0x"
+  AC_TRY_COMPILE([
+  template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+    typedef check<check<bool>> right_angle_brackets;
+
+    int a;
+    decltype(a) b;
+
+    typedef check<int> check_type;
+    check_type c;
+    check_type&& cr = static_cast<check_type&&>(c);],,
+  ax_cv_cxx_compile_cxx0x_cxx=yes, ax_cv_cxx_compile_cxx0x_cxx=no)
+  CXXFLAGS="$ac_save_CXXFLAGS"
+  AC_LANG_RESTORE
+  ])
+
+  AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x,
+  ax_cv_cxx_compile_cxx0x_gxx,
+  [AC_LANG_SAVE
+  AC_LANG_CPLUSPLUS
+  ac_save_CXXFLAGS="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAGS -std=gnu++0x"
+  AC_TRY_COMPILE([
+  template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+    typedef check<check<bool>> right_angle_brackets;
+
+    int a;
+    decltype(a) b;
+
+    typedef check<int> check_type;
+    check_type c;
+    check_type&& cr = static_cast<check_type&&>(c);],,
+  ax_cv_cxx_compile_cxx0x_gxx=yes, ax_cv_cxx_compile_cxx0x_gxx=no)
+  CXXFLAGS="$ac_save_CXXFLAGS"
+  AC_LANG_RESTORE
+  ])
+
+  if test "$ax_cv_cxx_compile_cxx0x_native" = yes ||
+     test "$ax_cv_cxx_compile_cxx0x_cxx" = yes ||
+     test "$ax_cv_cxx_compile_cxx0x_gxx" = yes; then
+    AC_DEFINE(HAVE_STDCXX_0X,,[Define if g++ supports C++0x features. ])
+  fi
+])
index 33e3616b8dd5ad902d16d1f1ed61e79b27a358af..2717975b06f1ce0b416c07f88581343d928a99db 100644 (file)
@@ -158,10 +158,6 @@ static int re_match_2(struct re_pattern_buffer * buffer, const char *string1,
 #define ISUPPER(c) (isascii ((unsigned char)c) && isupper ((unsigned char)c))
 #define ISXDIGIT(c) (isascii ((unsigned char)c) && isxdigit ((unsigned char)c))
 
-#ifndef NULL
-#define NULL 0
-#endif
-
 /* We remove any previous definition of `SIGN_EXTEND_CHAR',
  * since ours (we hope) works properly with all combinations of
  * machines, compilers, `char' and `unsigned char' argument types.
index fc8238350e0bc731b880ce690fe6ad5eb13f3cca..f3e11fb387c7968652674376818681d508ec0336 100644 (file)
@@ -17,6 +17,7 @@ libcompat_squid_a_SOURCES = \
        compat.h \
        compat_shared.h \
        cpu.h \
+       cppunit.h \
        debug.cc \
        debug.h \
        drand48.h \
index e1de846f5b6dc60b7577e654faf645ecd7a6eab4..b964509f347f032b02ac23046925ecb6f54e6e2d 100644 (file)
 /* some functions are unsafe to be used in Squid. */
 #include "compat/unsafe.h"
 
+/* cppunit is not quite C++0x compatible yet */
+#include "compat/cppunit.h"
+
 #endif /* _SQUID_COMPAT_H */
diff --git a/compat/cppunit.h b/compat/cppunit.h
new file mode 100644 (file)
index 0000000..4ae60b6
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef SQUID_COMPAT_CPPUNIT_H
+#define SQUID_COMPAT_CPPUNIT_H
+
+// CPPUNIT test suite uses auto_ptr which is deprecated in C++0x
+
+#if defined(__cplusplus) && HAVE_UNIQUE_PTR
+#include <cppunit/extensions/HelperMacros.h>
+
+#undef CPPUNIT_TEST_SUITE_END
+
+// Clone from cppunit 1.12.1
+#define CPPUNIT_TEST_SUITE_END()                                               \
+    }                                                                          \
+                                                                               \
+    static CPPUNIT_NS::TestSuite *suite()                                      \
+    {                                                                          \
+      const CPPUNIT_NS::TestNamer &namer = getTestNamer__();                   \
+      std::unique_ptr<CPPUNIT_NS::TestSuite> suite(                            \
+             new CPPUNIT_NS::TestSuite( namer.getFixtureName() ));             \
+      CPPUNIT_NS::ConcretTestFixtureFactory<TestFixtureType> factory;          \
+      CPPUNIT_NS::TestSuiteBuilderContextBase context( *suite.get(),           \
+                                                       namer,                  \
+                                                       factory );              \
+      TestFixtureType::addTestsToSuite( context );                             \
+      return suite.release();                                                  \
+    }                                                                          \
+  private: /* dummy typedef so that the macro can still end with ';'*/         \
+    typedef int CppUnitDummyTypedefForSemiColonEnding__
+
+
+#endif /* HAVE_UNIQUE_PTR */
+
+#endif /* SQUID_COMPAT_CPPUNIT_H */
index 707a45191f62f38d056f3067ca87e75ca2840038..318ae10849d8763f21ccbe6c3f6806afeb5ec2c1 100644 (file)
@@ -138,4 +138,12 @@ typedef int socklen_t;
 typedef long mtyp_t;
 #endif
 
+#ifndef NULL
+#if defined(__cplusplus) && HAVE_NULLPTR
+#define NULL nullptr
+#else
+#define NULL 0
+#endif
+#endif
+
 #endif /* SQUID_TYPES_H */
index 17d09c03de5cf6007223db07fde1efe237a0e0fa..5babed57000129eaa368c682852224ee5e8937e9 100644 (file)
@@ -21,8 +21,11 @@ m4_include([acinclude/krb5.m4])
 m4_include([acinclude/pam.m4])
 m4_include([acinclude/pkg.m4])
 m4_include([acinclude/lib-checks.m4])
+m4_include([acinclude/ax_cxx_compile_stdcxx_0x.m4])
+m4_include([acinclude/ax_cxx_0x_types.m4])
 
 PRESET_CFLAGS="$CFLAGS"
+PRESET_CXXFLAGS="$CXXFLAGS"
 PRESET_LDFLAGS="$LDFLAGS"
 
 dnl Set default LDFLAGS
@@ -54,6 +57,12 @@ if test "x$squid_host_os" = "solaris" -a "x$GCC" != "x" ; then
        AC_USE_SYSTEM_EXTENSIONS
 fi
 
+# Check for C++0x compiler support
+AX_CXX_COMPILE_STDCXX_0X
+if test "x$ax_cv_cxx_compile_cxx0x_cxx" = "xyes"; then
+    CXXFLAGS="$CXXFLAGS -std=c++0x"
+fi
+
 # test for programs
 AC_PROG_RANLIB
 AC_PROG_CPP
@@ -2431,6 +2440,10 @@ AC_CHECK_SIZEOF(long)
 AC_CHECK_SIZEOF(off_t)
 AC_CHECK_SIZEOF(size_t)
 
+dnl Some C++0x types we try to use
+AX_CXX_TYPE_NULLPTR
+AX_CXX_TYPE_UNIQUE_PTR
+
 dnl On Solaris 9 x86, gcc may includes a "fixed" set of old system include files
 dnl that is incompatible with the updated Solaris header files.
 dnl For this reason, we must check if pad128_t and upad128_t are defined.
index c3c89d411ec38773351c56a001d418a2b9334d90..4350d6dc1d7e57d4f99798754dbf2b6b5317de39 100644 (file)
@@ -47,20 +47,6 @@ SOFTWARE.
 
 #define SID_MAX_LEN    64
 
-#if 0 /* defines performed globally by config.h */
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef TRUE
-#define TRUE   1
-#endif
-#ifndef FALSE
-#define FALSE  0
-#endif
-#endif /* dead code. */
-
 #define READ       1
 #define WRITE      0
 
index fb9b7157599d26013c020051ed778b02a8b12d3a..97511f38ee790407b0f797448a2b8f7bb2e6ac80 100644 (file)
@@ -70,7 +70,10 @@ protected:
             return traits_type::eof();
 
         if (aChar != traits_type::eof()) {
-            char chars[1] = {aChar};
+            // NP: cast because GCC promotes int_type to 32-bit type
+            //     std::basic_streambuf<char>::int_type {aka int}
+            //     despite the definition with 8-bit type value.
+            char chars[1] = {char(aChar)};
 
             if (aChar != traits_type::eof())
                 theEntry->append(chars, 1);
index 9c7432cc7349a522187c1913b41000f77941e80c..769bd4e7b693a279abe709360bb1a3fb31bf44f6 100644 (file)
@@ -70,17 +70,29 @@ Mgr::Inquirer::start()
     Must(Comm::IsConnOpen(conn));
     Must(aggrAction != NULL);
 
+#if HAVE_UNIQUE_PTR
+    std::unique_ptr<MemBuf> replyBuf;
+#else
     std::auto_ptr<MemBuf> replyBuf;
+#endif
     if (strands.empty()) {
         LOCAL_ARRAY(char, url, MAX_URL);
         snprintf(url, MAX_URL, "%s", aggrAction->command().params.httpUri.termedBuf());
         HttpRequest *req = HttpRequest::CreateFromUrl(url);
         ErrorState *err = errorCon(ERR_INVALID_URL, HTTP_NOT_FOUND, req);
+#if HAVE_UNIQUE_PTR
+        std::unique_ptr<HttpReply> reply(err->BuildHttpReply());
+#else
         std::auto_ptr<HttpReply> reply(err->BuildHttpReply());
+#endif
         replyBuf.reset(reply->pack());
         errorStateFree(err);
     } else {
+#if HAVE_UNIQUE_PTR
+        std::unique_ptr<HttpReply> reply(new HttpReply);
+#else
         std::auto_ptr<HttpReply> reply(new HttpReply);
+#endif
         reply->setHeaders(HTTP_OK, NULL, "text/plain", -1, squid_curtime, squid_curtime);
         reply->header.putStr(HDR_CONNECTION, "close"); // until we chunk response
         replyBuf.reset(reply->pack());