1. Revert change: downgrade gcc version from 5 to 4.9.
2. Add macro USE_UTF8_INSTEAD_OF_CODECVT to judge use codecvt or utf8.
This commit is contained in:
parent
2dc9fb50be
commit
72d86f91ed
|
@ -100,13 +100,14 @@ endif()
|
|||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
|
||||
if(NOT (GCC_VERSION VERSION_GREATER 4.9 OR GCC_VERSION VERSION_EQUAL 4.9))
|
||||
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.9 or greater.")
|
||||
# Just g++-5.0 and greater contain <codecvt> header. (test in ubuntu)
|
||||
if(NOT (GCC_VERSION VERSION_GREATER 5.0 OR GCC_VERSION VERSION_EQUAL 5.0))
|
||||
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 5.0 or greater.")
|
||||
endif ()
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND ANDROID)
|
||||
# Need -Os cflag and cxxflags here to work with exception handling on armeabi.
|
||||
# see https://github.com/android-ndk/ndk/issues/573
|
||||
# and without -stdlib=libc++ cxxflags
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND ANDROID)
|
||||
# Need -Os cflag and cxxflags here to work with exception handling on armeabi.
|
||||
# see https://github.com/android-ndk/ndk/issues/573
|
||||
# and without -stdlib=libc++ cxxflags
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND ( CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") )
|
||||
|
@ -120,7 +121,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND ( CMAKE_SYSTEM_NAME MATCH
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
endif()
|
||||
elseif(MSVC_VERSION GREATER 1800 OR MSVC_VERSION EQUAL 1800)
|
||||
# Visual Studio 2012+ supports c++11 features
|
||||
# Visual Studio 2012+ supports c++11 features
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
|
||||
else()
|
||||
|
@ -152,7 +153,7 @@ if (ANTLR4_INSTALL)
|
|||
|
||||
set(ANTLR4_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING
|
||||
"Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.")
|
||||
|
||||
|
||||
set(ANTLR4_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/antlr4-runtime CACHE STRING
|
||||
"Installation directory for include files, relative to ${CMAKE_INSTALL_PREFIX}.")
|
||||
|
||||
|
@ -160,18 +161,18 @@ if (ANTLR4_INSTALL)
|
|||
cmake/antlr4-runtime.cmake.in
|
||||
${project_runtime_config}
|
||||
INSTALL_DESTINATION ${ANTLR4_CMAKE_DIR}/antlr4-runtime
|
||||
PATH_VARS
|
||||
PATH_VARS
|
||||
ANTLR4_INCLUDE_DIR
|
||||
ANTLR4_LIB_DIR )
|
||||
|
||||
|
||||
configure_package_config_file(
|
||||
cmake/antlr4-generator.cmake.in
|
||||
${project_generator_config}
|
||||
INSTALL_DESTINATION ${ANTLR4_CMAKE_DIR}/antlr4-generator
|
||||
PATH_VARS
|
||||
PATH_VARS
|
||||
ANTLR4_INCLUDE_DIR
|
||||
ANTLR4_LIB_DIR )
|
||||
|
||||
|
||||
write_basic_package_version_file(
|
||||
${version_runtime_config}
|
||||
VERSION ${ANTLR_VERSION}
|
||||
|
@ -198,12 +199,12 @@ endif(ANTLR4_INSTALL)
|
|||
if(EXISTS LICENSE.txt)
|
||||
install(FILES LICENSE.txt
|
||||
DESTINATION "share/doc/libantlr4")
|
||||
elseif(EXISTS ../../LICENSE.txt)
|
||||
elseif(EXISTS ../../LICENSE.txt)
|
||||
install(FILES ../../LICENSE.txt
|
||||
DESTINATION "share/doc/libantlr4")
|
||||
endif()
|
||||
|
||||
install(FILES README.md VERSION
|
||||
install(FILES README.md VERSION
|
||||
DESTINATION "share/doc/libantlr4")
|
||||
|
||||
set(CPACK_PACKAGE_CONTACT "antlr-discussion@googlegroups.com")
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
#include <condition_variable>
|
||||
#include <functional>
|
||||
|
||||
#ifndef USE_UTF8_INSTEAD_OF_CODECVT
|
||||
#include <codecvt>
|
||||
#endif
|
||||
|
||||
// Defines for the Guid class and other platform dependent stuff.
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -51,12 +51,9 @@ namespace antlrcpp {
|
|||
}
|
||||
// else fall through
|
||||
#ifndef _MSC_VER
|
||||
// GCC 4.9 can't recognize clang::fallthrough.
|
||||
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC___ >= 5))
|
||||
#if __has_cpp_attribute(clang::fallthrough)
|
||||
[[clang::fallthrough]];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
|
|
@ -20,15 +20,25 @@ void replaceAll(std::string& str, std::string const& from, std::string const& to
|
|||
}
|
||||
|
||||
std::string ws2s(std::wstring const& wstr) {
|
||||
#ifndef USE_UTF8_INSTEAD_OF_CODECVT
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
std::string narrow = converter.to_bytes(wstr);
|
||||
#else
|
||||
std::string narrow;
|
||||
utf8::utf32to8(wstr.begin(), wstr.end(), std::back_inserter(narrow));
|
||||
#endif
|
||||
|
||||
return narrow;
|
||||
}
|
||||
|
||||
std::wstring s2ws(const std::string &str) {
|
||||
#ifndef USE_UTF8_INSTEAD_OF_CODECVT
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
std::wstring wide = converter.from_bytes(str);
|
||||
#else
|
||||
std::wstring wide;
|
||||
utf8::utf8to32(str.begin(), str.end(), std::back_inserter(wide));
|
||||
#endif
|
||||
|
||||
return wide;
|
||||
}
|
||||
|
|
|
@ -6,33 +6,66 @@
|
|||
#pragma once
|
||||
|
||||
#include "antlr4-common.h"
|
||||
|
||||
#ifdef USE_UTF8_INSTEAD_OF_CODECVT
|
||||
#include "utf8.h"
|
||||
#endif
|
||||
|
||||
namespace antlrcpp {
|
||||
|
||||
// I wouldn't prefer wstring_convert for two reasons:
|
||||
// 1. According to https://en.cppreference.com/w/cpp/locale/wstring_convert,
|
||||
// wstring_convert is deprecated in C++17.
|
||||
// 2. GCC 4.9 doesn't support codecvt header. And many projects still use
|
||||
// GCC 4.9 as compiler.
|
||||
// For all conversions utf8 <-> utf32.
|
||||
// I wouldn't prefer wstring_convert because: according to
|
||||
// https://en.cppreference.com/w/cpp/locale/wstring_convert,
|
||||
// wstring_convert is deprecated in C++17.
|
||||
// utfcpp (https://github.com/nemtrif/utfcpp) is a substitution.
|
||||
#ifndef USE_UTF8_INSTEAD_OF_CODECVT
|
||||
// VS 2015 and VS 2017 have different bugs in std::codecvt_utf8<char32_t> (VS 2013 works fine).
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
|
||||
typedef std::wstring_convert<std::codecvt_utf8<__int32>, __int32> UTF32Converter;
|
||||
#else
|
||||
typedef std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> UTF32Converter;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// The conversion functions fails in VS2017, so we explicitly use a workaround.
|
||||
template<typename T>
|
||||
inline std::string utf32_to_utf8(T const& data)
|
||||
{
|
||||
std::string narrow;
|
||||
utf8::utf32to8(data.begin(), data.end(), std::back_inserter(narrow));
|
||||
#ifndef USE_UTF8_INSTEAD_OF_CODECVT
|
||||
// Don't make the converter static or we have to serialize access to it.
|
||||
thread_local UTF32Converter converter;
|
||||
|
||||
return narrow;
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
|
||||
auto p = reinterpret_cast<const int32_t *>(data.data());
|
||||
return converter.to_bytes(p, p + data.size());
|
||||
#else
|
||||
return converter.to_bytes(data);
|
||||
#endif
|
||||
#else
|
||||
std::string narrow;
|
||||
utf8::utf32to8(data.begin(), data.end(), std::back_inserter(narrow));
|
||||
return narrow;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline UTF32String utf8_to_utf32(const char* first, const char* last)
|
||||
{
|
||||
UTF32String wide;
|
||||
utf8::utf8to32(first, last, std::back_inserter(wide));
|
||||
#ifndef USE_UTF8_INSTEAD_OF_CODECVT
|
||||
thread_local UTF32Converter converter;
|
||||
|
||||
return wide;
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
|
||||
auto r = converter.from_bytes(first, last);
|
||||
i32string s = reinterpret_cast<const int32_t *>(r.data());
|
||||
return s;
|
||||
#else
|
||||
std::u32string s = converter.from_bytes(first, last);
|
||||
return s;
|
||||
#endif
|
||||
#else
|
||||
UTF32String wide;
|
||||
utf8::utf8to32(first, last, std::back_inserter(wide));
|
||||
return wide;
|
||||
#endif
|
||||
}
|
||||
|
||||
void replaceAll(std::string &str, std::string const& from, std::string const& to);
|
||||
|
|
|
@ -109,12 +109,7 @@ ParseTreePattern ParseTreePatternMatcher::compile(const std::string &pattern, in
|
|||
throw e;
|
||||
#else
|
||||
} catch (std::exception & /*e*/) {
|
||||
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC___ >= 5))
|
||||
std::throw_with_nested((const char*)"Cannot invoke start rule"); // Wrap any other exception. We should however probably use one of the ANTLR exceptions here.
|
||||
#else
|
||||
// throw_with_nested doesn't accept const char* as argument in GCC 4.9.
|
||||
std::throw_with_nested(std::runtime_error("Cannot invoke start rule"));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue