You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rm...@apache.org on 2025/12/23 22:07:25 UTC

(logging-log4cxx) branch refactor-apr-classes created (now 5c23488f)

This is an automated email from the ASF dual-hosted git repository.

rmiddleton pushed a change to branch refactor-apr-classes
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git


      at 5c23488f refactor apr classes to start apr being optional

This branch includes the following new commits:

     new 5c23488f refactor apr classes to start apr being optional

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(logging-log4cxx) 01/01: refactor apr classes to start apr being optional

Posted by rm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rmiddleton pushed a commit to branch refactor-apr-classes
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git

commit 5c23488f45054c0c00dfd276f5c32e0fc2de2539
Author: Robert Middleton <ro...@rm5248.com>
AuthorDate: Tue Dec 23 17:07:11 2025 -0500

    refactor apr classes to start apr being optional
---
 CMakeLists.txt                        |  20 ++--
 src/CMakeLists.txt                    |  18 +++-
 src/main/cpp/CMakeLists.txt           |   7 +-
 src/main/cpp/aprinitializer.cpp       |  17 +++-
 src/main/cpp/charsetdecoder.cpp       |  19 ++--
 src/main/cpp/charsetencoder.cpp       |  35 ++++---
 src/main/include/log4cxx/log4cxx.h.in |   2 +
 src/test/cpp/CMakeLists.txt           |   8 +-
 src/test/cpp/logunit.cpp              |   8 +-
 src/test/cpp/util/binarycompare.cpp   |  64 +++++++++++-
 src/test/cpp/util/transformer.cpp     | 183 ++++++----------------------------
 src/test/cpp/util/transformer.h       |   7 +-
 12 files changed, 186 insertions(+), 202 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7db4e1eb..06ae89be 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -58,13 +58,19 @@ if(ENABLE_COVERAGE)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
 endif()
 
-# Find Apache Runtime
-option(APR_STATIC "Link to the APR static library" OFF)
-find_package(APR REQUIRED)
-
-# Find Apache Runtime Utilities
-option(APU_STATIC "Link to the APR-Util static library" OFF)
-find_package(APR-Util REQUIRED)
+option(ENABLE_APR "Enable APR for cross-platform support" ON)
+if(ENABLE_APR)
+    set(LOG4CXX_ENABLE_APR 1)
+    # Find Apache Runtime
+    option(APR_STATIC "Link to the APR static library" OFF)
+    #find_package(APR REQUIRED)
+
+    # Find Apache Runtime Utilities
+    option(APU_STATIC "Link to the APR-Util static library" OFF)
+    #find_package(APR-Util REQUIRED)
+else()
+    set(LOG4CXX_ENABLE_APR 0)
+endif(ENABLE_APR)
 
 if(NOT MSVC)
   # The pthread library is used to name threads and mask signals
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 868a1273..6b61ae1d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -19,9 +19,21 @@ include(${CMAKE_CURRENT_LIST_DIR}/cmake/boost-fallback/boost-fallback.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/cmake/compiler-features/check-compiler-support.cmake)
 
 add_subdirectory(main)
-target_compile_definitions(log4cxx PRIVATE ${LOG4CXX_COMPILE_DEFINITIONS} ${APR_COMPILE_DEFINITIONS} ${APR_UTIL_COMPILE_DEFINITIONS} )
-target_include_directories(log4cxx INTERFACE $<INSTALL_INTERFACE:include> PRIVATE ${APR_INCLUDE_DIR} ${APR_UTIL_INCLUDE_DIR})
-target_link_libraries(log4cxx PRIVATE ${APR_UTIL_LIBRARIES} ${EXPAT_LIBRARIES} ${APR_LIBRARIES} ${APR_SYSTEM_LIBS})
+target_compile_definitions(log4cxx PRIVATE
+    ${LOG4CXX_COMPILE_DEFINITIONS}
+    $<$<BOOL:${ENABLE_APR}>:${APR_COMPILE_DEFINITIONS}>
+    $<$<BOOL:${ENABLE_APR}>:${APR_UTIL_COMPILE_DEFINITIONS}>
+)
+target_include_directories(log4cxx INTERFACE $<INSTALL_INTERFACE:include> PRIVATE
+    $<$<BOOL:${ENABLE_APR}>:${APR_INCLUDE_DIR}>
+    $<$<BOOL:${ENABLE_APR}>:${APR_UTIL_INCLUDE_DIR}>
+)
+target_link_libraries(log4cxx PRIVATE
+    $<$<BOOL:${ENABLE_APR}>:${APR_UTIL_LIBRARIES}>
+    ${EXPAT_LIBRARIES}
+    $<$<BOOL:${ENABLE_APR}>:${APR_LIBRARIES}>
+    $<$<BOOL:${ENABLE_APR}>:${APR_SYSTEM_LIBS}>
+)
 if(HAS_LIBESMTP)
   target_include_directories(log4cxx PRIVATE ${ESMTP_INCLUDE_DIR})
   target_link_libraries(log4cxx PRIVATE ${ESMTP_LIBRARIES})
diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt
index 8a2526f4..17264e05 100644
--- a/src/main/cpp/CMakeLists.txt
+++ b/src/main/cpp/CMakeLists.txt
@@ -70,6 +70,12 @@ if(${ENABLE_FMT_LAYOUT})
     )
 endif()
 
+if(${ENABLE_APR})
+    list(APPEND extra_classes
+        dbappender.cpp
+    )
+endif()
+
 target_sources(log4cxx
   PRIVATE
   action.cpp
@@ -98,7 +104,6 @@ target_sources(log4cxx
   date.cpp
   dateformat.cpp
   datepatternconverter.cpp
-  dbappender.cpp
   defaultconfigurator.cpp
   defaultloggerfactory.cpp
   defaultrepositoryselector.cpp
diff --git a/src/main/cpp/aprinitializer.cpp b/src/main/cpp/aprinitializer.cpp
index 36119e2a..6f11aea1 100644
--- a/src/main/cpp/aprinitializer.cpp
+++ b/src/main/cpp/aprinitializer.cpp
@@ -19,16 +19,19 @@
 	#define LOG4CXX 1
 #endif
 #include <log4cxx/helpers/aprinitializer.h>
-#include <apr_pools.h>
 #include <assert.h>
 #include <log4cxx/helpers/threadspecificdata.h>
-#include <apr_thread_proc.h>
 #include <log4cxx/helpers/date.h>
 #include <log4cxx/helpers/loglog.h>
 #include <vector>
 #include <algorithm>
 #include <mutex>
 
+#ifdef LOG4CXX_ENABLE_APR
+#include <apr_pools.h>
+#include <apr_thread_proc.h>
+#endif
+
 using namespace LOG4CXX_NS::helpers;
 using namespace LOG4CXX_NS;
 
@@ -81,11 +84,15 @@ struct apr_environment
 {
     apr_environment()
     {
+#ifdef LOG4CXX_ENABLE_APR
         apr_initialize();
+#endif
     }
     ~apr_environment()
     {
+#ifdef LOG4CXX_ENABLE_APR
         apr_terminate();
+#endif
     }
 };
 
@@ -95,12 +102,14 @@ struct apr_environment
 APRInitializer::APRInitializer() :
 	m_priv(std::make_unique<APRInitializerPrivate>())
 {
-	apr_pool_create(&m_priv->p, NULL);
-	m_priv->startTime = Date::currentTime();
+#ifdef LOG4CXX_ENABLE_APR
+    apr_pool_create(&m_priv->p, NULL);
 #if APR_HAS_THREADS
 	apr_status_t stat = apr_threadkey_private_create(&m_priv->tlsKey, tlsDestructImpl, m_priv->p);
 	assert(stat == APR_SUCCESS);
 #endif
+#endif
+    m_priv->startTime = Date::currentTime();
 }
 
 APRInitializer::~APRInitializer()
diff --git a/src/main/cpp/charsetdecoder.cpp b/src/main/cpp/charsetdecoder.cpp
index ed79d440..3a3e9e5d 100644
--- a/src/main/cpp/charsetdecoder.cpp
+++ b/src/main/cpp/charsetdecoder.cpp
@@ -22,17 +22,20 @@
 #include <log4cxx/helpers/exception.h>
 #include <log4cxx/helpers/pool.h>
 #include <log4cxx/helpers/loglog.h>
-#include <apr_xlate.h>
 #if !defined(LOG4CXX)
 	#define LOG4CXX 1
 #endif
 #include <log4cxx/private/log4cxx_private.h>
 #include <locale.h>
-#include <apr_portable.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/transcoder.h>
 #include <mutex>
 
+#ifdef LOG4CXX_ENABLE_APR
+#include <apr_xlate.h>
+#include <apr_portable.h>
+#endif
+
 using namespace LOG4CXX_NS;
 using namespace LOG4CXX_NS::helpers;
 
@@ -255,7 +258,7 @@ class TrivialCharsetDecoder : public CharsetDecoder
 				in.position(in.position() + remaining);
 			}
 
-			return APR_SUCCESS;
+            return 0;
 		}
 
 
@@ -355,7 +358,7 @@ class ISOLatinCharsetDecoder : public CharsetDecoder
 				in.position(in.limit());
 			}
 
-			return APR_SUCCESS;
+            return 0;
 		}
 
 
@@ -386,7 +389,7 @@ class USASCIICharsetDecoder : public CharsetDecoder
 		virtual log4cxx_status_t decode(ByteBuffer& in,
 			LogString& out)
 		{
-			log4cxx_status_t stat = APR_SUCCESS;
+            log4cxx_status_t stat = 0;
 
 			if (in.remaining() > 0)
 			{
@@ -405,7 +408,7 @@ class USASCIICharsetDecoder : public CharsetDecoder
 					}
 					else
 					{
-						stat = APR_BADARG;
+                        stat = 1; // APR_BADARG
 						break;
 					}
 				}
@@ -434,7 +437,7 @@ class LocaleCharsetDecoder : public CharsetDecoder
 		}
 		log4cxx_status_t decode(ByteBuffer& in, LogString& out) override
 		{
-			log4cxx_status_t result = APR_SUCCESS;
+            log4cxx_status_t result = 0;
 			const char* p = in.current();
 			size_t i = in.position();
 			size_t remain = in.limit() - i;
@@ -460,7 +463,7 @@ class LocaleCharsetDecoder : public CharsetDecoder
 				}
 				if (static_cast<std::size_t>(-1) == n) // decoding error?
 				{
-					result = APR_BADARG;
+                    result = 1; // APR_BADARG
 					break;
 				}
 				if (static_cast<std::size_t>(-2) == n) // incomplete sequence?
diff --git a/src/main/cpp/charsetencoder.cpp b/src/main/cpp/charsetencoder.cpp
index b08e277b..0123e900 100644
--- a/src/main/cpp/charsetencoder.cpp
+++ b/src/main/cpp/charsetencoder.cpp
@@ -18,22 +18,25 @@
 #include <log4cxx/helpers/charsetencoder.h>
 #include <log4cxx/helpers/bytebuffer.h>
 #include <log4cxx/helpers/exception.h>
-#include <apr_xlate.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/transcoder.h>
 #include <algorithm>
-
 #if !defined(LOG4CXX)
 	#define LOG4CXX 1
 #endif
-
 #include <log4cxx/private/log4cxx_private.h>
-#include <apr_portable.h>
+
 #include <mutex>
 
 #ifdef LOG4CXX_HAS_WCSTOMBS
 	#include <stdlib.h>
 #endif
+#include <string.h>
+
+#ifdef LOG4CXX_ENABLE_APR
+#include <apr_xlate.h>
+#include <apr_portable.h>
+#endif
 
 using namespace LOG4CXX_NS;
 using namespace LOG4CXX_NS::helpers;
@@ -226,7 +229,7 @@ class USASCIICharsetEncoder : public CharsetEncoder
 			LogString::const_iterator& iter,
 			ByteBuffer& out)
 		{
-			log4cxx_status_t stat = APR_SUCCESS;
+            log4cxx_status_t stat = 0;
 
 			if (iter != in.end())
 			{
@@ -242,7 +245,7 @@ class USASCIICharsetEncoder : public CharsetEncoder
 					else
 					{
 						iter = prev;
-						stat = APR_BADARG;
+                        stat = 1; // APR_BADARG
 						break;
 					}
 				}
@@ -270,7 +273,7 @@ class ISOLatinCharsetEncoder : public CharsetEncoder
 			LogString::const_iterator& iter,
 			ByteBuffer& out)
 		{
-			log4cxx_status_t stat = APR_SUCCESS;
+            log4cxx_status_t stat = 0;
 
 			if (iter != in.end())
 			{
@@ -286,7 +289,7 @@ class ISOLatinCharsetEncoder : public CharsetEncoder
 					else
 					{
 						iter = prev;
-						stat = APR_BADARG;
+                        stat = 1; // APR_BADARG
 						break;
 					}
 				}
@@ -331,7 +334,7 @@ class TrivialCharsetEncoder : public CharsetEncoder
 				out.position(out.position() + requested * sizeof(logchar));
 			}
 
-			return APR_SUCCESS;
+            return 0;
 		}
 
 	private:
@@ -397,13 +400,13 @@ class UTF16BECharsetEncoder : public CharsetEncoder
 
 				if (sv == 0xFFFF)
 				{
-					return APR_BADARG;
+                    return 1; // APR_BADARG;
 				}
 
 				Transcoder::encodeUTF16BE(sv, out);
 			}
 
-			return APR_SUCCESS;
+            return 0;
 		}
 
 	private:
@@ -432,13 +435,13 @@ class UTF16LECharsetEncoder : public CharsetEncoder
 
 				if (sv == 0xFFFF)
 				{
-					return APR_BADARG;
+                    return 1; // APR_BADARG;
 				}
 
 				Transcoder::encodeUTF16LE(sv, out);
 			}
 
-			return APR_SUCCESS;
+            return 0;
 		}
 	private:
 		UTF16LECharsetEncoder(const UTF16LECharsetEncoder&);
@@ -460,7 +463,7 @@ class LocaleCharsetEncoder : public CharsetEncoder
 			, ByteBuffer&                out
 			) override
 		{
-			log4cxx_status_t result = APR_SUCCESS;
+            log4cxx_status_t result = 0;
 #if !LOG4CXX_CHARSET_EBCDIC
 			char* current = out.current();
 			size_t remain = out.remaining();
@@ -482,7 +485,7 @@ class LocaleCharsetEncoder : public CharsetEncoder
 				auto n = std::wcrtomb(current, ch, &this->state);
 				if (static_cast<std::size_t>(-1) == n) // not a valid wide character?
 				{
-					result = APR_BADARG;
+                    result = 1; // APR_BADARG
 					break;
 				}
 				remain -= n;
@@ -612,7 +615,7 @@ void CharsetEncoder::encode(CharsetEncoderPtr& enc,
 {
 	log4cxx_status_t stat = enc->encode(src, iter, dst);
 
-	if (stat != APR_SUCCESS && iter != src.end())
+    if (stat != 0 && iter != src.end())
 	{
 #if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_LOGCHAR_IS_UNICHAR
 		iter++;
diff --git a/src/main/include/log4cxx/log4cxx.h.in b/src/main/include/log4cxx/log4cxx.h.in
index 4e6c2931..f4d596f2 100644
--- a/src/main/include/log4cxx/log4cxx.h.in
+++ b/src/main/include/log4cxx/log4cxx.h.in
@@ -104,6 +104,8 @@ __pragma( warning( pop ) )
 
 #define LOG4CXX_NS @LOG4CXX_NS@
 
+#cmakedefine LOG4CXX_ENABLE_APR
+
 namespace LOG4CXX_NS {
 
 /**
diff --git a/src/test/cpp/CMakeLists.txt b/src/test/cpp/CMakeLists.txt
index 4eb99f7d..95ed4515 100644
--- a/src/test/cpp/CMakeLists.txt
+++ b/src/test/cpp/CMakeLists.txt
@@ -131,9 +131,13 @@ foreach(testName IN LISTS ALL_LOG4CXX_TESTS)
         target_link_libraries(${testName} PRIVATE MockCoreFoundation)
       endif()
     endif()
-    target_compile_definitions(${testName} PRIVATE ${TEST_COMPILE_DEFINITIONS} ${TESTING_DEPENDENCY_COMPILE_DEFINITIONS} )
+    target_compile_definitions(${testName} PRIVATE ${TEST_COMPILE_DEFINITIONS} ${TESTING_DEPENDENCY_COMPILE_DEFINITIONS} $<$<BOOL:${ENABLE_APR}>:LOG4CXX_TESTING_APR>)
     target_include_directories(${testName} PRIVATE ${CMAKE_CURRENT_LIST_DIR} $<TARGET_PROPERTY:log4cxx,INCLUDE_DIRECTORIES>)
-    target_link_libraries(${testName} PRIVATE testingFramework testingUtilities log4cxx ${APR_LIBRARIES} ${APR_SYSTEM_LIBS} Threads::Threads ${ODBC_LIBRARIES} )
+    target_link_libraries(${testName} PRIVATE testingFramework testingUtilities log4cxx
+        $<$<BOOL:${ENABLE_APR}>:${APR_LIBRARIES}>
+        $<$<BOOL:${ENABLE_APR}>:${APR_SYSTEM_LIBS}>
+        Threads::Threads ${ODBC_LIBRARIES}
+    )
     if(HAS_LIBESMTP)
       target_link_libraries(${testName} PRIVATE ${ESMTP_LIBRARIES})
     endif()
diff --git a/src/test/cpp/logunit.cpp b/src/test/cpp/logunit.cpp
index ce03206a..6769214d 100644
--- a/src/test/cpp/logunit.cpp
+++ b/src/test/cpp/logunit.cpp
@@ -17,7 +17,9 @@
 
 #include "logunit.h"
 
+#ifdef LOG4CXX_TESTING_APR
 #include <apr_general.h>
+#endif
 #include <algorithm>
 #include <stdlib.h>
 #include <locale.h>
@@ -35,8 +37,9 @@ void initialize()
 	{
 		printf("LC_CTYPE: %s\n", ctype);
 	}
-
+#ifdef LOG4CXX_TESTING_APR
 	apr_initialize();
+#endif
 }
 
 extern const char** testlist;
@@ -66,8 +69,9 @@ abts_suite* abts_run_suites(abts_suite* suite)
 			suite = iter->second->run(suite);
 		}
 	}
-
+#ifdef LOG4CXX_TESTING_APR
 	apr_terminate();
+#endif
 	return suite;
 }
 
diff --git a/src/test/cpp/util/binarycompare.cpp b/src/test/cpp/util/binarycompare.cpp
index 5752ccbc..9c44d950 100644
--- a/src/test/cpp/util/binarycompare.cpp
+++ b/src/test/cpp/util/binarycompare.cpp
@@ -15,16 +15,21 @@
  */
 
 #include "binarycompare.h"
-#include <apr_file_io.h>
 #include <log4cxx/helpers/pool.h>
 #include "../logunit.h"
+
+#ifdef LOG4CXX_TESTING_APR
+#include <apr_file_io.h>
 #include <apr_pools.h>
 #include <apr_strings.h>
+#endif
+#include <fstream>
 
 using namespace log4cxx;
 using namespace log4cxx::util;
 using namespace log4cxx::helpers;
 
+#ifdef LOG4CXX_TESTING_APR
 void BinaryCompare::compare(const char* filename1,
 	const char* filename2)
 {
@@ -91,3 +96,60 @@ void BinaryCompare::compare(const char* filename1,
 		}
 	}
 }
+#else
+void BinaryCompare::compare(const char* filename1,
+    const char* filename2)
+{
+    Pool p;
+    std::fstream file1(filename1, std::ios_base::in | std::ios_base::binary);
+    std::fstream file2(filename2, std::ios_base::in | std::ios_base::binary);
+
+    if (!file1.is_open())
+    {
+        LOGUNIT_FAIL(std::string("Unable to open ") + filename1);
+    }
+
+    if (!file2.is_open())
+    {
+        LOGUNIT_FAIL(std::string("Unable to open ") + filename2);
+    }
+
+    constexpr int BUFFER_SIZE = 1024;
+    char contents1[BUFFER_SIZE];
+    char contents2[BUFFER_SIZE];
+    memset(contents1, 0, BUFFER_SIZE);
+    memset(contents2, 0, BUFFER_SIZE);
+
+    file1.read(contents1, BUFFER_SIZE);
+    file2.read(contents2, BUFFER_SIZE);
+
+    if (file1.fail())
+    {
+        LOGUNIT_FAIL(std::string("Unable to read ") + filename1);
+    }
+
+    if (file2.fail())
+    {
+        LOGUNIT_FAIL(std::string("Unable to read ") + filename2);
+    }
+
+    for (int i = 0; i < BUFFER_SIZE; i++)
+    {
+        if (contents1[i] != contents2[i])
+        {
+            std::string msg("Contents differ at position ");
+            msg += std::to_string(i);
+            msg += ": [";
+            msg += filename1;
+            msg += "] has ";
+            msg += std::to_string(i);
+            msg += ", [";
+            msg += filename2;
+            msg += "] has ";
+            msg += std::to_string(i);
+            msg += ".";
+            LOGUNIT_FAIL(msg);
+        }
+    }
+}
+#endif
diff --git a/src/test/cpp/util/transformer.cpp b/src/test/cpp/util/transformer.cpp
index 96ed877b..81c5d5ba 100644
--- a/src/test/cpp/util/transformer.cpp
+++ b/src/test/cpp/util/transformer.cpp
@@ -18,24 +18,14 @@
 #include "transformer.h"
 #include <log4cxx/file.h>
 #include <log4cxx/helpers/transcoder.h>
-#include <apr_thread_proc.h>
-#include <apr_pools.h>
-#include <apr_file_io.h>
-#include <apr_strings.h>
 #include <assert.h>
 #include <iostream>
+#include <filesystem>
+#include <fstream>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
 
-#if !defined(APR_FOPEN_READ)
-	#define APR_FOPEN_READ APR_READ
-	#define APR_FOPEN_CREATE APR_CREATE
-	#define APR_FOPEN_WRITE APR_WRITE
-	#define APR_FOPEN_TRUNCATE APR_TRUNCATE
-	#define APR_FOPEN_APPEND APR_APPEND
-#endif
-
 void Transformer::transform(const File& in, const File& out,
 	const std::vector<Filter*>& filters)
 {
@@ -68,51 +58,15 @@ void Transformer::transform(const File& in, const File& out,
 
 void Transformer::copyFile(const File& in, const File& out)
 {
-	Pool p;
-	apr_pool_t* pool = p.getAPRPool();
-
-
-	//
-	//    fairly naive file copy code
-	//
-	//
-	apr_file_t* child_out;
-	apr_int32_t flags = APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE;
-	apr_status_t stat = out.open(&child_out, flags, APR_OS_DEFAULT, p);
-	assert(stat == APR_SUCCESS);
-
-	apr_file_t* in_file;
-	stat = in.open(&in_file, APR_FOPEN_READ, APR_OS_DEFAULT, p);
-	assert(stat == APR_SUCCESS);
-	apr_size_t bufsize = 32000;
-	void* buf = apr_palloc(pool, bufsize);
-	apr_size_t bytesRead = bufsize;
-
-	while (stat == 0 && bytesRead == bufsize)
-	{
-		stat = apr_file_read(in_file, buf, &bytesRead);
-
-		if (stat == 0 && bytesRead > 0)
-		{
-			stat = apr_file_write(child_out, buf, &bytesRead);
-			assert(stat == APR_SUCCESS);
-		}
-	}
-
-	stat = apr_file_close(child_out);
-	assert(stat == APR_SUCCESS);
+    bool stat = std::filesystem::copy_file(in.getPath(), out.getPath());
+    assert(stat);
 }
 
 void Transformer::createSedCommandFile(const std::string& regexName,
-	const log4cxx::Filter::PatternList& patterns,
-	apr_pool_t* pool)
+    const log4cxx::Filter::PatternList& patterns)
 {
-	apr_file_t* regexFile;
-	apr_status_t stat = apr_file_open(&regexFile,
-			regexName.c_str(),
-			APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE, APR_OS_DEFAULT,
-			pool);
-	assert(stat == APR_SUCCESS);
+    std::fstream regexFile(regexName, std::ios::out | std::ios::binary | std::ios::trunc);
+    assert(regexFile.is_open());
 
 	std::string tmp;
 
@@ -139,28 +93,18 @@ void Transformer::createSedCommandFile(const std::string& regexName,
 		tmp.append(sedSanitizer(iter->first));
 		tmp.append(1, 'Q');
 		tmp.append(sedSanitizer(iter->second));
-		tmp.append("Qg\n");
-		apr_file_puts(tmp.c_str(), regexFile);
-	}
-
-	apr_file_close(regexFile);
+        tmp.append("Qg\n");
+        regexFile << tmp.c_str();
+    }
 }
 
 void Transformer::transform(const File& in, const File& out,
 	const log4cxx::Filter::PatternList& patterns)
 {
-	//
-	//   if no patterns just copy the file
-	//
-	if (patterns.size() == 0)
-	{
-		copyFile(in, out);
-	}
-	else
-	{
-		Pool p;
-		apr_pool_t* pool = p.getAPRPool();
+    copyFile(in, out);
 
+    if(patterns.size() > 0)
+    {
 		//
 		//   write the regex's to a temporary file since they
 		//      may get mangled if passed as parameters
@@ -168,89 +112,24 @@ void Transformer::transform(const File& in, const File& out,
 		std::string regexName;
 		Transcoder::encode(in.getPath(), regexName);
 		regexName.append(".sed");
-		createSedCommandFile(regexName, patterns, pool);
-
-
-		//
-		//  prepare to launch sed
-		//
-		//
-		apr_procattr_t* attr = NULL;
-		apr_status_t stat = apr_procattr_create(&attr, pool);
-		assert(stat == APR_SUCCESS);
-
-		stat = apr_procattr_io_set(attr, APR_NO_PIPE, APR_FULL_BLOCK,
-				APR_FULL_BLOCK);
-		assert(stat == APR_SUCCESS);
-
-		//
-		//   find the program on the path
-		//
-		stat = apr_procattr_cmdtype_set(attr, APR_PROGRAM_PATH);
-		assert(stat == APR_SUCCESS);
-
-		//
-		//   build the argument list
-		//      using Q as regex separator on s command
-		//
-		const char** args = (const char**)
-			apr_palloc(pool, 5 * sizeof(*args));
-		int i = 0;
-
-		//
-		//   not well documented
-		//     but the first arg is a duplicate of the executable name
-		//
-		args[i++] = "sed";
-
-
-		std::string regexArg("-f");
-		regexArg.append(regexName);
-		args[i++] = apr_pstrdup(pool, regexArg.c_str());
-
-		//
-		//    specify the input file
-		args[i++] = Transcoder::encode(in.getPath(), p);
-		args[i] = NULL;
-
-
-
-		//
-		//    set the output stream to the filtered file
-		//
-		apr_file_t* child_out;
-		apr_int32_t flags = APR_FOPEN_READ | APR_FOPEN_WRITE |
-			APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE;
-		stat = out.open(&child_out, flags, APR_OS_DEFAULT, p);
-		assert(stat == APR_SUCCESS);
-
-		stat =  apr_procattr_child_out_set(attr, child_out, NULL);
-		assert(stat == APR_SUCCESS);
-
-		//
-		//   redirect the child's error stream to this processes' error stream
-		//
-		apr_file_t* child_err;
-		stat = apr_file_open_stderr(&child_err, pool);
-		assert(stat == 0);
-		stat =  apr_procattr_child_err_set(attr, child_err, NULL);
-		assert(stat == APR_SUCCESS);
-
-
-
-		apr_proc_t pid;
-		stat = apr_proc_create(&pid, "sed", args, NULL, attr, pool);
-
-		if (stat != APR_SUCCESS)
-		{
-			puts("Error invoking sed, sed must be on the path in order to run unit tests");
-		}
-
-		assert(stat == APR_SUCCESS);
-
-		apr_proc_wait(&pid, NULL, NULL, APR_WAIT);
-		stat = apr_file_close(child_out);
-		assert(stat == APR_SUCCESS);
+        createSedCommandFile(regexName, patterns);
+
+        std::vector<std::string> exec_args;
+        exec_args.push_back("sed");
+        exec_args.push_back("-i"); // edit in-place
+        exec_args.push_back("-f");
+        exec_args.push_back(regexName);
+        exec_args.push_back(out.getPath());
+
+        std::string sed_command;
+        for(const std::string& str : exec_args){
+            sed_command.append(str);
+            sed_command.append(" ");
+        }
+
+        // execute sed using the default shell on the system
+        int status = std::system(sed_command.c_str());
+        assert(status == 0);
 	}
 
 
diff --git a/src/test/cpp/util/transformer.h b/src/test/cpp/util/transformer.h
index e7ac49e5..a5bed675 100644
--- a/src/test/cpp/util/transformer.h
+++ b/src/test/cpp/util/transformer.h
@@ -21,10 +21,6 @@
 #include "filter.h"
 #include <vector>
 
-extern "C" {
-	struct apr_pool_t;
-}
-
 namespace LOG4CXX_NS
 {
 class File;
@@ -47,8 +43,7 @@ class Transformer
 		static void copyFile(const File& in,
 			const File& out);
 		static void createSedCommandFile(const std::string& regexName,
-			const log4cxx::Filter::PatternList& patterns,
-			apr_pool_t* pool);
+            const log4cxx::Filter::PatternList& patterns);
 
 };
 }