diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fce97b3b..a30364896 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,11 +230,6 @@ endif(LOG4CXX_QT_SUPPORT) # get_directory_property( HAS_LIBESMTP DIRECTORY src/main/include DEFINITION HAS_LIBESMTP ) get_directory_property( HAS_SYSLOG DIRECTORY src/main/include DEFINITION HAS_SYSLOG ) -get_directory_property( THREAD_IMPL DIRECTORY src DEFINITION THREAD_IMPL ) -get_directory_property( SMART_PTR_IMPL DIRECTORY src DEFINITION SMART_PTR_IMPL ) -get_directory_property( MUTEX_IMPL DIRECTORY src DEFINITION MUTEX_IMPL ) -get_directory_property( SHARED_MUTEX_IMPL DIRECTORY src DEFINITION SHARED_MUTEX_IMPL ) -get_directory_property( ATOMIC_IMPL DIRECTORY src DEFINITION ATOMIC_IMPL ) get_directory_property( FILESYSTEM_IMPL DIRECTORY src DEFINITION FILESYSTEM_IMPL ) get_directory_property( STD_MAKE_UNIQUE_IMPL DIRECTORY src DEFINITION STD_MAKE_UNIQUE_IMPL ) get_directory_property( STD_LIB_HAS_UNICODE_STRING DIRECTORY src DEFINITION STD_LIB_HAS_UNICODE_STRING ) @@ -310,12 +305,7 @@ message(STATUS " Qt support ...................... : ${LOG4CXX_QT_SUPPORT}") message(STATUS "C++ version and Boost settings:") message(STATUS " Prefer boost: ................... : ${PREFER_BOOST}") message(STATUS " make_unique implementation :..... : ${STD_MAKE_UNIQUE_IMPL}") -message(STATUS " thread implementation ........... : ${THREAD_IMPL}") message(STATUS " thread_local support? ........... : ${HAS_THREAD_LOCAL}") -message(STATUS " mutex implementation ............ : ${MUTEX_IMPL}") -message(STATUS " shared_ptr implementation ....... : ${SMART_PTR_IMPL}") -message(STATUS " shared_mutex implementation ..... : ${SHARED_MUTEX_IMPL}") -message(STATUS " atomic implementation ........... : ${ATOMIC_IMPL}") message(STATUS " filesystem implementation ....... : ${FILESYSTEM_IMPL}") if(BUILD_TESTING) diff --git a/src/cmake/boost-fallback/boost-fallback.cmake b/src/cmake/boost-fallback/boost-fallback.cmake index 1a0a8493c..93952a926 100644 --- a/src/cmake/boost-fallback/boost-fallback.cmake +++ b/src/cmake/boost-fallback/boost-fallback.cmake @@ -1,48 +1,4 @@ -#include(${CMAKE_MODULE_PATH}/FindPackageHandleStandardArgs.cmake) - -# Checks for classes in std::, falling back to boost if the requested -# classes are not available -# -# Available classes to check for: -# thread -# mutex -# shared_mutex -# filesystem -# -# Variables set: -# ${prefix}_ - -#function(_boost_fallback_thread) -# try_compile(HAS_STD_THREAD "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" -# "${CMAKE_CURRENT_LIST_DIR}/test-stdthread.cpp") - - -# find_package(boost_thread COMPONENTS thread) -#endfunction() - -## check for boost fallback instead of std:: classes -## arg1: prefix for variables to set -## arg2: list of classes to check for -#function(boost_fallback prefix classes) -#endfunction() - -# # This module checks for C++ standard classes and their boost counterparts -# -# Thread variables set: -# STD_THREAD_FOUND - if std::thread is found -# Boost_THREAD_FOUND - if boost::thread is found -# -# Mutex variables set: -# STD_MUTEX_FOUND - if std::mutex is found -# STD_SHARED_MUTEX_FOUND - if std::shared_mutex is found -# Boost_MUTEX_FOUND - if boost::mutex is found -# Boost_SHARED_MUTEX_FOUND - if boost::shared_mutex is found -# -# Smart pointer variables set: -# STD_SHARED_PTR_FOUND - if std::shared_ptr is found -# Boost_SHARED_PTR_FOUND - if boost::shared_ptr is found -# # Filesystem variables set: # STD_FILESYSTEM_FOUND - if std::filesystem is found # STD_EXPERIMENTAL_FILESYSTEM_FOUND - if std::experimental::filesystem is found @@ -50,101 +6,21 @@ include(FindThreads) -try_compile(STD_THREAD_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-stdthread.cpp") -try_compile(STD_MUTEX_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-stdmutex.cpp") -try_compile(STD_SHARED_MUTEX_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-stdsharedmutex.cpp") -try_compile(STD_SHARED_PTR_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-stdsharedptr.cpp") -try_compile(STD_ATOMIC_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-stdatomic.cpp") try_compile(STD_FILESYSTEM_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" "${CMAKE_CURRENT_LIST_DIR}/test-stdfilesystem.cpp") try_compile(STD_EXPERIMENTAL_FILESYSTEM_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" "${CMAKE_CURRENT_LIST_DIR}/test-stdexpfilesystem.cpp") -# We need to have all three boost components in order to run our tests -# Boost thread requires chrono and atomic to work -find_package(Boost COMPONENTS thread chrono atomic) -if( ${Boost_FOUND} ) - try_compile(Boost_SHARED_PTR_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-boostsharedptr.cpp") - try_compile(Boost_MUTEX_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-boostmutex.cpp") - try_compile(Boost_SHARED_MUTEX_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-boostsharedmutex.cpp" - LINK_LIBRARIES Threads::Threads Boost::thread) - try_compile(Boost_ATOMIC_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-boostatomic.cpp") -endif( ${Boost_FOUND} ) - -find_package(Boost COMPONENTS filesystem) -if( ${Boost_FOUND} ) - try_compile(Boost_FILESYSTEM_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" - "${CMAKE_CURRENT_LIST_DIR}/test-boostfilesystem.cpp") -endif( ${Boost_FOUND} ) - - -# Link the target with the appropriate boost libraries(if required) -function(boostfallback_link target) - if(NOT ${STD_THREAD_FOUND}) - if(${Boost_THREAD_FOUND}) - find_package(Boost COMPONENTS thread) - target_link_libraries( ${target} PUBLIC Boost::thread) - endif() - endif() - if(NOT ${STD_SHARED_MUTEX_FOUND}) - if(${Boost_SHARED_MUTEX_FOUND}) - find_package(Boost COMPONENTS thread) - target_link_libraries( ${target} PUBLIC Boost::thread) - endif() - endif() -endfunction() - # Check for standard headers that we need, fall back to boost if they're not found set(NAMESPACE_ALIAS log4cxx) option(PREFER_BOOST "Prefer Boost over std:: equivalents" OFF) -if( ${STD_THREAD_FOUND} AND NOT ${PREFER_BOOST} ) - set( THREAD_IMPL "std::thread" ) -elseif( ${Boost_THREAD_FOUND} ) - set( THREAD_IMPL "boost::thread" ) -else() - set( THREAD_IMPL "NONE" ) -endif() - -if( ${STD_MUTEX_FOUND} AND NOT ${PREFER_BOOST} ) - set( MUTEX_IMPL "std::mutex" ) -elseif( ${Boost_MUTEX_FOUND} ) - set( MUTEX_IMPL "boost::mutex" ) -else() - set( MUTEX_IMPL "NONE" ) -endif() - -if( ${STD_SHARED_PTR_FOUND} AND NOT ${PREFER_BOOST} ) - set( SMART_PTR_IMPL "std::shared_ptr" ) -elseif( ${Boost_SHARED_PTR_FOUND} ) - set( SMART_PTR_IMPL "boost::shared_ptr" ) -else() - set( SMART_PTR_IMPL "NONE" ) -endif() - -if( ${STD_SHARED_MUTEX_FOUND} AND NOT ${PREFER_BOOST} ) - set( SHARED_MUTEX_IMPL "std::shared_mutex" ) -elseif( ${Boost_SHARED_MUTEX_FOUND} ) - set( SHARED_MUTEX_IMPL "boost::shared_mutex" ) -else() - set( SHARED_MUTEX_IMPL "NONE" ) -endif() - -if( ${STD_ATOMIC_FOUND} AND NOT ${PREFER_BOOST} ) - set( ATOMIC_IMPL "std::atomic" ) -elseif( ${Boost_ATOMIC_FOUND} ) - set( ATOMIC_IMPL "boost::atomic" ) -else() - set( ATOMIC_IMPL "NONE" ) +if( ${PREFER_BOOST} OR NOT ( ${STD_FILESYSTEM_FOUND} OR ${STD_EXPERIMENTAL_FILESYSTEM_FOUND} ) ) + find_package(Boost COMPONENTS filesystem) + if( ${Boost_FOUND} ) + try_compile(Boost_FILESYSTEM_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests" + "${CMAKE_CURRENT_LIST_DIR}/test-boostfilesystem.cpp") + endif( ${Boost_FOUND} ) endif() if( ${STD_FILESYSTEM_FOUND} AND NOT ${PREFER_BOOST} ) diff --git a/src/cmake/boost-fallback/boost-std-configuration.h.cmake b/src/cmake/boost-fallback/boost-std-configuration.h.cmake index 9ccf8fd90..a56b21ff4 100644 --- a/src/cmake/boost-fallback/boost-std-configuration.h.cmake +++ b/src/cmake/boost-fallback/boost-std-configuration.h.cmake @@ -1,28 +1,10 @@ #ifndef BOOST_STD_CONFIGURATION_H #define BOOST_STD_CONFIGURATION_H -#cmakedefine01 STD_SHARED_MUTEX_FOUND -#cmakedefine01 Boost_SHARED_MUTEX_FOUND #cmakedefine01 STD_FILESYSTEM_FOUND #cmakedefine01 Boost_FILESYSTEM_FOUND #cmakedefine01 STD_EXPERIMENTAL_FILESYSTEM_FOUND -#if STD_SHARED_MUTEX_FOUND -#include -namespace ${NAMESPACE_ALIAS} { - typedef std::shared_mutex shared_mutex; - template - using shared_lock = std::shared_lock; -} -#elif Boost_SHARED_MUTEX_FOUND -#include -namespace ${NAMESPACE_ALIAS} { - typedef boost::shared_mutex shared_mutex; - template - using shared_lock = boost::shared_lock; -} -#endif - #if STD_FILESYSTEM_FOUND #include namespace ${NAMESPACE_ALIAS} { diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt index e4aa0ce17..be2dc4e00 100644 --- a/src/main/cpp/CMakeLists.txt +++ b/src/main/cpp/CMakeLists.txt @@ -206,7 +206,6 @@ set_target_properties(log4cxx PROPERTIES VERSION ${LIBLOG4CXX_LIB_VERSION} SOVERSION ${LIBLOG4CXX_LIB_SOVERSION} ) -boostfallback_link(log4cxx) get_directory_property( FILESYSTEM_IMPL DIRECTORY "${LOG4CXX_SOURCE_DIR}/src/main/include" DEFINITION FILESYSTEM_IMPL ) if("${FILESYSTEM_IMPL}" STREQUAL "std::filesystem" OR "${FILESYSTEM_IMPL}" STREQUAL "std::experimental::filesystem" ) diff --git a/src/main/cpp/charsetdecoder.cpp b/src/main/cpp/charsetdecoder.cpp index 551679ad0..b3c8539bf 100644 --- a/src/main/cpp/charsetdecoder.cpp +++ b/src/main/cpp/charsetdecoder.cpp @@ -14,11 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define NOMINMAX /* tell windows not to define min/max macros */ #include #include #include #include #include +#include #include #if !defined(LOG4CXX) #define LOG4CXX 1 @@ -165,21 +167,14 @@ class MbstowcsCharsetDecoder : public CharsetDecoder { log4cxx_status_t stat = APR_SUCCESS; enum { BUFSIZE = 256 }; - wchar_t buf[BUFSIZE]; + wchar_t wbuf[BUFSIZE]; + char cbuf[BUFSIZE*4]; mbstate_t mbstate; memset(&mbstate, 0, sizeof(mbstate)); while (in.remaining() > 0) { - size_t requested = in.remaining(); - - if (requested > BUFSIZE - 1) - { - requested = BUFSIZE - 1; - } - - memset(buf, 0, BUFSIZE * sizeof(wchar_t)); const char* src = in.current(); if (*src == 0) @@ -189,21 +184,31 @@ class MbstowcsCharsetDecoder : public CharsetDecoder } else { - size_t converted = mbsrtowcs(buf, + auto available = std::min(sizeof (cbuf) - 1, in.remaining()); + strncpy(cbuf, src, available); + cbuf[available] = 0; + src = cbuf; + size_t wCharCount = mbsrtowcs(wbuf, &src, - requested, + BUFSIZE - 1, &mbstate); + auto converted = src - cbuf; + in.position(in.position() + converted); - if (converted == (size_t) -1) + if (wCharCount == (size_t) -1) // Illegal byte sequence? { - stat = APR_BADARG; - in.position(src - in.data()); + LogString msg(LOG4CXX_STR("Illegal byte sequence at ")); + msg.append(std::to_wstring(in.position())); + msg.append(LOG4CXX_STR(" of ")); + msg.append(std::to_wstring(in.limit())); + LogLog::warn(msg); + stat = APR_BADCH; break; } else { - stat = append(out, buf); - in.position(in.position() + requested); + wbuf[wCharCount] = 0; + stat = append(out, wbuf); } } } @@ -418,73 +423,60 @@ class USASCIICharsetDecoder : public CharsetDecoder }; /** - * Charset decoder that uses an embedded CharsetDecoder consistent - * with current locale settings. + * Charset decoder that uses current locale settings. */ class LocaleCharsetDecoder : public CharsetDecoder { public: - LocaleCharsetDecoder() : pool(), decoder(), encoding() + LocaleCharsetDecoder() : state() { } - virtual ~LocaleCharsetDecoder() - { - } - virtual log4cxx_status_t decode(ByteBuffer& in, - LogString& out) + log4cxx_status_t decode(ByteBuffer& in, LogString& out) override { + log4cxx_status_t result = APR_SUCCESS; const char* p = in.current(); size_t i = in.position(); + size_t remain = in.limit() - i; #if !LOG4CXX_CHARSET_EBCDIC - - for (; i < in.limit() && ((unsigned int) *p) < 0x80; i++, p++) + if (std::mbsinit(&this->state)) // ByteBuffer not partially decoded? { - out.append(1, *p); + // Copy single byte characters + for (; 0 < remain && ((unsigned int) *p) < 0x80; --remain, ++i, p++) + { + out.append(1, *p); + } } - - in.position(i); #endif - - if (i < in.limit()) + // Decode characters that may be represented by multiple bytes + while (0 < remain) { - Pool subpool; - const char* enc = apr_os_locale_encoding(subpool.getAPRPool()); + wchar_t ch; + size_t n = std::mbrtowc(&ch, p, remain, &this->state); + if (0 == n) // NULL encountered? { - std::unique_lock lock(mutex); - - if (enc == 0) - { - if (decoder == 0) - { - encoding = "C"; - decoder.reset( new USASCIICharsetDecoder() ); - } - } - else if (encoding != enc) - { - encoding = enc; - - try - { - LOG4CXX_DECODE_CHAR(e, encoding); - decoder = getDecoder(e); - } - catch (IllegalArgumentException&) - { - decoder.reset( new USASCIICharsetDecoder() ); - } - } + ++i; + break; + } + if (static_cast(-1) == n) // decoding error? + { + result = APR_BADARG; + break; } - return decoder->decode(in, out); + if (static_cast(-2) == n) // incomplete sequence? + { + break; + } + Transcoder::encode(static_cast(ch), out); + remain -= n; + i += n; + p += n; } - - return APR_SUCCESS; + in.position(i); + return result; } + private: - Pool pool; - std::mutex mutex; - CharsetDecoderPtr decoder; - std::string encoding; + std::mbstate_t state; }; @@ -561,7 +553,8 @@ CharsetDecoderPtr CharsetDecoder::getISOLatinDecoder() CharsetDecoderPtr CharsetDecoder::getDecoder(const LogString& charset) { if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-8"), LOG4CXX_STR("utf-8")) || - StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF8"), LOG4CXX_STR("utf8"))) + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF8"), LOG4CXX_STR("utf8")) || + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP65001"), LOG4CXX_STR("cp65001"))) { return std::make_shared(); } @@ -569,12 +562,14 @@ CharsetDecoderPtr CharsetDecoder::getDecoder(const LogString& charset) charset == LOG4CXX_STR("646") || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("US-ASCII"), LOG4CXX_STR("us-ascii")) || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO646-US"), LOG4CXX_STR("iso646-US")) || - StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ANSI_X3.4-1968"), LOG4CXX_STR("ansi_x3.4-1968"))) + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ANSI_X3.4-1968"), LOG4CXX_STR("ansi_x3.4-1968")) || + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP20127"), LOG4CXX_STR("cp20127"))) { return std::make_shared(); } else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-8859-1"), LOG4CXX_STR("iso-8859-1")) || - StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-LATIN-1"), LOG4CXX_STR("iso-latin-1"))) + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-LATIN-1"), LOG4CXX_STR("iso-latin-1")) || + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP1252"), LOG4CXX_STR("cp1252"))) { return std::make_shared(); } diff --git a/src/main/cpp/charsetencoder.cpp b/src/main/cpp/charsetencoder.cpp index 82047dddd..3c075a357 100644 --- a/src/main/cpp/charsetencoder.cpp +++ b/src/main/cpp/charsetencoder.cpp @@ -446,79 +446,54 @@ class UTF16LECharsetEncoder : public CharsetEncoder }; /** - * Charset encoder that uses an embedded CharsetEncoder consistent - * with current locale settings. + * Charset encoder that uses current locale settings. */ class LocaleCharsetEncoder : public CharsetEncoder { public: - LocaleCharsetEncoder() : pool(), encoder(), encoding() + LocaleCharsetEncoder() : state() { } - virtual ~LocaleCharsetEncoder() - { - } - virtual log4cxx_status_t encode(const LogString& in, - LogString::const_iterator& iter, - ByteBuffer& out) + log4cxx_status_t encode + ( const LogString& in + , LogString::const_iterator& iter + , ByteBuffer& out + ) override { + log4cxx_status_t result = APR_SUCCESS; #if !LOG4CXX_CHARSET_EBCDIC char* current = out.current(); size_t remain = out.remaining(); - - for (; - iter != in.end() && ((unsigned int) *iter) < 0x80 && remain > 0; - iter++, remain--, current++) + if (std::mbsinit(&this->state)) // ByteBuffer not partially encoded? { - *current = *iter; + // Copy single byte characters + for (; + iter != in.end() && ((unsigned int) *iter) < 0x80 && 0 < remain; + iter++, remain--, current++) + { + *current = *iter; + } } - - out.position(current - out.data()); #endif - - if (iter != in.end() && out.remaining() > 0) + // Encode characters that may require multiple bytes + while (iter != in.end() && MB_CUR_MAX <= remain) { - Pool subpool; - const char* enc = apr_os_locale_encoding(subpool.getAPRPool()); + auto ch = Transcoder::decode(in, iter); + auto n = std::wcrtomb(current, ch, &this->state); + if (static_cast(-1) == n) // not a valid wide character? { - std::unique_lock lock(mutex); - - if (enc == 0) - { - if (encoder == 0) - { - encoding = "C"; - encoder.reset( new USASCIICharsetEncoder() ); - } - } - else if (encoding != enc) - { - encoding = enc; - LOG4CXX_DECODE_CHAR(ename, encoding); - - try - { - encoder = CharsetEncoder::getEncoder(ename); - } - catch (IllegalArgumentException&) - { - encoder.reset( new USASCIICharsetEncoder() ); - } - } + result = APR_BADARG; + break; } - return encoder->encode(in, iter, out); + remain -= n; + current += n; } - - return APR_SUCCESS; + out.position(current - out.data()); + return result; } private: - LocaleCharsetEncoder(const LocaleCharsetEncoder&); - LocaleCharsetEncoder& operator=(const LocaleCharsetEncoder&); - Pool pool; - std::mutex mutex; - CharsetEncoderPtr encoder; - std::string encoding; + std::mbstate_t state; }; @@ -578,7 +553,8 @@ CharsetEncoderPtr CharsetEncoder::getUTF8Encoder() CharsetEncoderPtr CharsetEncoder::getEncoder(const LogString& charset) { - if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-8"), LOG4CXX_STR("utf-8"))) + if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-8"), LOG4CXX_STR("utf-8")) + || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP65001"), LOG4CXX_STR("cp65001"))) { return std::make_shared(); } @@ -586,17 +562,20 @@ CharsetEncoderPtr CharsetEncoder::getEncoder(const LogString& charset) charset == LOG4CXX_STR("646") || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("US-ASCII"), LOG4CXX_STR("us-ascii")) || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO646-US"), LOG4CXX_STR("iso646-US")) || - StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ANSI_X3.4-1968"), LOG4CXX_STR("ansi_x3.4-1968"))) + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ANSI_X3.4-1968"), LOG4CXX_STR("ansi_x3.4-1968")) || + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP20127"), LOG4CXX_STR("cp20127"))) { return std::make_shared(); } else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-8859-1"), LOG4CXX_STR("iso-8859-1")) || - StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-LATIN-1"), LOG4CXX_STR("iso-latin-1"))) + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-LATIN-1"), LOG4CXX_STR("iso-latin-1")) || + StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP1252"), LOG4CXX_STR("cp1252"))) { return std::make_shared(); } else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16BE"), LOG4CXX_STR("utf-16be")) - || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16"), LOG4CXX_STR("utf-16"))) + || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16"), LOG4CXX_STR("utf-16")) + || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP1200"), LOG4CXX_STR("cp1200"))) { return std::make_shared(); } diff --git a/src/main/cpp/exception.cpp b/src/main/cpp/exception.cpp index 5daed6414..a6d06b08b 100644 --- a/src/main/cpp/exception.cpp +++ b/src/main/cpp/exception.cpp @@ -172,7 +172,7 @@ IOException& IOException::operator=(const IOException& src) LogString IOException::formatMessage(log4cxx_status_t stat) { - char err_buff[32]; + char err_buff[1024]; LogString s(LOG4CXX_STR("IO Exception : status code = ")); Pool p; StringHelper::toString(stat, p, s); diff --git a/src/site/markdown/1-usage.md b/src/site/markdown/1-usage.md index ee88b2e29..76098f432 100644 --- a/src/site/markdown/1-usage.md +++ b/src/site/markdown/1-usage.md @@ -1,4 +1,4 @@ -Usage {#usage-overview} +Use {#usage-overview} === + + +See the following pages for information on building Log4cxx: + +* @subpage building +* @subpage dependencies +* @subpage build-cmake +* @subpage build-vcpkg diff --git a/src/site/markdown/3-development.md b/src/site/markdown/6-development.md similarity index 88% rename from src/site/markdown/3-development.md rename to src/site/markdown/6-development.md index 989943367..a1bf9a8d3 100644 --- a/src/site/markdown/3-development.md +++ b/src/site/markdown/6-development.md @@ -1,4 +1,4 @@ -Development {#development-overview} +Develop {#development-overview} === - -# Building Apache Log4cxx with CMake +[TOC] ## Quick start: @@ -43,22 +42,22 @@ $ sudo make install Windows Example: Building and testing Log4cxx on a Microsoft Windows with APR, Expat and APR-Util built from source -extracted into apr-1.7.0, libexpat(from github) and apr-util-1.6.1 in %HOMEPATH%/Libraries. +extracted into apr-1.7.4, libexpat(from github) and apr-util-1.6.3 in %HOMEPATH%/Libraries. ~~~ $ cd %HOMEPATH%/Libraries $ cmake -S libexpat/expat -B buildtrees/expat -DCMAKE_INSTALL_PREFIX=%HOMEPATH%/Libraries/installed $ cmake --build buildtrees/expat --target install --config Release -$ cmake -S apr-1.7.0 -B buildtrees/apr -DCMAKE_INSTALL_PREFIX=%HOMEPATH%/Libraries/installed +$ cmake -S apr-1.7.4 -B buildtrees/apr -DCMAKE_INSTALL_PREFIX=%HOMEPATH%/Libraries/installed $ cmake --build buildtrees/apr --target install --config Release $ set CMAKE_PREFIX_PATH=%HOMEPATH%/Libraries/installed -$ cmake -S apr-util-1.6.1 -B buildtrees/apr-util -DCMAKE_INSTALL_PREFIX=%HOMEPATH%/Libraries/installed +$ cmake -S apr-util-1.6.3 -B buildtrees/apr-util -DCMAKE_INSTALL_PREFIX=%HOMEPATH%/Libraries/installed $ cmake --build buildtrees/apr-util --target install --config Release $ cmake -S apache-Log4cxx-x.x.x -B buildtrees/Log4cxx -DCMAKE_INSTALL_PREFIX=%HOMEPATH%/Libraries/installed $ cmake --build buildtrees/Log4cxx --target install --config Release ~~~ -## ccmake options +## CMake options | Option | Usage | |------------------------|-------| @@ -73,21 +72,6 @@ $ cmake --build buildtrees/Log4cxx --target install --config Release | -DPREFER_BOOST=on | Prefer the Boost version of dependent libraries over standard library | | -DLOG4CXX_QT_SUPPORT=ON | Enable QString API and log4cxx::qt namespace methods, requires QtCore, choice of ON, OFF (default). | -## A note on C++ version and Boost - -By default, Log4cxx attempts to use at least C++17 to compile. This is to -avoid 3rd party dependencies as much as possible. If C++17 is not -available, a search for Boost will be taken and those libaries will be used -instead. If you would prefer to use Boost, there are two options you have: - -1. Pass `-DPREFER_BOOST=ON` to CMake when compiling. This will ignore the - results of the tests that check for the standard version of components that - are required. Note that this will switch all components, regardless of the - C++ version in effect at compile time. -2. Revert to an earlier standard using `-DCMAKE_CXX_STANDARD=11` for example. - This will still to check for standard versions of required components, but - it will fall back to using Boost for newer components added in C++17. - # Platform specific notes: ## Mac OS/X: @@ -107,9 +91,9 @@ $ sudo apt-get install libssl-dev libapr1-dev libaprutil1-dev gzip zip CMake can be built from source by typing: ~~~ -$ wget https://github.com/Kitware/CMake/releases/download/v3.16.4/cmake-3.16.4.tar.gz -$ tar xf cmake-3.16.4.tar.gz -$ cd cmake-3.16.4 +$ wget https://github.com/Kitware/CMake/releases/download/v3.27.2/cmake-3.27.2.tar.gz +$ tar xf cmake-3.27.2.tar.gz +$ cd cmake-3.27.2 $ ./bootstrap $ make $ sudo make install diff --git a/src/site/markdown/development/building.md b/src/site/markdown/development/building.md index abc696c6e..6aab32c77 100644 --- a/src/site/markdown/development/building.md +++ b/src/site/markdown/development/building.md @@ -29,6 +29,17 @@ information. If you have trouble building, either create an issue in [Jira](https://issues.apache.org/jira/projects/LOGCXX/issues) or send a message to the [users mailing list]. +## Covered by Github + +These Github provided environments are +used in continuous integration and unit testing: + +* Windows - Visual Studio 2019 and 2022 +* Ubuntu 20.04 - GNU g++ 9.4.0, Clang 11.0.0 +* Ubuntu 22.04 - GNU g++ 11.4.0, Clang 14.0.0 +* MacOS 11 - AppleClang 13.0 +* MacOS 12 - AppleClang 14.0 + ## Covered by the team The following list provides an overview about the environments some of the @@ -38,8 +49,9 @@ something about how good the support on each platform is, it's just a guide. The following platforms/compilers are expected to work correctly: -* Windows 10(32 and 64-bit) - MSVC +* Windows 10(32 and 64-bit) - MSVC 2017, 2019 * Windows 10(32-bit) - Embarcadero C++ Builder XE 4 +* Windows 11(64-bit) - MSVC 2019, 2022 * Debian 10(32 and 64-bit) - gcc 8.3.0, clang-7 * Ubuntu 20.04(32 and 64-bit) - gcc, clang * Mac OSX - clang diff --git a/src/site/markdown/development/dependencies.md b/src/site/markdown/development/dependencies.md index 3b6641f0e..acf980e56 100644 --- a/src/site/markdown/development/dependencies.md +++ b/src/site/markdown/development/dependencies.md @@ -1,4 +1,4 @@ -Dependencies {#dependencies} +Log4cxx Dependencies {#dependencies} === - - -# Log4cxx Dependencies +[TOC] As of version 0.12.0, Log4cxx requires a minimum C++ version of C++11. -If C++17 is not available, then Log4cxx requires Boost Thread in order -to build, which in turn requires chrono and date\_time. -log4cxx requires the following software to build and/or run correctly: +Log4cxx requires the following software to build and/or run correctly: |Dependency Name|Version|Dependency Type|Homepage| |---------------|-------|---------------|--------| |Apache Portable Runtime(APR)|>=1.5.4|Compile/Runtime|https://apr.apache.org |APR-Util |>=1.5.4|Compile/Runtime|https://apr.apache.org -|Boost |any? |Compile/runtime. Not required if your compiler supports C++17|https://boost.org |gzip |any |Test/Runtime(optional)|https://gzip.org |sed |any |Test|N/A |zip |any |Test/Runtime(optional)|N/A -|log4j |1.2.14 |Test |https://http://logging.apache.org/log4j/2.x/ -|java |>=6 |Test |https://adoptopenjdk.net ## APR+APR-Util @@ -58,15 +51,42 @@ MinGW, cygwin, or MSYS2. `gzip` and `zip` only needed during runtime if you are compressing the log files, for example by setting a rollover policy which ends in `.gz` or `.zip`. -## log4j+Java +# Optional Dependencies + +The following table lists CMake options that require additional dependencies. + +|CMake option |Dependency Name|Version| Dependency Type | Homepage| +|---------------|---------------| :---: |---------------|--------| +|LOG4CXX_MULTIPROCESS_ROLLING_FILE_APPENDER |Boost | any | Compile/runtime. Not required if your compiler supports C++17 | https://boost.org | +|ENABLE_FMT_LAYOUT | {fmt} | 9+ | Compile/runtime | https://github.com/fmtlib/fmt | +|LOG4CXX_ENABLE_ODBC | unixodbc | any | Compile/runtime (not on Windows) | https://www.unixodbc.org/ | +|LOG4CXX_ENABLE_ESMTP | libesmtp | any | Compile/runtime (not on Windows) | https://github.com/libesmtp/libESMTP | +|LOG4CXX_QT_SUPPORT |Qt | 5 | Compile/runtime | https://www.qt.io/download | +|LOG4CXX_CFSTRING | Mac OS/X Core Foundation | any | Compile/runtime | https://developer.apple.com/documentation/corefoundation | + +## A note on C++ version and Boost + +By default, Log4cxx requests C++20 features. This is to +avoid 3rd party dependencies as much as possible. If C++17 is not +available, a search for Boost will be taken and those libraries will be used +instead. If you would prefer to use Boost, there are two options you have: -log4j and Java are needed to run some tests to ensure that log4cxx has binary compatability with -log4j. Note that the correct binary for log4j will be downloaded and used automatically if CMAKE is -used to build the project, otherwise one needs to get that manually. Java needs to be installed on -the system already in all cases, but with CMAKE again, if it's not, the corresponding tests are -skipped entirely automatically. +1. Pass `-DPREFER_BOOST=ON` to CMake when compiling. This will ignore the + results of the tests that check for the standard version of components that + are required. Note that this will switch all components, regardless of the + C++ version in effect at compile time. +2. Revert to an earlier standard using `-DCMAKE_CXX_STANDARD=11` for example. + This will still to check for standard versions of required components, but + it will fall back to using Boost for newer components added in C++17. # Licenses(direct dependencies only) -**Apache License, Version 2.0**: log4cxx, APR, APR-util -**Boost License, Version 1.0**: boost +| Dependency | License | +|------------|---------| +| APR, APR-util | **Apache License, Version 2.0** | +| Boost | **Boost License, Version 1.0** | +| {fmt} | **MIT** | +| unixodbc | **LGPL** | +| libesmtp | **LGPL** | +| Qt | Refer https://www.qt.io/licensing/ | +| Mac OS/X Core Foundation | **APSL 2.0** | \ No newline at end of file diff --git a/src/site/markdown/library-design.md b/src/site/markdown/library-design.md index 9d673c5f2..5f4649e99 100644 --- a/src/site/markdown/library-design.md +++ b/src/site/markdown/library-design.md @@ -1,4 +1,4 @@ -# Library Design Notes {#library-design} +Library Design Notes {#library-design} ===