diff options
Diffstat (limited to 'common/collection/collection_cmp.c')
-rw-r--r-- | common/collection/collection_cmp.c | 436 |
1 files changed, 0 insertions, 436 deletions
diff --git a/common/collection/collection_cmp.c b/common/collection/collection_cmp.c deleted file mode 100644 index c1f9017d..00000000 --- a/common/collection/collection_cmp.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - COLLECTION LIBRARY - - Function to compare items. - - Copyright (C) Dmitri Pal <dpal@redhat.com> 2009 - - Collection Library is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Collection Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with Collection Library. If not, see <http://www.gnu.org/licenses/>. -*/ - -#define _GNU_SOURCE -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <ctype.h> -#include <time.h> -#include "config.h" -#include "trace.h" - -/* The collection should use the real structures */ -#include "collection_priv.h" -#include "collection.h" - -#define NONZERO 1 -#define PROP_MSK 0x000000007 - - -#define TYPED_MATCH(type) \ - do { \ - if (*((type *)(first->data)) != *((type *)(second->data))) { \ - result = NONZERO; \ - if ((out_flags) && \ - (*((type *)(first->data)) < *((type *)(second->data)))) { \ - *out_flags |= COL_CMPOUT_DATA; \ - } \ - } \ - } while(0) - - -/* Function to compare two items */ -int col_compare_items(struct collection_item *first, - struct collection_item *second, - unsigned in_flags, - unsigned *out_flags) -{ - int result = 0; - unsigned mode; - int cmpres = 0; - char *substr; - - TRACE_FLOW_STRING("col_compare_items", "Entry."); - - /* If any of the arguments is NULL return - * that they are different. - */ - if ((first == NULL) || (second == NULL)) { - TRACE_INFO_STRING("One of the items is NULL", ""); - return NONZERO; - } - - /* Check if we are told to compare something */ - if (!in_flags) { - TRACE_INFO_NUMBER("No flags specified", in_flags); - return NONZERO; - } - - if (out_flags) *out_flags = 0; - - /* Start comparison */ - mode = in_flags & PROP_MSK; - if (mode > 0 ) { - /* We are told to compare the properties */ - switch(mode) { - - case COL_CMPIN_PROP_EQU: /* looking for exact match */ - - /* Compare hashes and lengths first */ - if ((first->phash == first->phash) && - (first->property_len == second->property_len)) { - /* Collections are case insensitive, sorry... */ - cmpres = strncasecmp(first->property, - second->property, - second->property_len); - if (cmpres != 0) { - result = NONZERO; - if (cmpres < 0) { - /* Second is greater */ - if (out_flags) *out_flags |= COL_CMPOUT_PROP_STR; - } - } - } - else { - result = NONZERO; - /* They are different so check if we need to compare? */ - if (out_flags) { - cmpres = strncasecmp(first->property, - second->property, - second->property_len); - if (cmpres < 0) { - /* Second is greater */ - *out_flags |= COL_CMPOUT_PROP_STR; - } - } - } - break; - - case COL_CMPIN_PROP_BEG: /* looking for beginning */ - - /* Compare lengths first */ - if (first->property_len >= second->property_len) { - cmpres = strncasecmp(first->property, - second->property, - second->property_len); - if (cmpres == 0) { - /* Check we need to validate for dot */ - if (in_flags & COL_CMPIN_PROP_DOT) { - if ((first->property[second->property_len] != '\0') && - (first->property[second->property_len] != '.')) { - result = NONZERO; - } - } - } - else result = NONZERO; - } - else result = NONZERO; - break; - - case COL_CMPIN_PROP_MID: /* looking for middle */ - - /* Compare lengths first */ - if (first->property_len >= second->property_len) { - substr = strcasestr(first->property, second->property); - if (substr != NULL) { - /* Check we need to validate for dot */ - if (in_flags & COL_CMPIN_PROP_DOT) { - /* Check if we have a dot before or after */ - if (((substr != first->property) && - (first->property[(substr - first->property) - 1] != '.')) || - ((substr[second->property_len] != '\0') && - (substr[second->property_len] != '.'))) { - result = NONZERO; - } - } - } - else result = NONZERO; - } - else result = NONZERO; - break; - - case COL_CMPIN_PROP_END: /* looking for end */ - - /* Compare lengths first */ - if (first->property_len >= second->property_len) { - substr = first->property + (first->property_len - second->property_len); - cmpres = strncasecmp(substr, - second->property, - second->property_len); - if (cmpres == 0) { - /* Check we need to validate for dot */ - if (in_flags & COL_CMPIN_PROP_DOT) { - if ((substr != first->property) && - (first->property[(substr - first->property) - 1] != '.')) { - result = NONZERO; - } - } - } - else result = NONZERO; - } - else result = NONZERO; - break; - - default: result = NONZERO; - break; - } - } - - /* Check if we are told to compare property lengths */ - if (in_flags & COL_CMPIN_PROP_LEN) { - if (first->property_len != second->property_len) { - result = NONZERO; - /* Do we need to tell who is greater? */ - if ((out_flags) && (first->property_len < second->property_len)) { - *out_flags |= COL_CMPOUT_PROP_LEN; - } - } - } - - /* Check if we are told to compare types */ - if (in_flags & COL_CMPIN_TYPE) { - if (first->type != second->type) result = NONZERO; - } - - /* Check if we need to compare data length */ - if (in_flags & COL_CMPIN_DATA_LEN) { - if (first->length != second->length) { - result = NONZERO; - /* Do we need to tell who is greater? */ - if ((out_flags) && (first->length < second->length)) { - *out_flags |= COL_CMPOUT_DATA_LEN; - } - } - } - - /* Check if we need to compare data */ - if (in_flags & COL_CMPIN_DATA) { - if (first->type == second->type) { - switch(first->type) { - - case COL_TYPE_STRING: - if (first->length == second->length) { - cmpres = strncmp((const char *)first->data, - (const char *)second->data, - first->length); - - if (cmpres != 0) { - result = NONZERO; - if (cmpres < 0) { - /* Second is greater */ - if (out_flags) *out_flags |= COL_CMPOUT_DATA; - } - } - - } - else result = NONZERO; - break; - - case COL_TYPE_BINARY: - if (first->length == second->length) { - cmpres = memcmp(first->data, - second->data, - first->length); - - if (cmpres != 0) result = NONZERO; - } - else result = NONZERO; - break; - - case COL_TYPE_INTEGER: - /* Use macro to match data */ - TYPED_MATCH(int); - break; - - case COL_TYPE_UNSIGNED: - /* Use macro to match data */ - TYPED_MATCH(unsigned); - break; - - case COL_TYPE_LONG: - /* Use macro to match data */ - TYPED_MATCH(long); - break; - - case COL_TYPE_ULONG: - /* Use macro to match data */ - TYPED_MATCH(unsigned long); - break; - - case COL_TYPE_DOUBLE: - /* Use macro to match data */ - TYPED_MATCH(double); - break; - - case COL_TYPE_BOOL: - /* Use macro to match data */ - TYPED_MATCH(unsigned char); - break; - - /* These are never same */ - case COL_TYPE_COLLECTION: - case COL_TYPE_COLLECTIONREF: - case COL_TYPE_END: - default: - result = NONZERO; - break; - } - - } - else result = NONZERO; - } - - TRACE_FLOW_NUMBER("col_compare_items. Exit. Returning:", result); - return result; -} - -/* Sort collection */ -int col_sort_collection(struct collection_item *col, - unsigned cmp_flags, - unsigned sort_flags) -{ - int error = EOK; - - struct collection_item *current; - struct collection_header *header; - struct collection_item **array; - struct collection_item *temp_item; - struct collection_item *other; - size_t size; - int ind, last; - int i, j; - int res; - unsigned out_flags; - - TRACE_FLOW_STRING("col_sort_collection", "Entry."); - - TRACE_INFO_NUMBER("Comparison flags:", cmp_flags); - TRACE_INFO_NUMBER("Sort flags:", sort_flags); - - if ((col == NULL) || (col->type != COL_TYPE_COLLECTION)) { - TRACE_ERROR_STRING("Collecton must not ne NULL", ""); - return EINVAL; - } - - /* This will be a fast and simple implementation for now */ - header = (struct collection_header *)(col->data); - - if ((sort_flags & COL_SORT_SUB) && - (sort_flags & COL_SORT_MYSUB) && - (header->reference_count > 1)) { - TRACE_FLOW_STRING("col_sort_collection", "Exit."); - return error; - } - - size = sizeof(struct collection_item *) * (header->count - 1); - array = (struct collection_item **)malloc(size); - if (array == NULL) { - TRACE_ERROR_NUMBER("Failed to allocate memory", ENOMEM); - return ENOMEM; - } - - /* Fill array */ - current = col->next; - ind = 0; - while (current != NULL) { - TRACE_INFO_STRING("Item:", current->property); - array[ind] = current; - if ((sort_flags & COL_SORT_SUB) && - (array[ind]->type == COL_TYPE_COLLECTIONREF)) { - /* If we found a subcollection and we need to sort it - * then sort it. - */ - other = *((struct collection_item **)(array[ind]->data)); - error = col_sort_collection(other, cmp_flags, sort_flags); - if (error) { - TRACE_ERROR_NUMBER("Subcollection sort failed", error); - free(array); - return error; - } - } - ind++; - current = current->next; - } - - last = ind - 1; - - for (i = 0; i < last; i++) { - - TRACE_INFO_STRING("Arg1:", array[i]->property); - TRACE_INFO_STRING("Arg2:", array[i + 1]->property); - - res = col_compare_items(array[i], - array[i + 1], - cmp_flags, - &out_flags); - - TRACE_INFO_STRING("Result:", ((res == 0) ? "same" : "different")); - TRACE_INFO_NUMBER("Out flags", out_flags); - - /* If they are not same and second is not greater - * in any way then we need to swap them */ - if ((res != 0) && (out_flags == 0)) { - /* Swap */ - TRACE_INFO_STRING("Swapping:", ""); - TRACE_INFO_STRING("Item:", array[i]->property); - TRACE_INFO_STRING("Item:", array[i + 1]->property); - - temp_item = array[i]; - array[i] = array[i + 1]; - array[i + 1] = temp_item; - - /* But we need to go up bubbling this item - */ - j = i; - while (j > 0) { - res = col_compare_items(array[j - 1], - array[j], - cmp_flags, - &out_flags); - /* If they are not same and second is not greater - * in any way then we need to swap them */ - if ((res != 0) && (out_flags == 0)) { - /* Swap */ - temp_item = array[j - 1]; - array[j - 1] = array[j]; - array[j] = temp_item; - } - else break; - j--; - } - } - } - - /* Build the chain back */ - if (sort_flags & COL_SORT_DESC) { - col->next = array[last]; - for (i = last; i > 0 ; i--) { - array[i]->next = array[i - 1]; - } - array[0]->next = NULL; - header->last = array[0]; - } - else { - col->next = array[0]; - for (i = 0; i < last ; i++) { - array[i]->next = array[i + 1]; - } - array[last]->next = NULL; - header->last = array[last]; - } - - free(array); - - TRACE_FLOW_STRING("col_sort_collection", "Exit."); - return error; - -} |