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

pnoltes pushed a commit to branch feature/674-use-properties-type-in-filter
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 1e9ec2f78412744ea08bd0357aef67a6e4b67abb
Author: Pepijn Noltes <[email protected]>
AuthorDate: Sun Nov 19 19:01:41 2023 +0100

    Refactor filter create / parse functions
---
 libs/utils/benchmark/src/FilterBenchmark.cc |  11 +-
 libs/utils/gtest/src/FilterTestSuite.cc     | 487 +++++++++++++++-------------
 libs/utils/include/celix_filter.h           |  10 +-
 libs/utils/src/filter.c                     | 384 +++++++++++-----------
 4 files changed, 468 insertions(+), 424 deletions(-)

diff --git a/libs/utils/benchmark/src/FilterBenchmark.cc 
b/libs/utils/benchmark/src/FilterBenchmark.cc
index 43b4cdef..1a415350 100644
--- a/libs/utils/benchmark/src/FilterBenchmark.cc
+++ b/libs/utils/benchmark/src/FilterBenchmark.cc
@@ -176,10 +176,16 @@ static void 
FilterBenchmark_versionRangeFilter(benchmark::State& state) {
     benchmark.testFilter(state, filter, true);
 }
 
+static void FilterBenchmark_substringFilter(benchmark::State& state) {
+    FilterBenchmark benchmark{state};
+    celix::Filter filter{"(&(version_key1>=1.0.0)(version_key1<2.0.0))"};
+    benchmark.testFilter(state, filter, true);
+}
+
+
 static void FilterBenchmark_complexFilter(benchmark::State& state) {
     FilterBenchmark benchmark{state};
-    celix::Filter 
filter{"(&(version_key1>=1.0.0)(version_key1<2.0.0)(str_key1=str_value1)(long_key1=1)(double_key1>=0."
-                         "9)(bool_key1=true))"};
+    celix::Filter filter{"(str_key1=*value1)"};
     benchmark.testFilter(state, filter, true);
 }
 
@@ -206,4 +212,5 @@ CELIX_BENCHMARK(FilterBenchmark_versionGreaterEqualFilter);
 
 //Specials
 CELIX_BENCHMARK(FilterBenchmark_versionRangeFilter);
+CELIX_BENCHMARK(FilterBenchmark_substringFilter);
 CELIX_BENCHMARK(FilterBenchmark_complexFilter);
diff --git a/libs/utils/gtest/src/FilterTestSuite.cc 
b/libs/utils/gtest/src/FilterTestSuite.cc
index 55fb5e2c..2dd171e2 100644
--- a/libs/utils/gtest/src/FilterTestSuite.cc
+++ b/libs/utils/gtest/src/FilterTestSuite.cc
@@ -18,346 +18,356 @@
  */
 
 #include <gtest/gtest.h>
+
 #include "celix_filter.h"
 #include "celix_utils.h"
+#include "celix_err.h"
 
+class FilterTestSuite : public ::testing::Test {
+  public:
+    FilterTestSuite() {
+        celix_err_resetErrors();
+    }
 
-class FilterTestSuite : public ::testing::Test {};
+    ~FilterTestSuite() override {
+        celix_err_printErrors(stderr, nullptr, nullptr);
+    }
+};
 
-TEST_F(FilterTestSuite, create_destroy){
+TEST_F(FilterTestSuite, CreateDestroyTest) {
     const char* filter_str = 
"(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))";
-    celix_filter_t * get_filter;
+    celix_filter_t* filter;
 
-    get_filter = celix_filter_create(filter_str);
-    ASSERT_TRUE(get_filter != NULL);
+    filter = celix_filter_create(filter_str);
+    ASSERT_TRUE(filter != nullptr);
 
-    celix_filter_destroy(get_filter);
+    celix_filter_destroy(filter);
 }
 
-TEST_F(FilterTestSuite, create_fail_missing_opening_brackets){
-    celix_filter_t * get_filter;
+TEST_F(FilterTestSuite, MissingOpenBracketsCreateTest) {
+    celix_filter_t* filter;
 
-    //test missing opening brackets in main filter
-    const char *filter_str1 = 
"&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3))";
-    get_filter = celix_filter_create(filter_str1);
-    ASSERT_TRUE(get_filter == NULL);
+    // test missing opening brackets in main filter
+    const char* str1 = 
"&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3))";
+    filter = celix_filter_create(str1);
+    ASSERT_TRUE(filter == nullptr);
 
-    //test missing opening brackets in AND comparator
-    const char *filter_str2 = 
"(&test_attr1=attr1|(test_attr2=attr2)(test_attr3=attr3))";
-    get_filter = celix_filter_create(filter_str2);
-    ASSERT_TRUE(get_filter == NULL);
+    // test missing opening brackets in AND comparator
+    const char* str2 = 
"(&test_attr1=attr1|(test_attr2=attr2)(test_attr3=attr3))";
+    filter = celix_filter_create(str2);
+    ASSERT_TRUE(filter == nullptr);
 
-    //test missing opening brackets in AND comparator
-    const char *filter_str3 = 
"(&(test_attr1=attr1)(|test_attr2=attr2(test_attr3=attr3))";
-    get_filter = celix_filter_create(filter_str3);
-    ASSERT_TRUE(get_filter == NULL);
+    // test missing opening brackets in AND comparator
+    const char* str3 = 
"(&(test_attr1=attr1)(|test_attr2=attr2(test_attr3=attr3))";
+    filter = celix_filter_create(str3);
+    ASSERT_TRUE(filter == nullptr);
 
-    //test missing opening brackets in NOT comparator
-    const char *filter_str4 = "(&(test_attr1=attr1)(!test_attr2=attr2)";
-    get_filter = celix_filter_create(filter_str4);
-    ASSERT_TRUE(get_filter == NULL);
+    // test missing opening brackets in NOT comparator
+    const char* str4 = "(&(test_attr1=attr1)(!test_attr2=attr2)";
+    filter = celix_filter_create(str4);
+    ASSERT_TRUE(filter == nullptr);
 }
 
-TEST_F(FilterTestSuite, create_fail_missing_closing_brackets){
-    char * filter_str;
-    celix_filter_t * get_filter;
-    //test missing closing brackets in substring
-    filter_str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3");
-    get_filter = celix_filter_create(filter_str);
-    ASSERT_TRUE(get_filter == NULL);
-    free(filter_str);
-
-    //test missing closing brackets in value
-    filter_str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3>=attr3");
-    get_filter = celix_filter_create(filter_str);
-    ASSERT_TRUE(get_filter == NULL);
-    free(filter_str);
+TEST_F(FilterTestSuite, MissingClosingBracketsCreateTest) {
+    char* str;
+    celix_filter_t* filter;
+    // test missing closing brackets in substring
+    str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3");
+    filter = celix_filter_create(str);
+    ASSERT_TRUE(filter == nullptr);
+    free(str);
+
+    // test missing closing brackets in value
+    str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3>=attr3");
+    filter = celix_filter_create(str);
+    ASSERT_TRUE(filter == nullptr);
+    free(str);
 }
 
-TEST_F(FilterTestSuite, create_fail_invalid_closing_brackets) {
-    char *filter_str;
-    celix_filter_t *get_filter;
-
-    //test missing closing brackets in substring
-    filter_str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=at(tr3)))");
-    get_filter = celix_filter_create(filter_str);
-    ASSERT_TRUE(get_filter == NULL);
-    free(filter_str);
-
-    //test missing closing brackets in value
-    filter_str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3>=att(r3)))");
-    get_filter = celix_filter_create(filter_str);
-    ASSERT_TRUE(get_filter == NULL);
-    free(filter_str);
+TEST_F(FilterTestSuite, InvalidClosingBracketsCreateTest) {
+    char* str;
+    celix_filter_t* filter;
+
+    // test missing closing brackets in substring
+    str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=at(tr3)))");
+    filter = celix_filter_create(str);
+    ASSERT_TRUE(filter == nullptr);
+    free(str);
+
+    // test missing closing brackets in value
+    str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3>=att(r3)))");
+    filter = celix_filter_create(str);
+    ASSERT_TRUE(filter == nullptr);
+    free(str);
 }
 
-TEST_F(FilterTestSuite, create_misc) {
-    celix_filter_t *get_filter;
-    //test trailing chars
-    const char *filter_str1 = 
"(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3))) oh no! trailing 
chars";
-    get_filter = celix_filter_create(filter_str1);
-    ASSERT_TRUE(get_filter == NULL);
-
-    //test half APPROX operator (should be "~=", instead is "~")
-    const char *filter_str2 = 
"(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3~attr3)))";
-    get_filter = celix_filter_create(filter_str2);
-    ASSERT_TRUE(get_filter == NULL);
-
-    //test PRESENT operator with trailing chars (should just register as 
substrings: "*" and "attr3")
-    const char *filter_str3 = "(test_attr3=*attr3)";
-    get_filter = celix_filter_create(filter_str3);
-    ASSERT_TRUE(get_filter != NULL);
-    ASSERT_EQ(CELIX_FILTER_OPERAND_SUBSTRING, get_filter->operand);
-    ASSERT_EQ(2, celix_arrayList_size((celix_array_list_t *) 
get_filter->children));
-    celix_filter_destroy(get_filter);
-
-    //test parsing a attribute of 0 length
-    const char *filter_str4 = "(>=attr3)";
-    get_filter = celix_filter_create(filter_str4);
-    ASSERT_TRUE(get_filter == NULL);
-
-    //test parsing a value of 0 length
-    const char *filter_str5 = "(test_attr3>=)";
-    get_filter = celix_filter_create(filter_str5);
-    ASSERT_TRUE(get_filter == NULL);
-
-    //test parsing a value with a escaped closing bracket "\)"
-    const char *filter_str6 = "(test_attr3>=strWith\\)inIt)";
-    get_filter = celix_filter_create(filter_str6);
-    ASSERT_TRUE(get_filter != NULL);
-    ASSERT_STREQ("strWith)inIt", (char *) get_filter->value);
-    celix_filter_destroy(get_filter);
-
-    //test parsing a substring with a escaped closing bracket "\)"
-    const char *filter_str7 = "(test_attr3=strWith\\)inIt)";
-    get_filter = celix_filter_create(filter_str7);
-    ASSERT_TRUE(get_filter != NULL);
-    ASSERT_STREQ("strWith)inIt", (char *) get_filter->value);
-    celix_filter_destroy(get_filter);
+TEST_F(FilterTestSuite, MiscInvalidCreateTest) {
+    celix_filter_t* filter;
+    // test trailing chars
+    const char* str1 = 
"(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3))) oh no! trailing 
chars";
+    filter = celix_filter_create(str1);
+    ASSERT_TRUE(filter == nullptr);
+
+    // test half APPROX operator (should be "~=", instead is "~")
+    const char* str2 = 
"(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3~attr3)))";
+    filter = celix_filter_create(str2);
+    ASSERT_TRUE(filter == nullptr);
+
+    // test PRESENT operator with trailing chars (should just register as 
substrings: "*" and "attr3")
+    const char* str3 = "(test_attr3=*attr3)";
+    filter = celix_filter_create(str3);
+    ASSERT_TRUE(filter != nullptr);
+    ASSERT_EQ(CELIX_FILTER_OPERAND_SUBSTRING, filter->operand);
+    ASSERT_EQ(2, celix_arrayList_size((celix_array_list_t*)filter->children));
+    celix_filter_destroy(filter);
+
+    // test parsing an attribute of 0 length
+    const char* str4 = "(>=attr3)";
+    filter = celix_filter_create(str4);
+    ASSERT_TRUE(filter == nullptr);
+
+    // test parsing a value of 0 length
+    const char* str5 = "(test_attr3>=)";
+    filter = celix_filter_create(str5);
+    ASSERT_TRUE(filter == nullptr);
+
+    // test parsing a value with a escaped closing bracket "\)"
+    const char* str6 = "(test_attr3>=strWith\\)inIt)";
+    filter = celix_filter_create(str6);
+    ASSERT_TRUE(filter != nullptr);
+    ASSERT_STREQ("strWith)inIt", (char*)filter->value);
+    celix_filter_destroy(filter);
+
+    // test parsing a substring with an escaped closing bracket "\)"
+    const char* str7 = "(test_attr3=strWith\\)inIt)";
+    filter = celix_filter_create(str7);
+    ASSERT_TRUE(filter != nullptr);
+    ASSERT_STREQ("strWith)inIt", (char*)filter->value);
+    celix_filter_destroy(filter);
 }
 
-TEST_F(FilterTestSuite, match_comparators) {
-    char *filter_str;
-    celix_filter_t *filter;
-    celix_properties_t *props = celix_properties_create();
-    char *key = celix_utils_strdup("test_attr1");
-    char *val = celix_utils_strdup("attr1");
-    char *key2 = celix_utils_strdup("test_attr2");
-    char *val2 = celix_utils_strdup("attr2");
+TEST_F(FilterTestSuite, MatchEqualTest) {
+    char* str;
+    celix_filter_t* filter;
+    celix_properties_t* props = celix_properties_create();
+    char* key = celix_utils_strdup("test_attr1");
+    char* val = celix_utils_strdup("attr1");
+    char* key2 = celix_utils_strdup("test_attr2");
+    char* val2 = celix_utils_strdup("attr2");
     celix_properties_set(props, key, val);
     celix_properties_set(props, key2, val2);
-    //test AND
-    filter_str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(!(test_attr3=attr3))))");
-    filter = celix_filter_create(filter_str);
+    // test AND
+    str = 
celix_utils_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(!(test_attr3=attr3))))");
+    filter = celix_filter_create(str);
     bool result = celix_filter_match(filter, props);
     ASSERT_TRUE(result);
 
-    //test AND false
+    // test AND false
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1=attr1)(test_attr1=attr2))");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1=attr1)(test_attr1=attr2))");
+    filter = celix_filter_create(str);
     ASSERT_TRUE(filter == nullptr);
     result = celix_filter_match(filter, props);
     ASSERT_TRUE(result);
 
-//cleanup
+    // cleanup
     celix_properties_destroy(props);
     celix_filter_destroy(filter);
-    free(filter_str);
+    free(str);
     free(key);
     free(key2);
     free(val);
     free(val2);
 }
 
-TEST_F(FilterTestSuite, match_operators) {
-    char *filter_str;
-    celix_filter_t *filter;
-    celix_properties_t *props = celix_properties_create();
-    char *key = celix_utils_strdup("test_attr1");
-    char *val = celix_utils_strdup("attr1");
-    char *key2 = celix_utils_strdup("test_attr2");
-    char *val2 = celix_utils_strdup("attr2");
+TEST_F(FilterTestSuite, MatchTest) {
+    char* str;
+    celix_filter_t* filter;
+    celix_properties_t* props = celix_properties_create();
+    char* key = celix_utils_strdup("test_attr1");
+    char* val = celix_utils_strdup("attr1");
+    char* key2 = celix_utils_strdup("test_attr2");
+    char* val2 = celix_utils_strdup("attr2");
     celix_properties_set(props, key, val);
     celix_properties_set(props, key2, val2);
 
     // Test EQUALS
-    filter_str = celix_utils_strdup("(test_attr1=attr1)");
-    filter = celix_filter_create(filter_str);
+    str = celix_utils_strdup("(test_attr1=attr1)");
+    filter = celix_filter_create(str);
     bool result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
     // Test EQUALS false
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1=falseString)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1=falseString)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_FALSE(result);
 
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1~=attr1)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1~=attr1)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1~=ATTR1)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1~=ATTR1)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
     // Test PRESENT
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1=*)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1=*)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
     // Test NOT PRESENT
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr3=*)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr3=*)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_FALSE(result);
 
     // Test NOT PRESENT
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(!(test_attr3=*))");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(!(test_attr3=*))");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
     // Test LESSEQUAL less
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1<=attr5)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1<=attr5)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
     // Test LESSEQUAL equals
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr2<=attr2)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr2<=attr2)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
-    //test LESSEQUAL false
+    // test LESSEQUAL false
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr2<=attr1)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr2<=attr1)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_FALSE(result);
 
-    //test GREATEREQUAL greater
+    // test GREATEREQUAL greater
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr2>=attr1)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr2>=attr1)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
-    //test GREATEREQUAL equals
+    // test GREATEREQUAL equals
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr2>=attr2)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr2>=attr2)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
-    //test GREATEREQUAL false
+    // test GREATEREQUAL false
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1>=attr5)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1>=attr5)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_FALSE(result);
 
-    //test LESS less
+    // test LESS less
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1<attr5)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1<attr5)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
-    //test LESS equals
+    // test LESS equals
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr2<attr2)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr2<attr2)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_FALSE(result);
 
-    //test LESS false
+    // test LESS false
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr2<attr1)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr2<attr1)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_FALSE(result);
 
-    //test GREATER greater
+    // test GREATER greater
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr2>attr1)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr2>attr1)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
-    //test GREATER equals
+    // test GREATER equals
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr2>attr2)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr2>attr2)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_FALSE(result);
 
-    //test GREATER false
+    // test GREATER false
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1>attr5)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1>attr5)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_FALSE(result);
 
-    //test SUBSTRING equals
+    // test SUBSTRING equals
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1=attr*)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1=attr*)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_TRUE(result);
 
     celix_filter_destroy(filter);
-    free(filter_str);
-    filter_str = celix_utils_strdup("(test_attr1=attr*charsNotPresent)");
-    filter = celix_filter_create(filter_str);
+    free(str);
+    str = celix_utils_strdup("(test_attr1=attr*charsNotPresent)");
+    filter = celix_filter_create(str);
     result = celix_filter_match(filter, props);
     EXPECT_FALSE(result);
 
-    //cleanup
+    // cleanup
     celix_properties_destroy(props);
     celix_filter_destroy(filter);
-    free(filter_str);
+    free(str);
     free(key);
     free(key2);
     free(val);
     free(val2);
 }
 
-TEST_F(FilterTestSuite, match_recursion) {
-    auto* filter_str = 
"(&(test_attr1=attr1)(|(&(test_attr2=attr2)(!(&(test_attr1=attr1)(test_attr3=attr3))))(test_attr3=attr3)))";
-    auto* filter = celix_filter_create(filter_str);
+TEST_F(FilterTestSuite, MatchRecursionTest) {
+    auto* str = 
"(&(test_attr1=attr1)(|(&(test_attr2=attr2)(!(&(test_attr1=attr1)(test_attr3=attr3))))(test_attr3=attr3)))";
+    auto* filter = celix_filter_create(str);
     auto* props = celix_properties_create();
     auto* key = "test_attr1";
     auto* val = "attr1";
@@ -372,9 +382,9 @@ TEST_F(FilterTestSuite, match_recursion) {
     celix_filter_destroy(filter);
 }
 
-TEST_F(FilterTestSuite, match_false) {
-    auto* filter_str = 
"(&(test_attr1=attr1)(&(test_attr2=attr2)(test_attr3=attr3)))";
-    celix_filter_t* filter = celix_filter_create(filter_str);
+TEST_F(FilterTestSuite, FalseMatchTest) {
+    auto* str = "(&(test_attr1=attr1)(&(test_attr2=attr2)(test_attr3=attr3)))";
+    celix_filter_t* filter = celix_filter_create(str);
     celix_properties_t* props = celix_properties_create();
     auto* key = "test_attr1";
     auto* val = "attr1";
@@ -386,29 +396,28 @@ TEST_F(FilterTestSuite, match_false) {
     bool result = celix_filter_match(filter, props);
     ASSERT_FALSE(result);
 
-    //cleanup
+    // cleanup
     celix_properties_destroy(props);
     celix_filter_destroy(filter);
 }
 
-TEST_F(FilterTestSuite, getString) {
-    auto* filter_str = 
"(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))";
-    celix_filter_t * filter = celix_filter_create(filter_str);
+TEST_F(FilterTestSuite, GetStringTest) {
+    auto* str = "(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))";
+    celix_filter_t* filter = celix_filter_create(str);
 
-    const char * get_str = celix_filter_getFilterString(filter);
-    ASSERT_STREQ(filter_str, get_str);
+    const char* get_str = celix_filter_getFilterString(filter);
+    ASSERT_STREQ(str, get_str);
 
-    //cleanup
+    // cleanup
     celix_filter_destroy(filter);
 }
 
-
-TEST_F(FilterTestSuite, filterMatch) {
+TEST_F(FilterTestSuite, FilterEqualsTest) {
     auto* f1 = celix_filter_create("(test_attr1=attr1)");
     auto* f2 = celix_filter_create("(test_attr1=attr1)");
     auto* f3 = celix_filter_create("(test_attr1=attr2)");
-    EXPECT_TRUE(celix_filter_matchFilter(f1, f2));
-    EXPECT_FALSE(celix_filter_matchFilter(f1, f3));
+    EXPECT_TRUE(celix_filter_equals(f1, f2));
+    EXPECT_FALSE(celix_filter_equals(f1, f3));
     celix_filter_destroy(f1);
     celix_filter_destroy(f2);
     celix_filter_destroy(f3);
@@ -418,16 +427,56 @@ TEST_F(FilterTestSuite, AutoCleanupTest) {
     celix_autoptr(celix_filter_t) filter = 
celix_filter_create("(test_attr1=attr1)");
 }
 
-TEST_F(FilterTestSuite, create_fail_missing_filter_operand) {
-    celix_filter_t * filter= celix_filter_create("(&(test))");
-    ASSERT_TRUE(filter == NULL);
+TEST_F(FilterTestSuite, MissingOperandCreateTest) {
+    celix_filter_t* filter = celix_filter_create("(&(test))");
+    ASSERT_TRUE(filter == nullptr);
+
+    filter = celix_filter_create("(!(test))");
+    ASSERT_TRUE(filter == nullptr);
+}
+
+TEST_F(FilterTestSuite, SubStringTest) {
+    celix_autoptr(celix_properties_t) props = celix_properties_create();
+    celix_properties_set(props, "test", "John Bob Doe");
+
+    //test filter with matching subInitial
+    celix_autoptr(celix_filter_t) filter1 = celix_filter_create("(test=Jo*)");
+    EXPECT_TRUE(celix_filter_match(filter1, props));
+
+    //test filter with un-matching subInitial
+    celix_autoptr(celix_filter_t) filter2 = celix_filter_create("(test=Joo*)");
+    EXPECT_FALSE(celix_filter_match(filter2, props));
+
+    //test filter with matching subFinal
+    celix_autoptr(celix_filter_t) filter3 = celix_filter_create("(test=*Doe)");
+    EXPECT_TRUE(celix_filter_match(filter3, props));
+
+    //test filter with un-matching subFinal
+    celix_autoptr(celix_filter_t) filter4 = celix_filter_create("(test=*Doo)");
+    EXPECT_FALSE(celix_filter_match(filter4, props));
+
+    //test filter with matching subAny
+    celix_autoptr(celix_filter_t) filter5 = 
celix_filter_create("(test=*Bob*)");
+    EXPECT_TRUE(celix_filter_match(filter5, props));
+
+    //test filter with un-matching subAny
+    //TODO fixme
+//    celix_autoptr(celix_filter_t) filter6 = 
celix_filter_create("(test=*Boo*)");
+//    EXPECT_FALSE(celix_filter_match(filter6, props));
+
+    //test filter with matching subAny, subInitial and subFinal
+    celix_autoptr(celix_filter_t) filter7 = 
celix_filter_create("(test=Jo*Bob*Doe)");
+    EXPECT_TRUE(celix_filter_match(filter7, props));
+
+    //test filter with un-matching subAny, subInitial and subFinal
+    celix_autoptr(celix_filter_t) filter8 = 
celix_filter_create("(test=Jo*Boo*Doe)");
 
-    filter= celix_filter_create("(!(test))");
-    ASSERT_TRUE(filter == NULL);
+    //test filter with un-matching overlapping subAny, subInitial and subFinal
+    celix_autoptr(celix_filter_t) filter9 = celix_filter_create("(test=John 
B*Bob*b Doe)");
 }
 
 #include "filter.h"
-TEST_F(FilterTestSuite, deprecatedApi) {
+TEST_F(FilterTestSuite, DeprecatedApiTest) {
     auto* f1 = filter_create("(test_attr1=attr1)");
     auto* f2 = filter_create("(test_attr1=attr1)");
     bool result;
diff --git a/libs/utils/include/celix_filter.h 
b/libs/utils/include/celix_filter.h
index 24287a8f..33f24ed2 100644
--- a/libs/utils/include/celix_filter.h
+++ b/libs/utils/include/celix_filter.h
@@ -62,6 +62,14 @@ struct celix_filter_struct {
     celix_filter_internal_t* internal; //for internal use only
 };
 
+/**
+ * @brief Create a filter based on the provided filter string.
+ *
+ * If the return status is NULL, an error message is logged to celix_err.
+ *
+ * @param filterStr The filter string.
+ * @return The created filter or NULL if the filter string is invalid.
+ */
 CELIX_UTILS_EXPORT celix_filter_t* celix_filter_create(const char *filterStr);
 
 CELIX_UTILS_EXPORT void celix_filter_destroy(celix_filter_t *filter);
@@ -70,7 +78,7 @@ CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_filter_t, 
celix_filter_destroy)
 
 CELIX_UTILS_EXPORT bool celix_filter_match(const celix_filter_t *filter, const 
celix_properties_t* props);
 
-CELIX_UTILS_EXPORT bool celix_filter_matchFilter(const celix_filter_t 
*filter1, const celix_filter_t *filter2);
+CELIX_UTILS_EXPORT bool celix_filter_equals(const celix_filter_t *filter1, 
const celix_filter_t *filter2);
 
 CELIX_UTILS_EXPORT const char* celix_filter_getFilterString(const 
celix_filter_t *filter);
 
diff --git a/libs/utils/src/filter.c b/libs/utils/src/filter.c
index a414ebfe..f8eced27 100644
--- a/libs/utils/src/filter.c
+++ b/libs/utils/src/filter.c
@@ -24,11 +24,13 @@
 #include <assert.h>
 #include <utils.h>
 
-#include "celix_filter.h"
-#include "filter.h"
+#include "celix_convert_utils.h"
+#include "celix_err.h"
 #include "celix_errno.h"
+#include "celix_filter.h"
+#include "celix_stdlib_cleanup.h"
 #include "celix_version.h"
-#include "celix_convert_utils.h"
+#include "filter.h"
 
 struct celix_filter_internal {
     bool convertedToLong;
@@ -65,33 +67,29 @@ void filter_destroy(celix_filter_t * filter) {
 }
 
 static celix_filter_t * filter_parseFilter(char* filterString, int* pos) {
-    celix_filter_t * filter;
     filter_skipWhiteSpace(filterString, pos);
     if (filterString[*pos] == '\0') {
         //empty filter
-        fprintf(stderr, "Filter Error: Cannot create LDAP filter from an empty 
string.\n");
+        celix_err_push("Filter Error: Cannot create LDAP filter from an empty 
string.\n");
         return NULL;
     } else if (filterString[*pos] != '(') {
-        fprintf(stderr, "Filter Error: Missing '(' in filter string '%s'.\n", 
filterString);
+        celix_err_pushf("Filter Error: Missing '(' in filter string '%s'.\n", 
filterString);
         return NULL;
     }
     (*pos)++; //eat '('
 
-    filter = filter_parseFilterComp(filterString, pos);
+    celix_autoptr(celix_filter_t) filter = 
filter_parseFilterComp(filterString, pos);
 
     filter_skipWhiteSpace(filterString, pos);
 
     if (filterString[*pos] != ')') {
-        fprintf(stderr, "Filter Error: Missing ')' in filter string '%s'.\n", 
filterString);
-        if(filter!=NULL){
-            filter_destroy(filter);
-        }
+        celix_err_pushf("Filter Error: Missing ')' in filter string '%s'.\n", 
filterString);
         return NULL;
     }
     (*pos)++; //eat ')'
     filter_skipWhiteSpace(filterString, pos);
 
-    return filter;
+    return celix_steal_ptr(filter);
 }
 
 static celix_filter_t * filter_parseFilterComp(char * filterString, int * pos) 
{
@@ -516,7 +514,7 @@ static int celix_filter_compareAttributeValue(const 
celix_filter_t* filter, cons
     return strcmp(propertyValue, filter->value);
 }
 
-static celix_status_t filter_compareSubString(const celix_filter_t* filter, 
const celix_properties_entry_t* entry, bool* out) {
+static bool filter_compareSubString(const celix_filter_t* filter, const 
celix_properties_entry_t* entry) {
     const char* propertyValue = entry->value;
     int pos = 0;
     int size = celix_arrayList_size(filter->children);
@@ -532,8 +530,7 @@ static celix_status_t filter_compareSubString(const 
celix_filter_t* filter, cons
                 }
                 index = strcspn(propertyValue+pos, substr2);
                 if (index == strlen(propertyValue+pos)) {
-                        *out = false;
-                        return CELIX_SUCCESS;
+                        return false;
                 }
 
                 pos = index + strlen(substr2);
@@ -542,15 +539,14 @@ static celix_status_t filter_compareSubString(const 
celix_filter_t* filter, cons
                 }
             } else {
                 unsigned int len = strlen(substr);
-                char * region = (char *)calloc(1, len+1);
+                char * region = (char *)calloc(1, len+1); //TODO refactor 
filter compile to prevent calloc need
                 strncpy(region, propertyValue+pos, len);
                 region[len]    = '\0';
                 if (strcmp(region, substr) == 0) {
                         pos += len;
                 } else {
                         free(region);
-                        *out = false;
-                        return CELIX_SUCCESS;
+                        return false;
                 }
                 free(region);
             }
@@ -559,62 +555,44 @@ static celix_status_t filter_compareSubString(const 
celix_filter_t* filter, cons
             int begin;
 
             if (substr == NULL) {
-                *out = true;
-                return CELIX_SUCCESS;
+                return true;
             }
             len = strlen(substr);
             begin = strlen(propertyValue)-len;
-            *out = (strcmp(propertyValue+begin, substr) == 0);
-            return CELIX_SUCCESS;
+            return (strcmp(propertyValue+begin, substr) == 0);
         }
     }
-    *out = true;
-    return CELIX_SUCCESS;
+    return true;
 }
 
-static celix_status_t filter_matchPropertyEntry(const celix_filter_t* filter, 
const celix_properties_entry_t* entry, bool *out) {
-    celix_status_t  status = CELIX_SUCCESS;
-    bool result = false;
-
+static bool celix_filter_matchPropertyEntry(const celix_filter_t* filter, 
const celix_properties_entry_t* entry) {
     if (filter == NULL || entry == NULL) {
-        *out = false;
-        return status;
+        return false;
     }
 
     switch (filter->operand) {
         case CELIX_FILTER_OPERAND_SUBSTRING:
-            return filter_compareSubString(filter, entry, out);
+            return filter_compareSubString(filter, entry);
         case CELIX_FILTER_OPERAND_APPROX:
-            *out = strcasecmp(entry->value, filter->value) == 0;
-            return CELIX_SUCCESS;
+            return strcasecmp(entry->value, filter->value) == 0;
         case CELIX_FILTER_OPERAND_EQUAL:
-            *out = (celix_filter_compareAttributeValue(filter, entry) == 0);
-            return CELIX_SUCCESS;
+            return celix_filter_compareAttributeValue(filter, entry) == 0;
         case CELIX_FILTER_OPERAND_GREATER:
-            *out = (celix_filter_compareAttributeValue(filter, entry) > 0);
-            return CELIX_SUCCESS;
+            return celix_filter_compareAttributeValue(filter, entry) > 0;
         case CELIX_FILTER_OPERAND_GREATEREQUAL:
-            *out = (celix_filter_compareAttributeValue(filter, entry) >= 0);
-            return CELIX_SUCCESS;
+            return celix_filter_compareAttributeValue(filter, entry) >= 0;
         case CELIX_FILTER_OPERAND_LESS:
-            *out = (celix_filter_compareAttributeValue(filter, entry) < 0);
-            return CELIX_SUCCESS;
+            return celix_filter_compareAttributeValue(filter, entry) < 0;
         case CELIX_FILTER_OPERAND_LESSEQUAL:
-            *out = (celix_filter_compareAttributeValue(filter, entry) <= 0);
-            return CELIX_SUCCESS;
+            return celix_filter_compareAttributeValue(filter, entry) <= 0;
         case CELIX_FILTER_OPERAND_AND:
         case CELIX_FILTER_OPERAND_NOT:
         case CELIX_FILTER_OPERAND_OR:
         case CELIX_FILTER_OPERAND_PRESENT:
         default:
-            ;
-            /* fall through */
+            assert(false); //should not reach here
     }
-
-    if (out != NULL) {
-        *out = result;
-    }
-    return status;
+    return false;
 }
 
 celix_status_t filter_getString(celix_filter_t * filter, const char 
**filterStr) {
@@ -625,7 +603,7 @@ celix_status_t filter_getString(celix_filter_t * filter, 
const char **filterStr)
 }
 
 celix_status_t filter_match_filter(celix_filter_t *src, celix_filter_t *dest, 
bool *out) {
-    bool result = celix_filter_matchFilter(src, dest);
+    bool result = celix_filter_equals(src, dest);
     if (out != NULL) {
         *out = result;
     }
@@ -634,186 +612,188 @@ celix_status_t filter_match_filter(celix_filter_t *src, 
celix_filter_t *dest, bo
 
 
 celix_filter_t* celix_filter_create(const char *filterString) {
-    celix_filter_t * filter = NULL;
-    char* filterStr = string_ndup(filterString, 1024*1024);
+    celix_autofree char* str = celix_utils_strdup(filterString);
+    if (!str) {
+        celix_err_push("Failed to create filter string");
+        // TODO test error
+        return NULL;
+    }
+
     int pos = 0;
-    filter = filter_parseFilter(filterStr, &pos);
-    if (filter != NULL && pos != strlen(filterStr)) {
-        fprintf(stderr, "Filter Error: Extraneous trailing characters.\n");
-        filter_destroy(filter);
-        filter = NULL;
-    } else if (filter != NULL) {
-        if (filter->operand != CELIX_FILTER_OPERAND_OR && filter->operand != 
CELIX_FILTER_OPERAND_AND &&
-            filter->operand != CELIX_FILTER_OPERAND_NOT && filter->operand != 
CELIX_FILTER_OPERAND_SUBSTRING &&
-            filter->operand != CELIX_FILTER_OPERAND_PRESENT) {
-            if (filter->attribute == NULL || filter->value == NULL) {
-                filter_destroy(filter);
-                filter = NULL;
-            }
-        }
+    celix_autoptr(celix_filter_t) filter = filter_parseFilter(str, &pos);
+    if (!filter) {
+        celix_err_push("Failed to parse filter string");
+        return NULL;
+    }
+    if (pos != strlen(filterString)) {
+        celix_err_push("Filter Error: Extraneous trailing characters.\n");
+        return NULL;
     }
 
-    if (filter == NULL) {
-        free(filterStr);
-    } else {
-        filter->filterStr = filterStr;
-        celix_status_t status = celix_filter_compile(filter);
-        if (status != CELIX_SUCCESS) {
-            celix_filter_destroy(filter);
-            filter = NULL;
+    if (filter->operand != CELIX_FILTER_OPERAND_OR && filter->operand != 
CELIX_FILTER_OPERAND_AND &&
+        filter->operand != CELIX_FILTER_OPERAND_NOT && filter->operand != 
CELIX_FILTER_OPERAND_SUBSTRING &&
+        filter->operand != CELIX_FILTER_OPERAND_PRESENT) {
+        if (filter->attribute == NULL || filter->value == NULL) {
+            celix_err_push("Filter Error: Missing attribute or value.\n");
+            return NULL;
         }
     }
 
-    return filter;
+    filter->filterStr = celix_steal_ptr(str);
+    if (celix_filter_compile(filter) != CELIX_SUCCESS) {
+        // TODO test error
+        return NULL;
+    }
+    return celix_steal_ptr(filter);
 }
 
-void celix_filter_destroy(celix_filter_t *filter) {
-    if (filter != NULL) {
-        if(filter->children != NULL) {
-            if (filter->operand == CELIX_FILTER_OPERAND_SUBSTRING) {
-                int size = celix_arrayList_size(filter->children);
-                int i = 0;
-                for (i = 0; i < size; i++) {
-                    char *operand = celix_arrayList_get(filter->children, i);
-                    free(operand);
-                }
-                celix_arrayList_destroy(filter->children);
-                filter->children = NULL;
-            } else if (filter->operand == CELIX_FILTER_OPERAND_OR || 
filter->operand == CELIX_FILTER_OPERAND_AND || filter->operand == 
CELIX_FILTER_OPERAND_NOT) {
-                int size = celix_arrayList_size(filter->children);
-                int i = 0;
-                for (i = 0; i < size; i++) {
-                    celix_filter_t *f = celix_arrayList_get(filter->children, 
i);
-                    celix_filter_destroy(f);
-                }
-                celix_arrayList_destroy(filter->children);
-                filter->children = NULL;
-            } else {
-                fprintf(stderr, "Filter Error: Corrupt filter. children has a 
value, but not an expected operand\n");
-            }
-        }
-        free((char*)filter->value);
-        filter->value = NULL;
-        free((char*)filter->attribute);
-        filter->attribute = NULL;
-        free((char*)filter->filterStr);
-        filter->filterStr = NULL;
-        if (filter->internal != NULL) {
-            celix_version_destroy(filter->internal->versionValue);
-            free(filter->internal);
-        }
-        free(filter);
-    }
+void celix_filter_destroy(celix_filter_t* filter) {
+    if (!filter) {
+        return;
+    }
+
+    if (filter->children != NULL) {
+        int size = celix_arrayList_size(filter->children);
+        if (filter->operand == CELIX_FILTER_OPERAND_SUBSTRING) {
+            for (int i = 0; i < size; i++) {
+                char* operand = celix_arrayList_get(filter->children, i);
+                free(operand);
+            }
+            celix_arrayList_destroy(filter->children);
+            filter->children = NULL;
+        } else if (filter->operand == CELIX_FILTER_OPERAND_OR || 
filter->operand == CELIX_FILTER_OPERAND_AND ||
+                   filter->operand == CELIX_FILTER_OPERAND_NOT) {
+            for (int i = 0; i < size; i++) {
+                celix_filter_t* f = celix_arrayList_get(filter->children, i);
+                celix_filter_destroy(f);
+            }
+            celix_arrayList_destroy(filter->children);
+            filter->children = NULL;
+        }
+    }
+    free((char*)filter->value);
+    filter->value = NULL;
+    free((char*)filter->attribute);
+    filter->attribute = NULL;
+    free((char*)filter->filterStr);
+    filter->filterStr = NULL;
+    if (filter->internal != NULL) {
+        celix_version_destroy(filter->internal->versionValue);
+        free(filter->internal);
+    }
+    free(filter);
 }
 
-bool celix_filter_match(const celix_filter_t *filter, const 
celix_properties_t* properties) {
+bool celix_filter_match(const celix_filter_t* filter, const 
celix_properties_t* properties) {
     if (filter == NULL) {
-        return true; //matching on null(empty) filter is always true
+        return true; // matching on null(empty) filter is always true
     }
+
     switch (filter->operand) {
-        case CELIX_FILTER_OPERAND_AND: {
-            celix_array_list_t* children = filter->children;
-            for (int i = 0; i < celix_arrayList_size(children); i++) {
-                celix_filter_t * sfilter = (celix_filter_t *) 
celix_arrayList_get(children, i);
-                bool mresult = celix_filter_match(sfilter, properties);
-                if (!mresult) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        case CELIX_FILTER_OPERAND_OR: {
-            celix_array_list_t* children = filter->children;
-            for (int i = 0; i < celix_arrayList_size(children); i++) {
-                celix_filter_t * sfilter = (celix_filter_t *) 
celix_arrayList_get(children, i);
-                bool mresult = celix_filter_match(sfilter, properties);
-                if (mresult) {
-                    return true;
-                }
+    case CELIX_FILTER_OPERAND_AND: {
+        celix_array_list_t* childern = filter->children;
+        for (int i = 0; i < celix_arrayList_size(childern); i++) {
+            celix_filter_t* childFilter = 
(celix_filter_t*)celix_arrayList_get(childern, i);
+            bool childResult = celix_filter_match(childFilter, properties);
+            if (!childResult) {
+                return false;
             }
-            return false;
         }
-        case CELIX_FILTER_OPERAND_NOT: {
-            celix_filter_t * sfilter = celix_arrayList_get(filter->children, 
0);
-            bool mresult = celix_filter_match(sfilter, properties);
-            return !mresult;
-        }
-        case CELIX_FILTER_OPERAND_PRESENT: {
-            char * value = (properties == NULL) ? NULL: 
(char*)celix_properties_get(properties, filter->attribute, NULL);
-            return value != NULL;
-        }
-        case CELIX_FILTER_OPERAND_SUBSTRING :
-        case CELIX_FILTER_OPERAND_EQUAL :
-        case CELIX_FILTER_OPERAND_GREATER :
-        case CELIX_FILTER_OPERAND_GREATEREQUAL :
-        case CELIX_FILTER_OPERAND_LESS :
-        case CELIX_FILTER_OPERAND_LESSEQUAL :
-        case CELIX_FILTER_OPERAND_APPROX : {
-            celix_properties_entry_t *entry = 
celix_properties_getEntry(properties, filter->attribute);
-            bool result;
-            celix_status_t status = filter_matchPropertyEntry(filter, entry, 
&result);
-            if (status != CELIX_SUCCESS) {
-                //TODO handle error
-                return false;
+        return true;
+    }
+    case CELIX_FILTER_OPERAND_OR: {
+        celix_array_list_t* children = filter->children;
+        for (int i = 0; i < celix_arrayList_size(children); i++) {
+            celix_filter_t* childFilter = 
(celix_filter_t*)celix_arrayList_get(children, i);
+            bool childResult = celix_filter_match(childFilter, properties);
+            if (childResult) {
+                return true;
             }
-            return result;
         }
+        return false;
+    }
+    case CELIX_FILTER_OPERAND_NOT: {
+        celix_filter_t* childFilter = celix_arrayList_get(filter->children, 0);
+        bool childResult = celix_filter_match(childFilter, properties);
+        return !childResult;
+    }
+    case CELIX_FILTER_OPERAND_PRESENT: {
+        char* value = (properties == NULL) ? NULL : 
(char*)celix_properties_get(properties, filter->attribute, NULL);
+        return value != NULL;
+    }
+    case CELIX_FILTER_OPERAND_SUBSTRING:
+    case CELIX_FILTER_OPERAND_EQUAL:
+    case CELIX_FILTER_OPERAND_GREATER:
+    case CELIX_FILTER_OPERAND_GREATEREQUAL:
+    case CELIX_FILTER_OPERAND_LESS:
+    case CELIX_FILTER_OPERAND_LESSEQUAL:
+    case CELIX_FILTER_OPERAND_APPROX: {
+        const celix_properties_entry_t* entry = 
celix_properties_getEntry(properties, filter->attribute);
+        bool result = celix_filter_matchPropertyEntry(filter, entry);
+        return result;
+    }
     }
 
-    //LCOV_EXCL_START
-    assert(false); //should never happen
+    // LCOV_EXCL_START
+    assert(false); // should never happen
     return false;
-    //LCOV_EXCL_STOP
+    // LCOV_EXCL_STOP
 }
 
-bool celix_filter_matchFilter(const celix_filter_t *filter1, const 
celix_filter_t *filter2) {
-    bool result = false;
+bool celix_filter_equals(const celix_filter_t *filter1, const celix_filter_t 
*filter2) {
     if (filter1 == filter2) {
-        result = true; //NOTE. also means NULL filter are equal
-    } else if (filter1 != NULL && filter2 != NULL && filter1->operand == 
filter2->operand) {
-        if (filter1->operand == CELIX_FILTER_OPERAND_AND || filter1->operand 
== CELIX_FILTER_OPERAND_OR || filter1->operand == CELIX_FILTER_OPERAND_NOT) {
-            assert(filter1->children != NULL);
-            assert(filter2->children != NULL);
-            int sizeSrc = celix_arrayList_size(filter1->children);
-            int sizeDest = celix_arrayList_size(filter2->children);
-            if (sizeSrc == sizeDest) {
-                int i;
-                int k;
-                int sameCount = 0;
-                for (i =0; i < sizeSrc; ++i) {
-                    bool same = false;
-                    celix_filter_t *srcPart = 
celix_arrayList_get(filter1->children, i);
-                    for (k = 0; k < sizeDest; ++k) {
-                        celix_filter_t *destPart = 
celix_arrayList_get(filter2->children, k);
-                        filter_match_filter(srcPart, destPart, &same);
-                        if (same) {
-                            sameCount += 1;
-                            break;
-                        }
+        return true;
+    }
+    if (!filter1 || !filter2) {
+        return false;
+    }
+    if (filter1->operand != filter2->operand) {
+        return false;
+    }
+
+
+    if (filter1->operand == CELIX_FILTER_OPERAND_AND || filter1->operand == 
CELIX_FILTER_OPERAND_OR || filter1->operand == CELIX_FILTER_OPERAND_NOT) {
+        assert(filter1->children != NULL);
+        assert(filter2->children != NULL);
+        int sizeSrc = celix_arrayList_size(filter1->children);
+        int sizeDest = celix_arrayList_size(filter2->children);
+        if (sizeSrc == sizeDest) {
+            int i;
+            int k;
+            int sameCount = 0;
+            for (i =0; i < sizeSrc; ++i) {
+                bool same = false;
+                celix_filter_t *srcPart = 
celix_arrayList_get(filter1->children, i);
+                for (k = 0; k < sizeDest; ++k) {
+                    celix_filter_t *destPart = 
celix_arrayList_get(filter2->children, k);
+                    filter_match_filter(srcPart, destPart, &same);
+                    if (same) {
+                        sameCount += 1;
+                        break;
                     }
                 }
-                result = sameCount == sizeSrc;
-            }
-        } else { //compare attr and value
-            bool attrSame = false;
-            bool valSame = false;
-            if (filter1->attribute == NULL && filter2->attribute == NULL) {
-                attrSame = true;
-            } else if (filter1->attribute != NULL && filter2->attribute != 
NULL) {
-                attrSame = celix_utils_stringEquals(filter1->attribute, 
filter2->attribute);
             }
+            return sameCount == sizeSrc;
+        }
+        return false;
+    }
 
-            if (filter1->value == NULL  && filter2->value == NULL) {
-                valSame = true;
-            } else if (filter1->value != NULL && filter2->value != NULL) {
-                valSame = celix_utils_stringEquals(filter1->value, 
filter2->value);
-            }
+    //compare attr and value
+    bool attrSame = false;
+    bool valSame = false;
+    if (filter1->attribute == NULL && filter2->attribute == NULL) {
+        attrSame = true;
+    } else if (filter1->attribute != NULL && filter2->attribute != NULL) {
+        attrSame = celix_utils_stringEquals(filter1->attribute, 
filter2->attribute);
+    }
 
-            result = attrSame && valSame;
-        }
+    if (filter1->value == NULL  && filter2->value == NULL) {
+        valSame = true;
+    } else if (filter1->value != NULL && filter2->value != NULL) {
+        valSame = celix_utils_stringEquals(filter1->value, filter2->value);
     }
 
-    return result;
+    return attrSame && valSame;
 }
 
 const char* celix_filter_getFilterString(const celix_filter_t *filter) {
@@ -907,4 +887,4 @@ static bool hasMandatoryNegatedPresenceAttribute(const 
celix_filter_t *filter, c
 }
 bool celix_filter_hasMandatoryNegatedPresenceAttribute(const celix_filter_t 
*filter, const char *attribute) {
     return hasMandatoryNegatedPresenceAttribute(filter, attribute, false, 
false);
-}
\ No newline at end of file
+}

Reply via email to