Repository: celix
Updated Branches:
  refs/heads/develop b0477babb -> f4cd98387


Refactors filter so that it is possible to traverse parsed filter. Also fixes 
an issue where semantically equal filter where not matched


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/f4cd9838
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/f4cd9838
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/f4cd9838

Branch: refs/heads/develop
Commit: f4cd983871cd2050244743c0dc047c62b11c1adb
Parents: b0477ba
Author: Pepijn Noltes <pepijnnol...@gmail.com>
Authored: Mon Feb 12 23:56:42 2018 +0100
Committer: Pepijn Noltes <pepijnnol...@gmail.com>
Committed: Mon Feb 12 23:56:47 2018 +0100

----------------------------------------------------------------------
 framework/include/filter.h             |  44 ++-
 framework/private/test/filter_test.cpp |  80 +++--
 framework/src/filter.c                 | 519 ++++++++++++++--------------
 framework/src/filter_private.h         |  57 ---
 utils/include/array_list.h             |   2 +
 5 files changed, 351 insertions(+), 351 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/f4cd9838/framework/include/filter.h
----------------------------------------------------------------------
diff --git a/framework/include/filter.h b/framework/include/filter.h
index 687de2a..179ef53 100644
--- a/framework/include/filter.h
+++ b/framework/include/filter.h
@@ -31,22 +31,54 @@
 #include "properties.h"
 #include "celixbool.h"
 #include "framework_exports.h"
+#include "array_list.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef struct filter *filter_pt;
+typedef enum celix_filter_operand_enum
+{
+    CELIX_FILTER_OPERAND_EQUAL,
+    CELIX_FILTER_OPERAND_APPROX,
+    CELIX_FILTER_OPERAND_GREATER,
+    CELIX_FILTER_OPERAND_GREATEREQUAL,
+    CELIX_FILTER_OPERAND_LESS,
+    CELIX_FILTER_OPERAND_LESSEQUAL,
+    CELIX_FILTER_OPERAND_PRESENT,
+    CELIX_FILTER_OPERAND_SUBSTRING,
+    CELIX_FILTER_OPERAND_AND,
+    CELIX_FILTER_OPERAND_OR,
+    CELIX_FILTER_OPERAND_NOT,
+} celix_filter_operand_t;
 
-FRAMEWORK_EXPORT filter_pt filter_create(const char *filterString);
+typedef struct celix_filter_struct filter_t; //deprecated
+typedef struct celix_filter_struct *filter_pt; //deprecated
 
-FRAMEWORK_EXPORT void filter_destroy(filter_pt filter);
+typedef struct celix_filter_struct celix_filter_t;
 
-FRAMEWORK_EXPORT celix_status_t filter_match(filter_pt filter, properties_pt 
properties, bool *result);
+struct celix_filter_struct {
+    celix_filter_operand_t operand;
+    char *attribute; //NULL for operands AND, OR ot NOT
+    char *value; //NULL for operands AND, OR or NOT NOT
+    char *filterStr;
 
-FRAMEWORK_EXPORT celix_status_t filter_match_filter(filter_pt src, filter_pt 
dest, bool *result);
+    //type is celix_filter_t* for AND, OR and NOT operator and char* for 
SUBSTRING
+    //for other operands childern is NULL
+    array_list_t *children;
+};
 
-FRAMEWORK_EXPORT celix_status_t filter_getString(filter_pt filter, const char 
**filterStr);
+FRAMEWORK_EXPORT celix_filter_t* filter_create(const char *filterString);
+
+FRAMEWORK_EXPORT void filter_destroy(celix_filter_t *filter);
+
+FRAMEWORK_EXPORT celix_status_t filter_match(celix_filter_t *filter, 
properties_t *properties, bool *result);
+
+FRAMEWORK_EXPORT celix_status_t filter_match_filter(celix_filter_t *src, 
filter_t *dest, bool *result);
+
+FRAMEWORK_EXPORT celix_status_t filter_getString(celix_filter_t *filter, const 
char **filterStr);
+
+FRAMEWORK_EXPORT celix_status_t filter_getString(celix_filter_t *filter, const 
char **filterStr);
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/f4cd9838/framework/private/test/filter_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/filter_test.cpp 
b/framework/private/test/filter_test.cpp
index c9b1ca5..b802923 100644
--- a/framework/private/test/filter_test.cpp
+++ b/framework/private/test/filter_test.cpp
@@ -16,13 +16,7 @@
  *specific language governing permissions and limitations
  *under the License.
  */
-/*
- * filter_test.cpp
- *
- *  \date       Feb 11, 2013
- *  \author     <a href="mailto:d...@celix.apache.org";>Apache Celix Project 
Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -33,8 +27,8 @@
 #include "CppUTestExt/MockSupport.h"
 
 extern "C" {
-#include "filter_private.h"
 #include "celix_log.h"
+#include "filter.h"
 
 framework_logger_pt logger = (framework_logger_pt) 0x42;
 }
@@ -73,7 +67,7 @@ TEST_GROUP(filter) {
 //----------------FILTER TESTS----------------
 TEST(filter, create_destroy){
        char * filter_str = 
my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
-       filter_pt get_filter;
+       celix_filter_t * get_filter;
 
        get_filter = filter_create(filter_str);
        CHECK(get_filter != NULL);
@@ -88,7 +82,7 @@ TEST(filter, create_destroy){
 
 TEST(filter, create_fail_missing_opening_brackets){
        char * filter_str;
-       filter_pt get_filter;
+       celix_filter_t * get_filter;
 
        //test missing opening brackets in main filter
        mock().expectNCalls(2, "framework_log");
@@ -125,7 +119,7 @@ TEST(filter, create_fail_missing_opening_brackets){
 
 TEST(filter, create_fail_missing_closing_brackets){
        char * filter_str;
-       filter_pt get_filter;
+       celix_filter_t * get_filter;
        //test missing closing brackets in substring
        mock().expectNCalls(5, "framework_log");
        filter_str = 
my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3");
@@ -145,7 +139,7 @@ TEST(filter, create_fail_missing_closing_brackets){
 
 TEST(filter, create_fail_invalid_closing_brackets){
        char * filter_str;
-       filter_pt get_filter;
+       celix_filter_t * get_filter;
        //test missing closing brackets in substring
        mock().expectNCalls(6, "framework_log");
        filter_str = 
my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=at(tr3)))");
@@ -165,7 +159,7 @@ TEST(filter, create_fail_invalid_closing_brackets){
 
 TEST(filter, create_misc){
        char * filter_str;
-       filter_pt get_filter;
+       celix_filter_t * get_filter;
        //test trailing chars
        mock().expectOneCall("framework_log");
        filter_str = 
my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3))) oh no! 
trailing chars");
@@ -186,8 +180,8 @@ TEST(filter, create_misc){
        filter_str = my_strdup("(test_attr3=*attr3)");
        get_filter = filter_create(filter_str);
        CHECK(get_filter != NULL);
-       LONGS_EQUAL(SUBSTRING, get_filter->operand)
-       LONGS_EQUAL(2, arrayList_size((array_list_pt) get_filter->value));
+       LONGS_EQUAL(CELIX_FILTER_OPERAND_SUBSTRING, get_filter->operand)
+       LONGS_EQUAL(2, arrayList_size((array_list_pt) get_filter->children));
        filter_destroy(get_filter);
        free(filter_str);
        mock().checkExpectations();
@@ -229,7 +223,7 @@ TEST(filter, create_misc){
 
 TEST(filter, match_comparators){
        char * filter_str;
-       filter_pt filter;
+       celix_filter_t * filter;
        properties_pt props = properties_create();
        char * key = my_strdup("test_attr1");
        char * val = my_strdup("attr1");
@@ -268,7 +262,7 @@ TEST(filter, match_comparators){
 
 TEST(filter, match_operators){
        char * filter_str;
-       filter_pt filter;
+       celix_filter_t * filter;
        properties_pt props = properties_create();
        char * key = my_strdup("test_attr1");
        char * val = my_strdup("attr1");
@@ -470,7 +464,7 @@ TEST(filter, match_operators){
 TEST(filter, match_recursion){
 
        char * filter_str = 
my_strdup("(&(test_attr1=attr1)(|(&(test_attr2=attr2)(!(&(test_attr1=attr1)(test_attr3=attr3))))(test_attr3=attr3)))");
-       filter_pt filter = filter_create(filter_str);
+       celix_filter_t * filter = filter_create(filter_str);
        properties_pt props = properties_create();
        char * key = my_strdup("test_attr1");
        char * val = my_strdup("attr1");
@@ -497,7 +491,7 @@ TEST(filter, match_recursion){
 
 TEST(filter, match_false){
        char * filter_str = 
my_strdup("(&(test_attr1=attr1)(&(test_attr2=attr2)(test_attr3=attr3)))");
-       filter_pt filter = filter_create(filter_str);
+       celix_filter_t * filter = filter_create(filter_str);
        properties_pt props = properties_create();
        char * key = my_strdup("test_attr1");
        char * val = my_strdup("attr1");
@@ -523,26 +517,54 @@ TEST(filter, match_false){
 }
 
 TEST(filter, match_filter){
-       char * filter_str = 
my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
-       char * compareTo_str = 
my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
-       filter_pt filter = filter_create(filter_str);
-       filter_pt compareTo = filter_create(compareTo_str);
+       mock().ignoreOtherCalls(); //only log
 
-       bool result;
-       filter_match_filter(filter, compareTo, &result);
+       celix_filter_t *filter = 
filter_create("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
+    celix_filter_t *compareTo = 
filter_create("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
 
+       bool result;
+       filter_match_filter(filter, compareTo, &result); //equal same order
+    CHECK_TRUE(result);
        //cleanup
        filter_destroy(filter);
        filter_destroy(compareTo);
-       free(filter_str);
-       free(compareTo_str);
 
-       mock().checkExpectations();
+    filter = 
filter_create("(&(test_attr1=attr1)(test_attr2=attr2)(test_attr3=attr3))");
+    compareTo = 
filter_create("(&(test_attr3=attr3)(test_attr2=attr2)(test_attr1=attr1))");
+       CHECK(filter != NULL);
+       CHECK(compareTo != NULL);
+    filter_match_filter(filter, compareTo, &result); //equal not same order
+    CHECK_TRUE(result);
+    //cleanup
+    filter_destroy(filter);
+    filter_destroy(compareTo);
+
+    filter = 
filter_create("(&(test_attr1=attr1)(test_attr2=attr2)(test_attr3=attr3))");
+    compareTo = 
filter_create("(&(test_attr1=attr1)(test_attr2=attr2)(test_attr4=attr4))");
+       CHECK(filter != NULL);
+       CHECK(compareTo != NULL);
+    filter_match_filter(filter, compareTo, &result); //almost, but not equal
+    CHECK_FALSE(result);
+    //cleanup
+    filter_destroy(filter);
+    filter_destroy(compareTo);
+
+       filter_match_filter(NULL, NULL, &result); //both null  -> equal
+       CHECK_TRUE(result);
+
+       filter = filter_create("(attr1=)");
+       filter_match_filter(filter, NULL, &result); //one null  -> not equal
+       CHECK_FALSE(result);
+
+       filter_match_filter(NULL, filter, &result); //one null  -> not equal
+       CHECK_FALSE(result);
+
+       filter_destroy(filter);
 }
 
 TEST(filter, getString){
        char * filter_str = 
my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
-       filter_pt filter = filter_create(filter_str);
+       celix_filter_t * filter = filter_create(filter_str);
 
        const char * get_str;
        filter_getString(filter, &get_str);

http://git-wip-us.apache.org/repos/asf/celix/blob/f4cd9838/framework/src/filter.c
----------------------------------------------------------------------
diff --git a/framework/src/filter.c b/framework/src/filter.c
index f06d6e8..7077b08 100644
--- a/framework/src/filter.c
+++ b/framework/src/filter.c
@@ -27,23 +27,22 @@
 #include <string.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <assert.h>
 
 #include "celix_log.h"
-#include "filter_private.h"
+#include "filter.h"
 
 static void filter_skipWhiteSpace(char* filterString, int* pos);
-static filter_pt filter_parseFilter(char* filterString, int* pos);
-static filter_pt filter_parseFilterComp(char* filterString, int* pos);
-static filter_pt filter_parseAnd(char* filterString, int* pos);
-static filter_pt filter_parseOr(char* filterString, int* pos);
-static filter_pt filter_parseNot(char* filterString, int* pos);
-static filter_pt filter_parseItem(char* filterString, int* pos);
+static celix_filter_t * filter_parseFilter(char* filterString, int* pos);
+static celix_filter_t * filter_parseFilterComp(char* filterString, int* pos);
+static celix_filter_t * filter_parseAndOrOr(char* filterString, 
celix_filter_operand_t andOrOr, int* pos);
+static celix_filter_t * filter_parseNot(char* filterString, int* pos);
+static celix_filter_t * filter_parseItem(char* filterString, int* pos);
 static char * filter_parseAttr(char* filterString, int* pos);
 static char * filter_parseValue(char* filterString, int* pos);
 static array_list_pt filter_parseSubstring(char* filterString, int* pos);
 
-static celix_status_t filter_compare(OPERAND operand, char * string, void * 
value2, bool *result);
-static celix_status_t filter_compareString(OPERAND operand, char * string, 
void * value2, bool *result);
+static celix_status_t filter_compare(celix_filter_t* filter, const char 
*propertyValue, bool *result);
 
 static void filter_skipWhiteSpace(char * filterString, int * pos) {
        int length;
@@ -52,60 +51,69 @@ static void filter_skipWhiteSpace(char * filterString, int 
* pos) {
        }
 }
 
-filter_pt filter_create(const char* filterString) {
-       filter_pt filter = NULL;
-       char* filterStr = (char*) filterString;
+celix_filter_t * filter_create(const char* filterString) {
+       celix_filter_t * filter = NULL;
+       char* filterStr = strndup(filterString, 1024*1024);
        int pos = 0;
        filter = filter_parseFilter(filterStr, &pos);
        if (pos != strlen(filterStr)) {
                fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error: Extraneous 
trailing characters.");
+        free(filterStr);
                filter_destroy(filter);
                return NULL;
        }
-       if(filter != NULL){
-               filter->filterStr = filterStr;
-       } 
+       if (filter != NULL) {
+        filter->filterStr = filterStr;
+
+        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;
+            }
+        }
+    }
 
        return filter;
 }
 
-void filter_destroy(filter_pt filter) {
+void filter_destroy(celix_filter_t * filter) {
        if (filter != NULL) {
-               if(filter->value!=NULL){
-                       if (filter->operand == SUBSTRING) {
-                               int size = arrayList_size(filter->value);
+               if(filter->children != NULL){
+                       if (filter->operand == CELIX_FILTER_OPERAND_SUBSTRING) {
+                               int size = arrayList_size(filter->children);
                                for (; size > 0; --size) {
-                                       char* operand = (char*) 
arrayList_remove(filter->value, 0);
+                                       char* operand = (char*) 
arrayList_remove(filter->children, 0);
                                        free(operand);
                                }
-                               arrayList_destroy(filter->value);
-                               filter->value = NULL;
-                       } else if ( (filter->operand == OR) || (filter->operand 
== AND) ) {
-                               int size = arrayList_size(filter->value);
-                               unsigned int i = 0;
-                               for (i = 0; i < size; i++) {
-                                       filter_pt f = 
arrayList_get(filter->value, i);
-                                       filter_destroy(f);
-                               }
-                               arrayList_destroy(filter->value);
-                               filter->value = NULL;
-                       } else  if (filter->operand == NOT) {
-                               filter_destroy(filter->value);
-                               filter->value = NULL;
-                       } else {
-                               free(filter->value);
-                               filter->value = NULL;
-                       }
+                               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 = arrayList_size(filter->children);
+                unsigned int i = 0;
+                for (i = 0; i < size; i++) {
+                    celix_filter_t *f = arrayList_get(filter->children, i);
+                    filter_destroy(f);
+                }
+                arrayList_destroy(filter->children);
+                filter->children = NULL;
+            } else {
+                fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error: Corrupt 
filter. childern has a value, but not an expected operand");
+            }
                }
+        free(filter->value);
+        filter->value = NULL;
                free(filter->attribute);
                filter->attribute = NULL;
                free(filter);
-               filter = NULL;
+        free(filter->filterStr);
+        filter->filterStr = NULL;
        }
 }
 
-static filter_pt filter_parseFilter(char * filterString, int * pos) {
-       filter_pt filter;
+static celix_filter_t * filter_parseFilter(char * filterString, int * pos) {
+       celix_filter_t * filter;
        filter_skipWhiteSpace(filterString, pos);
        if (filterString[*pos] != '(') {
                fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Missing '(' in 
filter string '%s'.", filterString);
@@ -127,17 +135,10 @@ static filter_pt filter_parseFilter(char * filterString, 
int * pos) {
        (*pos)++;
        filter_skipWhiteSpace(filterString, pos);
 
-       if(filter != NULL){
-               if(filter->value == NULL && filter->operand!=PRESENT){
-                       filter_destroy(filter);
-                       return NULL;
-               }
-       }
-
        return filter;
 }
 
-static filter_pt filter_parseFilterComp(char * filterString, int * pos) {
+static celix_filter_t * filter_parseFilterComp(char * filterString, int * pos) 
{
        char c;
        filter_skipWhiteSpace(filterString, pos);
 
@@ -146,11 +147,11 @@ static filter_pt filter_parseFilterComp(char * 
filterString, int * pos) {
        switch (c) {
                case '&': {
                        (*pos)++;
-                       return filter_parseAnd(filterString, pos);
+                       return filter_parseAndOrOr(filterString, 
CELIX_FILTER_OPERAND_AND, pos);
                }
                case '|': {
                        (*pos)++;
-                       return filter_parseOr(filterString, pos);
+                       return filter_parseAndOrOr(filterString, 
CELIX_FILTER_OPERAND_OR, pos);
                }
                case '!': {
                        (*pos)++;
@@ -160,9 +161,9 @@ static filter_pt filter_parseFilterComp(char * 
filterString, int * pos) {
        return filter_parseItem(filterString, pos);
 }
 
-static filter_pt filter_parseAnd(char * filterString, int * pos) {
+static celix_filter_t * filter_parseAndOrOr(char * filterString, 
celix_filter_operand_t andOrOr, int * pos) {
 
-       array_list_pt operands = NULL;
+       array_list_pt children = NULL;
        filter_skipWhiteSpace(filterString, pos);
        bool failure = false;
 
@@ -171,78 +172,35 @@ static filter_pt filter_parseAnd(char * filterString, int 
* pos) {
                return NULL;
        }
 
-       arrayList_create(&operands);
+       arrayList_create(&children);
        while(filterString[*pos] == '(') {
-               filter_pt child = filter_parseFilter(filterString, pos);
-               if(child == NULL){
+               celix_filter_t * child = filter_parseFilter(filterString, pos);
+               if(child == NULL) {
                        failure = true;
                        break;
                }
-               arrayList_add(operands, child);
+               arrayList_add(children, child);
        }
 
        if(failure == true){
-               array_list_iterator_pt listIt = 
arrayListIterator_create(operands);
-               while(arrayListIterator_hasNext(listIt)){
-                       filter_pt f = arrayListIterator_next(listIt);
+        int i;
+               for (i = 0; i < arrayList_size(children); ++i) {
+                       celix_filter_t * f = arrayList_get(children, i);
                        filter_destroy(f);
                }
-               arrayListIterator_destroy(listIt);
-               arrayList_destroy(operands);
-               operands = NULL;
+               arrayList_destroy(children);
+        children = NULL;
        }
 
-       filter_pt filter = (filter_pt) malloc(sizeof(*filter));
-       filter->operand = AND;
-       filter->attribute = NULL;
-       filter->value = operands;
+       celix_filter_t * filter = (celix_filter_t *) calloc(1, sizeof(*filter));
+       filter->operand = andOrOr;
+    filter->children = children;
 
        return filter;
 }
 
-static filter_pt filter_parseOr(char * filterString, int * pos) {
-
-       array_list_pt operands = NULL;
-
-       filter_skipWhiteSpace(filterString, pos);
-       bool failure = false;
-
-       if (filterString[*pos] != '(') {
-               fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Missing '('.");
-               return NULL;
-       }
-
-       arrayList_create(&operands);
-       while(filterString[*pos] == '(') {
-               filter_pt child = filter_parseFilter(filterString, pos);
-               if(child == NULL){
-                       failure = true;
-                       break;
-               }
-               arrayList_add(operands, child);
-       }
-
-       if(failure == true){
-               array_list_iterator_pt listIt = 
arrayListIterator_create(operands);
-               while(arrayListIterator_hasNext(listIt)){
-                       filter_pt f = arrayListIterator_next(listIt);
-                       filter_destroy(f);
-               }
-               arrayListIterator_destroy(listIt);
-               arrayList_destroy(operands);
-               operands = NULL;
-       }
-
-       filter_pt filter = (filter_pt) malloc(sizeof(*filter));
-       filter->operand = OR;
-       filter->attribute = NULL;
-       filter->value = operands;
-
-       return filter;
-}
-
-static filter_pt filter_parseNot(char * filterString, int * pos) {
-       filter_pt child = NULL;
+static celix_filter_t * filter_parseNot(char * filterString, int * pos) {
+       celix_filter_t * child = NULL;
        filter_skipWhiteSpace(filterString, pos);
 
        if (filterString[*pos] != '(') {
@@ -252,16 +210,18 @@ static filter_pt filter_parseNot(char * filterString, int 
* pos) {
 
        child = filter_parseFilter(filterString, pos);
 
+    array_list_t* children = NULL;
+    arrayList_create(&children);
+    arrayList_add(children, child);
 
-       filter_pt filter = (filter_pt) malloc(sizeof(*filter));
-       filter->operand = NOT;
-       filter->attribute = NULL;
-       filter->value = child;
+       celix_filter_t * filter = (celix_filter_t *) calloc(1, sizeof(*filter));
+       filter->operand = CELIX_FILTER_OPERAND_NOT;
+       filter->children = children;
 
        return filter;
 }
 
-static filter_pt filter_parseItem(char * filterString, int * pos) {
+static celix_filter_t * filter_parseItem(char * filterString, int * pos) {
        char * attr = filter_parseAttr(filterString, pos);
        if(attr == NULL){
                return NULL;
@@ -271,9 +231,9 @@ static filter_pt filter_parseItem(char * filterString, int 
* pos) {
        switch(filterString[*pos]) {
                case '~': {
                        if (filterString[*pos + 1] == '=') {
-                               filter_pt filter = (filter_pt) 
malloc(sizeof(*filter));
+                               celix_filter_t * filter = (celix_filter_t *) 
calloc(1, sizeof(*filter));
                                *pos += 2;
-                               filter->operand = APPROX;
+                               filter->operand = CELIX_FILTER_OPERAND_APPROX;
                                filter->attribute = attr;
                                filter->value = filter_parseValue(filterString, 
pos);
                                return filter;
@@ -282,17 +242,17 @@ static filter_pt filter_parseItem(char * filterString, 
int * pos) {
                }
                case '>': {
                        if (filterString[*pos + 1] == '=') {
-                               filter_pt filter = (filter_pt) 
malloc(sizeof(*filter));
+                               celix_filter_t * filter = (celix_filter_t *) 
calloc(1, sizeof(*filter));
                                *pos += 2;
-                               filter->operand = GREATEREQUAL;
+                               filter->operand = 
CELIX_FILTER_OPERAND_GREATEREQUAL;
                                filter->attribute = attr;
                                filter->value = filter_parseValue(filterString, 
pos);
                                return filter;
                        }
                        else {
-                filter_pt filter = (filter_pt) malloc(sizeof(*filter));
+                celix_filter_t * filter = (celix_filter_t *) calloc(1, 
sizeof(*filter));
                 *pos += 1;
-                filter->operand = GREATER;
+                filter->operand = CELIX_FILTER_OPERAND_GREATER;
                 filter->attribute = attr;
                 filter->value = filter_parseValue(filterString, pos);
                 return filter;
@@ -301,17 +261,17 @@ static filter_pt filter_parseItem(char * filterString, 
int * pos) {
                }
                case '<': {
                        if (filterString[*pos + 1] == '=') {
-                               filter_pt filter = (filter_pt) 
malloc(sizeof(*filter));
+                               celix_filter_t * filter = (celix_filter_t *) 
calloc(1, sizeof(*filter));
                                *pos += 2;
-                               filter->operand = LESSEQUAL;
+                               filter->operand = 
CELIX_FILTER_OPERAND_LESSEQUAL;
                                filter->attribute = attr;
                                filter->value = filter_parseValue(filterString, 
pos);
                                return filter;
                        }
                        else {
-                filter_pt filter = (filter_pt) malloc(sizeof(*filter));
+                celix_filter_t * filter = (celix_filter_t *) calloc(1, 
sizeof(*filter));
                 *pos += 1;
-                filter->operand = LESS;
+                filter->operand = CELIX_FILTER_OPERAND_LESS;
                 filter->attribute = attr;
                 filter->value = filter_parseValue(filterString, pos);
                 return filter;
@@ -319,29 +279,29 @@ static filter_pt filter_parseItem(char * filterString, 
int * pos) {
                        break;
                }
                case '=': {
-                       filter_pt filter = NULL;
+                       celix_filter_t * filter = NULL;
                        array_list_pt subs;
                        if (filterString[*pos + 1] == '*') {
                                int oldPos = *pos;
                                *pos += 2;
                                filter_skipWhiteSpace(filterString, pos);
                                if (filterString[*pos] == ')') {
-                                       filter_pt filter = (filter_pt) 
malloc(sizeof(*filter));
-                                       filter->operand = PRESENT;
+                                       celix_filter_t * filter = 
(celix_filter_t *) calloc(1, sizeof(*filter));
+                                       filter->operand = 
CELIX_FILTER_OPERAND_PRESENT;
                                        filter->attribute = attr;
                                        filter->value = NULL;
                                        return filter;
                                }
                                *pos = oldPos;
                        }
-                       filter = (filter_pt) malloc(sizeof(*filter));           
        
+                       filter = (celix_filter_t *) calloc(1, sizeof(*filter)); 
                
                        (*pos)++;
                        subs = filter_parseSubstring(filterString, pos);
                        if(subs!=NULL){
                                if (arrayList_size(subs) == 1) {
                                        char * string = (char *) 
arrayList_get(subs, 0);
                                        if (string != NULL) {
-                                               filter->operand = EQUAL;
+                                               filter->operand = 
CELIX_FILTER_OPERAND_EQUAL;
                                                filter->attribute = attr;
                                                filter->value = string;
 
@@ -352,9 +312,9 @@ static filter_pt filter_parseItem(char * filterString, int 
* pos) {
                                        }
                                }
                        }
-                       filter->operand = SUBSTRING;
+                       filter->operand = CELIX_FILTER_OPERAND_SUBSTRING;
                        filter->attribute = attr;
-                       filter->value = subs;
+            filter->children = subs;
                        return filter;
                }
        }
@@ -388,7 +348,7 @@ static char * filter_parseAttr(char * filterString, int * 
pos) {
                fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Missing attr.");
                return NULL;
        } else {
-               char * attr = (char *) malloc(length+1);
+               char * attr = (char *) calloc(1, length+1);
                strncpy(attr, filterString+begin, length);
                attr[length] = '\0';
                return attr;
@@ -504,13 +464,13 @@ static array_list_pt filter_parseSubstring(char * 
filterString, int * pos) {
        return operands;
 }
 
-celix_status_t filter_match(filter_pt filter, properties_pt properties, bool 
*result) {
+celix_status_t filter_match(celix_filter_t * filter, properties_pt properties, 
bool *result) {
        switch (filter->operand) {
-               case AND: {
-                       array_list_pt filters = (array_list_pt) filter->value;
+               case CELIX_FILTER_OPERAND_AND: {
+                       array_list_pt children = filter->children;
                        unsigned int i;
-                       for (i = 0; i < arrayList_size(filters); i++) {
-                               filter_pt sfilter = (filter_pt) 
arrayList_get(filters, i);
+                       for (i = 0; i < arrayList_size(children); i++) {
+                               celix_filter_t * sfilter = (celix_filter_t *) 
arrayList_get(children, i);
                                bool mresult;
                                filter_match(sfilter, properties, &mresult);
                                if (!mresult) {
@@ -521,11 +481,11 @@ celix_status_t filter_match(filter_pt filter, 
properties_pt properties, bool *re
                        *result = 1;
                        return CELIX_SUCCESS;
                }
-               case OR: {
-                       array_list_pt filters = (array_list_pt) filter->value;
+               case CELIX_FILTER_OPERAND_OR: {
+                       array_list_pt children = filter->children;
                        unsigned int i;
-                       for (i = 0; i < arrayList_size(filters); i++) {
-                               filter_pt sfilter = (filter_pt) 
arrayList_get(filters, i);
+                       for (i = 0; i < arrayList_size(children); i++) {
+                               celix_filter_t * sfilter = (celix_filter_t *) 
arrayList_get(children, i);
                                bool mresult;
                                filter_match(sfilter, properties, &mresult);
                                if (mresult) {
@@ -536,25 +496,25 @@ celix_status_t filter_match(filter_pt filter, 
properties_pt properties, bool *re
                        *result = 0;
                        return CELIX_SUCCESS;
                }
-               case NOT: {
-                       filter_pt sfilter = (filter_pt) filter->value;
+               case CELIX_FILTER_OPERAND_NOT: {
+                       celix_filter_t * sfilter = 
arrayList_get(filter->children, 0);
                        bool mresult;
                        filter_match(sfilter, properties, &mresult);
                        *result = !mresult;
                        return CELIX_SUCCESS;
                }
-               case SUBSTRING :
-               case EQUAL :
-               case GREATER :
-        case GREATEREQUAL :
-               case LESS :
-        case LESSEQUAL :
-               case APPROX : {
+               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 : {
                        char * value = (properties == NULL) ? NULL: 
(char*)properties_get(properties, filter->attribute);
 
-                       return filter_compare(filter->operand, value, 
filter->value, result);
+                       return filter_compare(filter, value, result);
                }
-               case PRESENT: {
+               case CELIX_FILTER_OPERAND_PRESENT: {
                        char * value = (properties == NULL) ? NULL: 
(char*)properties_get(properties, filter->attribute);
                        *result = value != NULL;
                        return CELIX_SUCCESS;
@@ -564,124 +524,165 @@ celix_status_t filter_match(filter_pt filter, 
properties_pt properties, bool *re
        return CELIX_SUCCESS;
 }
 
-static celix_status_t filter_compare(OPERAND operand, char * string, void * 
value2, bool *result) {
-       if (string == NULL) {
-               *result = 0;
-               return CELIX_SUCCESS;
-       }
-       return filter_compareString(operand, string, value2, result);
-
-}
-
-static celix_status_t filter_compareString(OPERAND operand, char * string, 
void * value2, bool *result) {
-       switch (operand) {
-               case SUBSTRING: {
-                       array_list_pt subs = (array_list_pt) value2;
-                       int pos = 0;
-                       unsigned int i;
-                       int size = arrayList_size(subs);
-                       for (i = 0; i < size; i++) {
-                               char * substr = (char *) arrayList_get(subs, i);
-
-                               if (i + 1 < size) {
-                                       if (substr == NULL) {
-                                               unsigned int index;
-                                               char * substr2 = (char *) 
arrayList_get(subs, i + 1);
-                                               if (substr2 == NULL) {
-                                                       continue;
-                                               }
-                                               index = strcspn(string+pos, 
substr2);
-                                               if (index == 
strlen(string+pos)) {
-                                                       *result = false;
-                                                       return CELIX_SUCCESS;
-                                               }
-
-                                               pos = index + strlen(substr2);
-                                               if (i + 2 < size) {
-                                                       i++;
-                                               }
-                                       } else {
-                                               unsigned int len = 
strlen(substr);
-                                               char * region = (char 
*)malloc(len+1);
-                                               strncpy(region, string+pos, 
len);
-                                               region[len]     = '\0';
-                                               if (strcmp(region, substr) == 
0) {
-                                                       pos += len;
-                                               } else {
-                                                       free(region);
-                                                       *result = false;
-                                                       return CELIX_SUCCESS;
-                                               }
-                                               free(region);
-                                       }
-                               } else {
-                                       unsigned int len;
-                                       int begin;
-
-                                       if (substr == NULL) {
-                                               *result = true;
-                                               return CELIX_SUCCESS;
-                                       }
-                                       len = strlen(substr);
-                                       begin = strlen(string)-len;
-                                       *result = (strcmp(string+begin, substr) 
== 0);
-                                       return CELIX_SUCCESS;
-                               }
-                       }
-                       *result = true;
-                       return CELIX_SUCCESS;
-               }
-               case APPROX: //TODO: Implement strcmp with ignorecase and 
ignorespaces
-               case EQUAL: {
-                       *result = (strcmp(string, (char *) value2) == 0);
-                       return CELIX_SUCCESS;
-               }
-               case GREATER: {
-                       *result = (strcmp(string, (char *) value2) > 0);
-                       return CELIX_SUCCESS;
-               }
-        case GREATEREQUAL: {
-            *result = (strcmp(string, (char *) value2) >= 0);
+static celix_status_t filter_compare(celix_filter_t* filter, const char 
*propertyValue, bool *out) {
+    celix_status_t  status = CELIX_SUCCESS;
+    bool result = false;
+
+    if (filter == NULL || propertyValue == NULL) {
+        *out = false;
+        return status;
+    }
+
+    switch (filter->operand) {
+        case CELIX_FILTER_OPERAND_SUBSTRING: {
+            int pos = 0;
+            unsigned int i;
+            int size = arrayList_size(filter->children);
+            for (i = 0; i < size; i++) {
+                char * substr = (char *) arrayList_get(filter->children, i);
+
+                if (i + 1 < size) {
+                    if (substr == NULL) {
+                        unsigned int index;
+                        char * substr2 = (char *) 
arrayList_get(filter->children, i + 1);
+                        if (substr2 == NULL) {
+                            continue;
+                        }
+                        index = strcspn(propertyValue+pos, substr2);
+                        if (index == strlen(propertyValue+pos)) {
+                            *out = false;
+                            return CELIX_SUCCESS;
+                        }
+
+                        pos = index + strlen(substr2);
+                        if (i + 2 < size) {
+                            i++;
+                        }
+                    } else {
+                        unsigned int len = strlen(substr);
+                        char * region = (char *)calloc(1, len+1);
+                        strncpy(region, propertyValue+pos, len);
+                        region[len]    = '\0';
+                        if (strcmp(region, substr) == 0) {
+                            pos += len;
+                        } else {
+                            free(region);
+                            *out = false;
+                            return CELIX_SUCCESS;
+                        }
+                        free(region);
+                    }
+                } else {
+                    unsigned int len;
+                    int begin;
+
+                    if (substr == NULL) {
+                        *out = true;
+                        return CELIX_SUCCESS;
+                    }
+                    len = strlen(substr);
+                    begin = strlen(propertyValue)-len;
+                    *out = (strcmp(propertyValue+begin, substr) == 0);
+                    return CELIX_SUCCESS;
+                }
+            }
+            *out = true;
             return CELIX_SUCCESS;
         }
-               case LESS: {
-                       *result = (strcmp(string, (char *) value2) < 0);
-                       return CELIX_SUCCESS;
-               }
-        case LESSEQUAL: {
-            *result = (strcmp(string, (char *) value2) <= 0);
+        case CELIX_FILTER_OPERAND_APPROX: //TODO: Implement strcmp with 
ignorecase and ignorespaces
+        case CELIX_FILTER_OPERAND_EQUAL: {
+            *out = (strcmp(propertyValue, filter->value) == 0);
             return CELIX_SUCCESS;
         }
-               case AND:
-               case NOT:
-               case OR:
-               case PRESENT: {
-               }
-               /* no break */
-       }
-       *result = false;
-       return CELIX_SUCCESS;
+        case CELIX_FILTER_OPERAND_GREATER: {
+            *out = (strcmp(propertyValue, filter->value) > 0);
+            return CELIX_SUCCESS;
+        }
+        case CELIX_FILTER_OPERAND_GREATEREQUAL: {
+            *out = (strcmp(propertyValue, filter->value) >= 0);
+            return CELIX_SUCCESS;
+        }
+        case CELIX_FILTER_OPERAND_LESS: {
+            *out = (strcmp(propertyValue, filter->value) < 0);
+            return CELIX_SUCCESS;
+        }
+        case CELIX_FILTER_OPERAND_LESSEQUAL: {
+            *out = (strcmp(propertyValue, filter->value) <= 0);
+            return CELIX_SUCCESS;
+        }
+        case CELIX_FILTER_OPERAND_AND:
+        case CELIX_FILTER_OPERAND_NOT:
+        case CELIX_FILTER_OPERAND_OR:
+        case CELIX_FILTER_OPERAND_PRESENT: {
+        }
+            /* no break */
+    }
+
+    if (status == CELIX_SUCCESS && out != NULL) {
+        *out = result;
+    }
+    return status;
 }
 
-celix_status_t filter_getString(filter_pt filter, const char **filterStr) {
+celix_status_t filter_getString(celix_filter_t * filter, const char 
**filterStr) {
        if (filter != NULL) {
                *filterStr = filter->filterStr;
        }
        return CELIX_SUCCESS;
 }
 
-celix_status_t filter_match_filter(filter_pt src, filter_pt dest, bool 
*result) {
-       char *srcStr = NULL;
-       char *destStr = NULL;
-       *result = false;
-
-       if (src) srcStr = src->filterStr;
-       if (dest) destStr = dest->filterStr;
+celix_status_t filter_match_filter(celix_filter_t *src, celix_filter_t *dest, 
bool *out) {
+    celix_status_t  status = CELIX_SUCCESS;
+       bool result = false;
+
+    if (src == dest) {
+        result = true; //NOTE. also means NULL filter are equal
+    } else if (src != NULL && dest != NULL && src->operand == dest->operand) {
+        if (src->operand == CELIX_FILTER_OPERAND_AND || src->operand == 
CELIX_FILTER_OPERAND_OR || src->operand == CELIX_FILTER_OPERAND_NOT) {
+            assert(src->children != NULL);
+            assert(dest->children != NULL);
+            int sizeSrc = arrayList_size(src->children);
+            int sizeDest = arrayList_size(dest->children);
+            if (sizeSrc == sizeDest) {
+                int i;
+                int k;
+                int sameCount = 0;
+                for (i =0; i < sizeSrc; ++i) {
+                    bool same = false;
+                    celix_filter_t *srcPart = arrayList_get(src->children, i);
+                    for (k = 0; k < sizeDest; ++k) {
+                        celix_filter_t *destPart = 
arrayList_get(dest->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 (src->attribute == NULL && dest->attribute == NULL) {
+                attrSame = true;
+            } else if (src->attribute != NULL && dest->attribute != NULL) {
+                attrSame = strncmp(src->attribute, dest->attribute, 1024 * 
1024) == 0;
+            }
+
+            if (src->value == NULL  && dest->value == NULL) {
+                valSame = true;
+            } else if (src->value != NULL && dest->value != NULL) {
+                valSame = strncmp(src->value, dest->value, 1024 * 1024) == 0;
+            }
+
+            result = attrSame && valSame;
+        }
+    }
 
-       if ((srcStr != NULL) && (destStr != NULL)) {
-               // TODO: should be done smarted, e.g. src="&(a=1)(b=2)" and 
dest="&(b=2)(a=1)" should result in true
-               *result = (strcmp(srcStr, destStr) == 0);
-       }
+    if (status == CELIX_SUCCESS && out != NULL) {
+        *out = result;
+    }
 
-       return CELIX_SUCCESS;
+       return status;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/f4cd9838/framework/src/filter_private.h
----------------------------------------------------------------------
diff --git a/framework/src/filter_private.h b/framework/src/filter_private.h
deleted file mode 100644
index d19de2d..0000000
--- a/framework/src/filter_private.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * filter_private.h
- *
- *  \date       Feb 13, 2013
- *  \author     <a href="mailto:d...@celix.apache.org";>Apache Celix Project 
Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-
-#ifndef FILTER_PRIVATE_H_
-#define FILTER_PRIVATE_H_
-
-#include "filter.h"
-#include "array_list.h"
-
-typedef enum operand
-{
-       EQUAL,
-       APPROX,
-       GREATER,
-    GREATEREQUAL,
-       LESS,
-       LESSEQUAL,
-       PRESENT,
-       SUBSTRING,
-       AND,
-       OR,
-       NOT,
-} OPERAND;
-
-struct filter {
-       OPERAND operand;
-       char * attribute;
-       void * value;
-       char *filterStr;
-};
-
-
-#endif /* FILTER_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/f4cd9838/utils/include/array_list.h
----------------------------------------------------------------------
diff --git a/utils/include/array_list.h b/utils/include/array_list.h
index 4f83a45..c816c3d 100644
--- a/utils/include/array_list.h
+++ b/utils/include/array_list.h
@@ -36,8 +36,10 @@ extern "C" {
 #endif
 
 typedef struct arrayList *array_list_pt;
+typedef struct arrayList array_list_t;
 
 typedef struct arrayListIterator *array_list_iterator_pt;
+typedef struct arrayListIterator array_list_iterator_t;
 
 typedef celix_status_t (*array_list_element_equals_pt)(const void *, const 
void *, bool *equals);
 

Reply via email to