forked from Mirrors/openclonk
Fallback to Boost.Regex if <regex> is broken
A large number of g++ versions ship a <regex> that declares all of the required functions, but don't actually implement them, making using them result in a linker error. Fallback to Boost.Regex if the host C++11 <regex> implementation is broken; the interface is the same anyway, only differing in the containing namespace. Unfortunately, Boost.Regex is not a header-only library, but this is not a big deal because all major Linux distributions ship it, and Visual Studio implements <regex> since 2010 (the oldest version we still support).stable-5.4
parent
2686cfd6f0
commit
924e0538fc
|
@ -1,7 +1,7 @@
|
|||
# OpenClonk, http://www.openclonk.org
|
||||
#
|
||||
# Copyright (c) 2009-2011 Günther Brammer
|
||||
# Copyright (c) 2009-2012 Nicolas Hake
|
||||
# Copyright (c) 2009-2013 Nicolas Hake
|
||||
# Copyright (c) 2009 David Dormagen
|
||||
# Copyright (c) 2009-2012 Armin Burgmeier
|
||||
# Copyright (c) 2009-2010 Sven Eberhardt
|
||||
|
@ -106,6 +106,14 @@ CHECK_CXX_SOURCE_COMPILES("int main() { void *d = nullptr; }" HAVE_NULLPTR)
|
|||
CHECK_CXX_SOURCE_COMPILES("int main() { static_assert(true, \"\"); }" HAVE_STATIC_ASSERT)
|
||||
set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
|
||||
|
||||
# g++'s libstdc++ doesn't properly support <regex> until 4.8.1 (maybe later?).
|
||||
# They ship a header that declares functions, but they don't ship an
|
||||
# implementation for some things (like std::regex_iterator).
|
||||
# This needs to test *linking*, not compilation; cmake does both at the same
|
||||
# time, so the test below works.
|
||||
CHECK_CXX_SOURCE_COMPILES("#include <regex>\nint main() { std::cregex_iterator ri; }" HAVE_WORKING_REGEX)
|
||||
CMAKE_DEPENDENT_OPTION(USE_BOOST_REGEX "Use Boost.Regex even if the C++ runtime has a working implementation of <regex>" OFF "HAVE_WORKING_REGEX" ON)
|
||||
|
||||
if(MSVC_VERSION GREATER 1499)
|
||||
list(APPEND OC_CXX_FLAGS /MP)
|
||||
list(REMOVE_ITEM OC_CXX_FLAGS_DEBUG /Gm)
|
||||
|
@ -842,12 +850,8 @@ include(FindPNG)
|
|||
include(FindZLIB)
|
||||
include_directories(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
|
||||
|
||||
find_package("Boost" 1.40.0)
|
||||
if(NOT Boost_INCLUDE_DIR)
|
||||
message(SEND_ERROR "Could not find the Boost C++ Libraries")
|
||||
else()
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIR})
|
||||
endif()
|
||||
find_package("Boost" 1.40.0 REQUIRED)
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIR})
|
||||
|
||||
include(FindThreads)
|
||||
if(NOT WIN32)
|
||||
|
@ -1423,6 +1427,15 @@ if(HAVE_UPNP)
|
|||
target_link_libraries(openclonk ${UPNP_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(USE_BOOST_REGEX)
|
||||
SET(Boost_USE_STATIC_LIBS ON)
|
||||
find_package(Boost 1.40.0 REQUIRED COMPONENTS regex)
|
||||
# Disable automatic linking, we'll do it ourselves
|
||||
add_definitions(-DBOOST_REGEX_NO_LIB)
|
||||
target_link_libraries(libc4script ${Boost_REGEX_LIBRARY})
|
||||
target_link_libraries(c4group ${Boost_REGEX_LIBRARY})
|
||||
endif()
|
||||
|
||||
add_subdirectory(tests EXCLUDE_FROM_ALL)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
|
|
@ -181,6 +181,9 @@
|
|||
/* Developer mode */
|
||||
#cmakedefine WITH_DEVELOPER_MODE 1
|
||||
|
||||
/* Define to 1 if you want to use Boost.Regex instead of <regex>. */
|
||||
#cmakedefine USE_BOOST_REGEX 1
|
||||
|
||||
/* Glib */
|
||||
#cmakedefine WITH_GLIB 1
|
||||
|
||||
|
|
|
@ -38,7 +38,14 @@
|
|||
#include <C4Config.h>
|
||||
#include <C4Game.h>
|
||||
|
||||
#include <regex>
|
||||
#ifdef USE_BOOST_REGEX
|
||||
# undef new
|
||||
# include <boost/regex.hpp>
|
||||
namespace re = boost;
|
||||
#else
|
||||
# include <regex>
|
||||
namespace re = std;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
#ifdef HAVE_LANGINFO_H
|
||||
|
@ -390,7 +397,7 @@ namespace
|
|||
{
|
||||
std::string GetResStr(const char *id, const char *stringtbl)
|
||||
{
|
||||
static std::regex line_pattern("^([^=]+)=(.*)\\r?$", std::regex_constants::optimize);
|
||||
static re::regex line_pattern("^([^=]+)=(.*)\\r?$", re::regex_constants::optimize);
|
||||
assert(stringtbl);
|
||||
if (!stringtbl)
|
||||
{
|
||||
|
@ -401,7 +408,7 @@ namespace
|
|||
const char *begin = stringtbl;
|
||||
const char *end = begin + std::char_traits<char>::length(begin);
|
||||
|
||||
for (auto it = std::cregex_iterator(begin, end, line_pattern); it != std::cregex_iterator(); ++it)
|
||||
for (auto it = re::cregex_iterator(begin, end, line_pattern); it != re::cregex_iterator(); ++it)
|
||||
{
|
||||
assert(it->size() == 3);
|
||||
if (it->size() != 3)
|
||||
|
|
Loading…
Reference in New Issue