You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by sw...@apache.org on 2026/06/02 07:19:34 UTC

(logging-log4cxx) 01/01: Ignore character case in loaded option names in the next ABI version

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

swebb2066 pushed a commit to branch case_insensitive_properties
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git

commit c175e90719dac36640d5f1f3bda0259e0a748bc5
Author: Stephen Webb <sw...@gmail.com>
AuthorDate: Tue Jun 2 17:18:57 2026 +1000

    Ignore character case in loaded option names in the next ABI version
---
 src/main/cpp/properties.cpp                   | 18 ++++++++++++++++++
 src/main/include/log4cxx/helpers/properties.h |  7 ++++++-
 src/test/cpp/helpers/propertiestestcase.cpp   | 15 +++++++++++++++
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/src/main/cpp/properties.cpp b/src/main/cpp/properties.cpp
index 893f186c..a5847b88 100644
--- a/src/main/cpp/properties.cpp
+++ b/src/main/cpp/properties.cpp
@@ -20,10 +20,28 @@
 #include <log4cxx/helpers/inputstreamreader.h>
 #include <log4cxx/helpers/exception.h>
 #include <log4cxx/helpers/pool.h>
+#include <cctype>
+#include <algorithm>
 
 using namespace LOG4CXX_NS;
 using namespace LOG4CXX_NS::helpers;
 
+template <typename Char>
+struct Properties::Less
+{
+	bool operator()(const std::basic_string<Char>& str1, const std::basic_string<Char>& str2) const
+	{
+		return std::lexicographical_compare
+			( str1.begin(), str1.end()
+			, str2.begin(), str2.end()
+			, [](Char c1, Char c2)
+				{
+					return std::tolower(c1) < std::tolower(c2);
+				}
+			);
+	}
+};
+
 class PropertyParser
 {
 	public:
diff --git a/src/main/include/log4cxx/helpers/properties.h b/src/main/include/log4cxx/helpers/properties.h
index 1481d2cc..2a82ad29 100644
--- a/src/main/include/log4cxx/helpers/properties.h
+++ b/src/main/include/log4cxx/helpers/properties.h
@@ -32,7 +32,12 @@ namespace helpers
 class LOG4CXX_EXPORT Properties
 {
 	private:
-		typedef std::map<LogString, LogString> PropertyMap;
+		template <typename Char> struct Less;
+#if LOG4CXX_ABI_VERSION < 15
+		using PropertyMap = std::map<LogString, LogString>;
+#else
+		using PropertyMap = std::map<LogString, LogString, Less<logchar> >;
+#endif
 		PropertyMap* properties;
 
 	public: // ...structors
diff --git a/src/test/cpp/helpers/propertiestestcase.cpp b/src/test/cpp/helpers/propertiestestcase.cpp
index 315b6c8e..338a04e9 100644
--- a/src/test/cpp/helpers/propertiestestcase.cpp
+++ b/src/test/cpp/helpers/propertiestestcase.cpp
@@ -44,6 +44,7 @@ LOGUNIT_CLASS(PropertiesTestCase)
 	LOGUNIT_TEST(testCRLF);
 	LOGUNIT_TEST(testLF);
 	LOGUNIT_TEST(testMixedLineEndings);
+	LOGUNIT_TEST(testCaseSensitivity);
 	LOGUNIT_TEST_SUITE_END();
 
 public:
@@ -295,6 +296,20 @@ public:
 		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("some_value")), value3);
 	}
 
+	void testCaseSensitivity(){
+		Properties properties;
+		properties.setProperty(LOG4CXX_STR("key"), LOG4CXX_STR("value1"));
+		properties.setProperty(LOG4CXX_STR("Key"), LOG4CXX_STR("value2"));
+		auto keys = properties.propertyNames();
+		auto keyCount = static_cast<int>(keys.size());
+#if LOG4CXX_ABI_VERSION < 15
+		LOGUNIT_ASSERT_EQUAL(keyCount, 2);
+#else
+		LOGUNIT_ASSERT_EQUAL(keyCount, 1);
+		LOGUNIT_ASSERT_EQUAL(properties.get(keys.front()), LOG4CXX_STR("value2"));
+#endif
+	}
+
 };