Verified Commit 14452bf4 authored by Alberto Miranda's avatar Alberto Miranda ♨️
Browse files

Don't use boost::regex if std::regex is available

See #39.
parent b9d1ae5f
Loading
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -125,9 +125,19 @@ AX_BOOST_ASIO
AX_BOOST_PROGRAM_OPTIONS
AX_BOOST_THREAD

# only check for boost_regex if we are building tests
# only check for std::regex/boost::regex if we are building tests
AS_IF([test "x$is_enabled_build_tests" = "xyes"], 
      [ AX_BOOST_REGEX 
      [ 
        # check whether the compiler has a functional std::regex
        AX_GCC_WORKING_STD_REGEX
        AS_IF([test "x$gcc_has_working_std_regex" = xno],
              [
                # fallback to boost::regex
                AC_MSG_WARN([falling back to boost::regex because std::regex is not functional])
                AX_BOOST_REGEX 
              ], [])
        AM_CONDITIONAL([HAVE_WORKING_STD_REGEX], 
                       test x$GCC_HAS_WORKING_STD_REGEX = xyes)
        AC_CONFIG_FILES(tests/Makefile)
      ], [])

+67 −0
Original line number Diff line number Diff line
# SYNOPSIS
#
#   AX_GCC_WORKING_STD_REGEX
#
# DESCRIPTION
#
#   This macro checks if GCC has a working implementation of std::regex, since
#   GCC 4.7/4.8 provided only valid headers and function stubs. Further 
#   information is available:
#   <https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions>.
#
#   If the std::regex implementation is functional, the macro will set the 
#   variable 'gcc_has_working_std_regex' to 'yes' and AC_DEFINE the C preprocessor
#   variable HAVE_WORKING_STD_REGEX.
#
#   An automake conditional can be subsequently defined as
#       AM_CONDITIONAL([HAVE_WORKING_STD_REGEX], 
#                      [test x$gcc_has_working_std_regex = xyes])
#
# LICENSE
#
#   Copyright (c) 2019 Alberto Miranda <alberto.miranda@bsc.es>
#
#   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 10

AC_DEFUN([AX_GCC_WORKING_STD_REGEX],
[
    gcc_has_working_std_regex=no
    AC_CACHE_CHECK(
        [whether GCC has a working std::regex implementation],
        ax_cv_gcc_working_regex,
        [
            AC_LANG_PUSH([C++])
            AC_COMPILE_IFELSE([
                AC_LANG_PROGRAM(
                        [[ @%:@include <regex> ]],
                        [[
                           @%:@if __cplusplus >= 201103L &&                          \
                               (!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
                                   (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
                                   defined(_GLIBCXX_REGEX_STATE_LIMIT)            || \
                                       (defined(_GLIBCXX_RELEASE)                 && \
                                       _GLIBCXX_RELEASE > 4)))
                           @%:@define HAVE_WORKING_REGEX 1
                           @%:@else
                           @%:@define HAVE_WORKING_REGEX 0
                           @%:@error std::regex does not work
                           @%:@endif
                        ]]
                )],
                ax_cv_gcc_working_regex=yes,
                ax_cv_gcc_working_regex=no)
            AC_LANG_POP([C++])
        ]
    )

    if test "x$ax_cv_gcc_working_regex" = "xyes"; then
        gcc_has_working_std_regex=yes
        AC_DEFINE([HAVE_WORKING_STD_REGEX], [1],
                  [define if the std::regex implementation works as expected])
    fi
])
+8 −2
Original line number Diff line number Diff line
@@ -100,7 +100,6 @@ api_LDFLAGS = \
	@BOOST_PROGRAM_OPTIONS_LIB@	\
	@BOOST_SYSTEM_LIB@ \
	@BOOST_THREAD_LIB@ \
	@BOOST_REGEX_LIB@ \
	@PROTOBUF_LIBS@ \
	-no-install \
	-Wl,-rpath,$(top_builddir)/lib/.libs \
@@ -109,6 +108,10 @@ api_LDFLAGS = \
	$(top_builddir)/lib/libnornsctl_debug.la \
	$(END)

if !HAVE_WORKING_STD_REGEX
api_LDFLAGS += @BOOST_REGEX_LIB@
endif

EXTRA_api_DEPENDENCIES = \
	$(top_builddir)/src/liburd_aux.la \
	$(top_builddir)/lib/libnorns_debug.la \
@@ -178,13 +181,16 @@ core_LDFLAGS = \
	@BOOST_PROGRAM_OPTIONS_LIB@	\
	@BOOST_SYSTEM_LIB@ \
	@BOOST_THREAD_LIB@ \
	@BOOST_REGEX_LIB@ \
	@PROTOBUF_LIBS@ \
	$(top_builddir)/src/liburd_aux.la \
	$(top_builddir)/lib/libnorns_debug.la \
	$(top_builddir)/lib/libnornsctl_debug.la \
	$(END)

if !HAVE_WORKING_STD_REGEX
core_LDFLAGS += @BOOST_REGEX_LIB@
endif

EXTRA_core_DEPENDENCIES = \
	$(top_builddir)/src/liburd_aux.la \
	$(top_builddir)/lib/libnorns_debug.la \
+25 −0
Original line number Diff line number Diff line
@@ -35,12 +35,19 @@
 * SOFTWARE.                                                             *
 *************************************************************************/


#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>

#include <config.h>
#ifdef HAVE_WORKING_STD_REGEX
#include <regex>
#else
#include <boost/regex.hpp>
#endif
#include <iostream>

#include "catch.hpp"
@@ -93,6 +100,22 @@ create_config_file(const bfs::path& basedir,

    const bfs::path config_file = cfgdir / name;

#ifdef HAVE_WORKING_STD_REGEX

    auto outstr = std::regex_replace(config_file::cftemplate,
                                     std::regex("@localstatedir@"),
                                     cfgdir.string());

    outstr = std::regex_replace(outstr, 
            std::regex("(staging_directory:)\\s*?\".*?\"(,?)$"),
                         "\\1 \"" + stdir.string() + "\"\\2");

    for(const auto& r : reps) {
        outstr = std::regex_replace(outstr, std::regex(r.first), r.second);
    }

#else

    auto outstr = boost::regex_replace(config_file::cftemplate,
                                             boost::regex("@localstatedir@"),
                                             cfgdir.string());
@@ -105,6 +128,8 @@ create_config_file(const bfs::path& basedir,
        outstr = boost::regex_replace(outstr, boost::regex(r.first), r.second);
    }

#endif

    bfs::ofstream outf(config_file);
    outf << outstr;
    outf.close();