From 085f6b64a32ff2447eedc60781d4a121ad716cdc Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Tue, 4 Mar 2008 01:10:56 +0100 Subject: [PATCH] Add find condition to logically combine two find conditions. --- demo/find.c | 6 +- libisofs/find.c | 138 ++++++++++++++++++++++++++++++++++++++++++++ libisofs/libisofs.h | 41 +++++++++++++ 3 files changed, 183 insertions(+), 2 deletions(-) diff --git a/demo/find.c b/demo/find.c index abae63d..00cccbc 100644 --- a/demo/find.c +++ b/demo/find.c @@ -16,9 +16,11 @@ print_dir(IsoDir *dir) { IsoDirIter *iter; IsoNode *node; - IsoFindCondition *cond; + IsoFindCondition *cond, *c1, *c2; - cond = iso_new_find_conditions_name("*a*"); + c1 = iso_new_find_conditions_name("*a*"); + c2 = iso_new_find_conditions_mode(S_IFREG); + cond = iso_new_find_conditions_and(c1, c2); iso_dir_find_children(dir, cond, &iter); while (iso_dir_iter_next(iter, &node) == 1) { printf(" %s\n", iso_node_get_name(node)); diff --git a/libisofs/find.c b/libisofs/find.c index fd0e9f6..0288113 100644 --- a/libisofs/find.c +++ b/libisofs/find.c @@ -477,3 +477,141 @@ IsoFindCondition *iso_new_find_conditions_ctime(time_t time, return cond; } +/*************** logical operations on conditions *****************/ + +struct logical_binary_conditions { + IsoFindCondition *a; + IsoFindCondition *b; +}; + +static +void cond_logical_binary_free(IsoFindCondition *cond) +{ + struct logical_binary_conditions *data; + data = cond->data; + data->a->free(data->a); + free(data->a); + data->b->free(data->b); + free(data->b); + free(cond->data); +} + +static +int cond_logical_and_matches(IsoFindCondition *cond, IsoNode *node) +{ + struct logical_binary_conditions *data = cond->data; + return data->a->matches(data->a, node) && data->b->matches(data->b, node); +} + +/** + * Create a new condition that check if the two given conditions are + * valid. + * + * @param a + * @param b + * IsoFindCondition to compare + * @result + * The created IsoFindCondition, NULL on error. + * + * @since 0.6.4 + */ +IsoFindCondition *iso_new_find_conditions_and(IsoFindCondition *a, + IsoFindCondition *b) +{ + IsoFindCondition *cond; + struct logical_binary_conditions *data; + cond = malloc(sizeof(IsoFindCondition)); + if (cond == NULL) { + return NULL; + } + data = malloc(sizeof(struct logical_binary_conditions)); + if (data == NULL) { + free(cond); + return NULL; + } + data->a = a; + data->b = b; + cond->data = data; + cond->free = cond_logical_binary_free; + cond->matches = cond_logical_and_matches; + return cond; +} + +static +int cond_logical_or_matches(IsoFindCondition *cond, IsoNode *node) +{ + struct logical_binary_conditions *data = cond->data; + return data->a->matches(data->a, node) || data->b->matches(data->b, node); +} + +/** + * Create a new condition that check if at least one the two given conditions + * is valid. + * + * @param a + * @param b + * IsoFindCondition to compare + * @result + * The created IsoFindCondition, NULL on error. + * + * @since 0.6.4 + */ +IsoFindCondition *iso_new_find_conditions_or(IsoFindCondition *a, + IsoFindCondition *b) +{ + IsoFindCondition *cond; + struct logical_binary_conditions *data; + cond = malloc(sizeof(IsoFindCondition)); + if (cond == NULL) { + return NULL; + } + data = malloc(sizeof(struct logical_binary_conditions)); + if (data == NULL) { + free(cond); + return NULL; + } + data->a = a; + data->b = b; + cond->data = data; + cond->free = cond_logical_binary_free; + cond->matches = cond_logical_or_matches; + return cond; +} + +static +void cond_not_free(IsoFindCondition *cond) +{ + IsoFindCondition *negate = cond->data; + negate->free(negate); + free(negate); +} + +static +int cond_not_matches(IsoFindCondition *cond, IsoNode *node) +{ + IsoFindCondition *negate = cond->data; + return !(negate->matches(negate, node)); +} + +/** + * Create a new condition that check if the given conditions is false. + * + * @param negate + * @result + * The created IsoFindCondition, NULL on error. + * + * @since 0.6.4 + */ +IsoFindCondition *iso_new_find_conditions_not(IsoFindCondition *negate) +{ + IsoFindCondition *cond; + cond = malloc(sizeof(IsoFindCondition)); + if (cond == NULL) { + return NULL; + } + cond->data = negate; + cond->free = cond_not_free; + cond->matches = cond_not_matches; + return cond; +} + diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 6eb29fa..a48666d 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -2289,6 +2289,47 @@ IsoFindCondition *iso_new_find_conditions_mtime(time_t time, IsoFindCondition *iso_new_find_conditions_ctime(time_t time, enum iso_find_comparisons comparison); +/** + * Create a new condition that check if the two given conditions are + * valid. + * + * @param a + * @param b + * IsoFindCondition to compare + * @result + * The created IsoFindCondition, NULL on error. + * + * @since 0.6.4 + */ +IsoFindCondition *iso_new_find_conditions_and(IsoFindCondition *a, + IsoFindCondition *b); + +/** + * Create a new condition that check if at least one the two given conditions + * is valid. + * + * @param a + * @param b + * IsoFindCondition to compare + * @result + * The created IsoFindCondition, NULL on error. + * + * @since 0.6.4 + */ +IsoFindCondition *iso_new_find_conditions_or(IsoFindCondition *a, + IsoFindCondition *b); + +/** + * Create a new condition that check if the given conditions is false. + * + * @param negate + * @result + * The created IsoFindCondition, NULL on error. + * + * @since 0.6.4 + */ +IsoFindCondition *iso_new_find_conditions_not(IsoFindCondition *negate); + /** * Find all directory children that match the given condition. *