From 665170ce6e77a88f8642a44f4e9ff4d68d2475ee Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 17 Jun 2006 19:23:11 +0000 Subject: [PATCH 001/250] Change set iteration to use iterator objects rather than foreach with callback functions. --- src/set.c | 267 ++++++++++++++++++++++++++++++++++-------------------- src/set.h | 66 ++++++++++---- 2 files changed, 221 insertions(+), 112 deletions(-) diff --git a/src/set.c b/src/set.c index 37bdbdb..26ce978 100644 --- a/src/set.c +++ b/src/set.c @@ -56,6 +56,13 @@ struct _Set { SetFreeFunc free_func; }; +struct _SetIterator { + Set *set; + SetEntry **current_entry; + SetEntry **next_entry; + int next_chain; +}; + /* Prime numbers on an escalating exponential scale, used for the table * size. Each value is approximately 1.5 * the previous value, so the * table size increases by 50% with each enlargement */ @@ -345,29 +352,6 @@ int set_query(Set *set, void *data) return 0; } -void set_foreach(Set *set, SetIterator callback, void *user_data) -{ - SetEntry *rover; - int i; - - /* Iterate over all chains and all values in the chains */ - - for (i=0; itable_size; ++i) { - rover = set->table[i]; - - while (rover != NULL) { - - /* Invoke callback for this data */ - - callback(rover->data, user_data); - - /* Advance to the next entry */ - - rover = rover->next; - } - } -} - int set_num_entries(Set *set) { return set->entries; @@ -407,120 +391,211 @@ void **set_to_array(Set *set) return array; } -struct set_union_data { - Set *new_set; - SetCopyFunc copy_func; -}; - -static void set_union_foreach1(void *value, void *user_data) +Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func) { - struct set_union_data *params; + SetIterator *iterator; + Set *new_set; + void *value; void *copied_value; - params = (struct set_union_data *) user_data; - - /* Copy the value into the new set, copying if necessary */ - - if (params->copy_func != NULL) { - copied_value = params->copy_func(value); - } else { - copied_value = value; - } - - set_insert(params->new_set, copied_value); -} + new_set = set_new(set1->hash_func, set1->equal_func); -static void set_union_foreach2(void *value, void *user_data) -{ - struct set_union_data *params; - void *copied_value; + /* Add all values from the first set */ + + iterator = set_iterate(set1); - params = (struct set_union_data *) user_data; + while (set_iterator_has_more(iterator)) { - /* Has this value been put into the new set yet? If not, add it. */ + /* Read the next value */ - if (set_query(params->new_set, value) == 0) { + value = set_iterator_next(iterator); /* Copy the value into the new set, copying if necessary */ - if (params->copy_func != NULL) { - copied_value = params->copy_func(value); + if (copy_func != NULL) { + copied_value = copy_func(value); } else { copied_value = value; } - set_insert(params->new_set, copied_value); + set_insert(new_set, copied_value); } -} - - -Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func) -{ - struct set_union_data user_data; - Set *new_set; - - new_set = set_new(set1->hash_func, set1->equal_func); - - user_data.new_set = new_set; - user_data.copy_func = copy_func; - /* Add all values from the first set */ + set_iterator_free(iterator); - set_foreach(set1, set_union_foreach1, &user_data); - /* Add all values from the second set */ - set_foreach(set2, set_union_foreach2, &user_data); + iterator = set_iterate(set2); - return new_set; -} + while (set_iterator_has_more(iterator)) { -struct set_intersection_data { - Set *new_set; - Set *set2; - SetCopyFunc copy_func; -}; + /* Read the next value */ -static void set_intersection_foreach(void *value, void *user_data) -{ - struct set_intersection_data *params; - void *copied_value; + value = set_iterator_next(iterator); - params = (struct set_intersection_data *) user_data; + /* Has this value been put into the new set already? + * If so, do not insert this again */ - /* Is this value in set 2 as well? If so, it should be in the - * new set. */ + if (set_query(new_set, value) == 0) { - if (set_query(params->set2, value) != 0) { + /* Insert the value into the new set, copying + * if necessary */ - /* Copy the value first before inserting, if necessary */ + if (copy_func != NULL) { + copied_value = copy_func(value); + } else { + copied_value = value; + } - if (params->copy_func != NULL) { - copied_value = params->copy_func(value); - } else { - copied_value = value; + set_insert(new_set, copied_value); } - - set_insert(params->new_set, copied_value); } + + set_iterator_free(iterator); + + return new_set; } Set *set_intersection(Set *set1, Set *set2, SetCopyFunc copy_func) { - struct set_intersection_data user_data; Set *new_set; + SetIterator *iterator; + void *value; + void *copied_value; new_set = set_new(set1->hash_func, set2->equal_func); /* Iterate over all values in set 1. */ - user_data.new_set = new_set; - user_data.set2 = set2; - user_data.copy_func = copy_func; + iterator = set_iterate(set1); + + while (set_iterator_has_more(iterator)) { + + /* Get the next value */ + + value = set_iterator_next(iterator); + + /* Is this value in set 2 as well? If so, it should be + * in the new set. */ + + if (set_query(set2, value) != 0) { + + /* Copy the value first before inserting, + * if necessary */ + + if (copy_func != NULL) { + copied_value = copy_func(value); + } else { + copied_value = value; + } + + set_insert(new_set, copied_value); + } + } + + set_iterator_free(iterator); - set_foreach(set1, set_intersection_foreach, &user_data); - return new_set; } +SetIterator *set_iterate(Set *set) +{ + SetIterator *iter; + int chain; + + /* Create a new iterator object */ + + iter = malloc(sizeof(SetIterator)); + + iter->set = set; + iter->current_entry = NULL; + iter->next_entry = NULL; + + /* Find the first entry */ + + for (chain = 0; chain < set->table_size; ++chain) { + + /* There is a value at the start of this chain */ + + if (set->table[chain] != NULL) { + iter->next_entry = &set->table[chain]; + break; + } + } + + iter->next_chain = chain; + + return iter; +} + +void *set_iterator_next(SetIterator *iterator) +{ + Set *set; + void *result; + int chain; + + set = iterator->set; + + /* No more entries? */ + + if (iterator->next_entry == NULL) { + return NULL; + } + /* We have the result immediately */ + + iterator->current_entry = iterator->next_entry; + result = (*iterator->current_entry)->data; + + /* Advance next_entry to the next SetEntry in the Set. */ + + if ((*iterator->current_entry)->next != NULL) { + + /* Use the next value in this chain */ + + iterator->next_entry = &((*iterator->current_entry)->next); + + } else { + + /* Default value if no valid chain is found */ + + iterator->next_entry = NULL; + + /* No more entries in this chain. Search the next chain */ + + chain = iterator->next_chain + 1; + + while (chain < set->table_size) { + + /* Is there a chain at this table entry? */ + + if (set->table[chain] != NULL) { + + /* Valid chain found! */ + + iterator->next_entry = &set->table[chain]; + + break; + } + + /* Keep searching until we find an empty chain */ + + ++chain; + } + + iterator->next_chain = chain; + } + + return result; +} + +int set_iterator_has_more(SetIterator *iterator) +{ + return iterator->next_entry != NULL; +} + +void set_iterator_free(SetIterator *iterator) +{ + free(iterator); +} + diff --git a/src/set.h b/src/set.h index deac61c..37cd07f 100644 --- a/src/set.h +++ b/src/set.h @@ -71,6 +71,14 @@ extern "C" { typedef struct _Set Set; +/** + * An object used to iterate over a set. + * + * @see set_iterate + */ + +typedef struct _SetIterator SetIterator; + /** * Hash function. Generates a hash key for data to be stored in a set. */ @@ -91,12 +99,6 @@ typedef int (*SetEqualFunc)(void *data1, void *data2); typedef void *(*SetCopyFunc)(void *data); -/** - * Set iterator. Callback function used to iterate over values in a set. - */ - -typedef void (*SetIterator)(void *data, void *user_data); - /** * Function used to free values stored in a set. See * @ref set_register_free_function. @@ -168,16 +170,6 @@ int set_remove(Set *set, void *data); int set_query(Set *set, void *data); -/** - * Iterate over all values in a set. - * - * @param set The set. - * @param callback Callback function to be invoked for each value. - * @param user_data Extra data to be passed to the callback function. - */ - -void set_foreach(Set *set, SetIterator callback, void *user_data); - /** * Retrieve the number of entries in a set * @@ -229,6 +221,48 @@ Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func); Set *set_intersection(Set *set1, Set *set2, SetCopyFunc copy_func); +/** + * Create an iterator to iterate over the values in a set. + * It should be noted that a set iterator must be freed once iterating + * has been completed. This should be done using @ref set_iterator_free. + * + * @param set The set to iterate over. + * @return A new iterator object. + */ + +SetIterator *set_iterate(Set *set); + +/** + * Determine if there are more values in the set to iterate over. + * It should be noted that a set iterator is not freed when iterating + * has finished. This should be done using @ref set_iterator_free. + * + * @param iterator The set iterator object. + * @return Zero if there are no more values in the set + * to iterate over, non-zero if there are more + * values to be read. + */ + +int set_iterator_has_more(SetIterator *iterator); + +/** + * Using a set iterator, retrieve the next value from the set. + * + * @param iterator The set iterator. + * @return The next value from the set, or NULL if no + * more values are available. + */ + +void *set_iterator_next(SetIterator *iterator); + +/** + * Free back a set iterator object. + * + * @param iterator The iterator to free. + */ + +void set_iterator_free(SetIterator *iterator); + #ifdef __cplusplus } #endif From 468f831e9795a31a9148ba6e1ec53bad22d1bcbb Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 19 Jun 2006 17:11:03 +0000 Subject: [PATCH 002/250] Convert hash table structure to use iterator objects instead of foreach with callback functions. --- src/hashtable.c | 121 ++++++++++++++++++++++++++---------------- src/hashtable.h | 85 +++++++++++++---------------- test/test-hashtable.c | 108 ++++++++++++++++++------------------- 3 files changed, 165 insertions(+), 149 deletions(-) diff --git a/src/hashtable.c b/src/hashtable.c index f1ee484..478ba58 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -59,6 +59,13 @@ struct _HashTable { int prime_index; }; +struct _HashTableIterator { + HashTable *hashtable; + HashTableEntry **current_entry; + HashTableEntry **next_entry; + int next_chain; +}; + /* Prime numbers on an escalating exponential scale, used for the table * size. Each value is approximately 1.5 * the previous value, so the * table size increases by 50% with each enlargement */ @@ -120,7 +127,7 @@ static void hash_table_free_entry(HashTable *hashtable, HashTableEntry *entry) } HashTable *hash_table_new(HashTableHashFunc hash_func, - HashTableEqualFunc equal_func) + HashTableEqualFunc equal_func) { HashTable *hashtable; @@ -377,74 +384,98 @@ int hash_table_num_entries(HashTable *hashtable) return hashtable->entries; } -void hash_table_foreach(HashTable *hashtable, HashTableIterator iterator, - void *user_data) +HashTableIterator *hash_table_iterate(HashTable *hashtable) { - int i; - HashTableEntry *rover; - - /* Iterate over all entries in all chains */ - - for (i=0; itable_size; ++i) { - rover = hashtable->table[i]; + HashTableIterator *iterator; + int chain; + + iterator = (HashTableIterator *) malloc(sizeof(HashTableIterator)); + iterator->hashtable = hashtable; + iterator->current_entry = NULL; - while (rover != NULL) { - iterator(rover->key, rover->value, user_data); - rover = rover->next; + /* Default value of next if no entries are found. */ + + iterator->next_entry = NULL; + + /* Find the first entry */ + + for (chain=0; chaintable_size; ++chain) { + + if (hashtable->table[chain] != NULL) { + iterator->next_entry = &hashtable->table[chain]; + iterator->next_chain = chain; + break; } } + + return iterator; } -int hash_table_foreach_remove(HashTable *hashtable, - HashTableRemoveIterator iterator, - void *user_data) +int hash_table_iterator_has_more(HashTableIterator *iterator) { - int i; - int removed_entries; - int remove; - HashTableEntry **rover; - HashTableEntry *entry; - - /* Iterate over all entries in all chains */ + return iterator->next_entry != NULL; +} - removed_entries = 0; +void *hash_table_iterator_next(HashTableIterator *iterator) +{ + HashTable *hashtable; + void *result; + int chain; - for (i=0; itable_size; ++i) { - rover = &(hashtable->table[i]); + hashtable = iterator->hashtable; - while (*rover != NULL) { - - entry = *rover; + /* No more entries? */ + + if (iterator->next_entry == NULL) { + return NULL; + } + + /* Result is immediately available */ - remove = iterator(entry->key, entry->value, user_data); + iterator->current_entry = iterator->next_entry; + result = (*iterator->current_entry)->key; - /* Remove this entry? */ + /* Find the next entry */ - if (remove) { + if ((*iterator->current_entry)->next != NULL) { + + /* Next entry in current chain */ - /* Unlink this entry from the chain */ + iterator->next_entry = &(*iterator->current_entry)->next; + + } else { + + /* None left in this chain, so advance to the next chain */ - *rover = entry->next; - --hashtable->entries; + chain = iterator->next_chain + 1; - /* Destroy the entry structure */ + /* Default value if no next chain found */ + + iterator->next_entry = NULL; - hash_table_free_entry(hashtable, entry); + while (chain < hashtable->table_size) { - /* Keep count of the number removed */ + /* Is there anything in this chain? */ - ++removed_entries; - - } else { + if (hashtable->table[chain] != NULL) { + iterator->next_entry + = &hashtable->table[chain]; + break; + } - /* Advance to the next entry in the chain */ + /* Try the next chain */ - rover = &((*rover)->next); - } + ++chain; } + + iterator->next_chain = chain; } - return removed_entries; + return result; } +void hash_table_iterator_free(HashTableIterator *iterator) +{ + free(iterator); +} diff --git a/src/hashtable.h b/src/hashtable.h index 9f4b877..ec2d6b6 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -65,6 +65,12 @@ extern "C" { typedef struct _HashTable HashTable; +/** + * Structure used to iterate over a hash table. + */ + +typedef struct _HashTableIterator HashTableIterator; + /** * Hash function used to generate hash values for keys used in a hash * table. @@ -91,36 +97,6 @@ typedef int (*HashTableEqualFunc)(void *data1, void *data2); typedef void (*HashTableFreeFunc)(void *data); -/** - * Type of function used as a callback when iterating over data. - * See @ref hash_table_foreach. - * - * @param key The key to the current element being iterated over. - * @param value The value of the current element being iterated over. - * @param user_data Extra data passed to the @ref hash_table_foreach - * function. - */ - -typedef void (*HashTableIterator)(void *key, void *value, void *user_data); - -/** - * Type of function used as a callback when iterating over a hash table, - * selectively removing entries. - * See @ref hash_table_foreach_remove. - * - * @param key The key to the current element being iterated over. - * @param value The value of the current element being iterated over. - * @param user_data Extra data passed to the @ref hash_table_foreach - * function. - * @return Non-zero (true) if the entry should be removed - * from the hash table. Zero (false) if the entry - * should not be removed from the hash table. - */ - -typedef int (*HashTableRemoveIterator)(void *key, - void *value, - void *user_data); - /** * Create a new hash table. * @@ -198,32 +174,47 @@ int hash_table_remove(HashTable *hashtable, void *key); int hash_table_num_entries(HashTable *hashtable); /** - * Iterate over all key-value pairs in a hash table. + * Create a new @ref HashTableIterator to iterate over a hash table. + * Note: iterators should be freed back with + * @ref hash_table_iterator_free once iterating has completed. * * @param hashtable The hash table. - * @param iterator Callback function to invoke for each element. - * @param user_data Extra data to pass to the iterator function - * as context. + * @return A pointer to a new @ref HashTableIterator + * to iterate over the hash table. */ -void hash_table_foreach(HashTable *hashtable, HashTableIterator iterator, - void *user_data); +HashTableIterator *hash_table_iterate(HashTable *hashtable); /** - * Iterate over all key-value pairs in a hash table, selectively - * removing entries. + * Determine if there are more keys in the hash table to iterate + * over. * - * @param hashtable The hash table. - * @param iterator Callback function to invoke for each element. - * @param user_data Extra data to pass to the iterator function - * as context. - * @return The total number of entries removed from - * the hash table. + * @param iterator The hash table iterator. + * @return Zero if there are no more values to iterate + * over, non-zero if there are more values to + * iterate over. + */ + +int hash_table_iterator_has_more(HashTableIterator *iterator); + +/** + * Using a hash table iterator, retrieve the next key. + * + * @param iterator The hash table iterator. + * @return The next key from the hash table, or NULL + * if there are no more keys to iterate over. + */ + +void *hash_table_iterator_next(HashTableIterator *iterator); + +/** + * Free back a hash table iterator object. This must be done once + * iterating has completed. + * + * @param iterator The hash table iterator. */ -int hash_table_foreach_remove(HashTable *hashtable, - HashTableRemoveIterator iterator, - void *user_data); +void hash_table_iterator_free(HashTableIterator *iterator); #ifdef __cplusplus } diff --git a/test/test-hashtable.c b/test/test-hashtable.c index 4052c5e..750828f 100644 --- a/test/test-hashtable.c +++ b/test/test-hashtable.c @@ -165,60 +165,51 @@ void test_hash_table_remove(void) assert(hash_table_num_entries(hashtable) == 9999); } -int hash_table_foreach_count; - -void hash_table_foreach_callback(void *key, void *value, void *user_data) -{ - ++hash_table_foreach_count; -} - -void test_hash_table_foreach(void) +void test_hash_table_iterating(void) { HashTable *hashtable; + HashTableIterator *iterator; + int count; hashtable = generate_hashtable(); /* Iterate over all values in the table */ - hash_table_foreach_count = 0; + count = 0; - hash_table_foreach(hashtable, hash_table_foreach_callback, NULL); + iterator = hash_table_iterate(hashtable); - assert(hash_table_foreach_count == 10000); + while (hash_table_iterator_has_more(iterator)) { + hash_table_iterator_next(iterator); + + ++count; + } + + hash_table_iterator_free(iterator); + + assert(count == 10000); /* Test iterating over an empty table */ hashtable = hash_table_new(int_hash, int_equal); - hash_table_foreach_count = 0; + iterator = hash_table_iterate(hashtable); - hash_table_foreach(hashtable, hash_table_foreach_callback, NULL); + assert(hash_table_iterator_has_more(iterator) == 0); - assert(hash_table_foreach_count == 0); + hash_table_iterator_free(iterator); } -int hash_table_foreach_remove_count; -int hash_table_foreach_remove_removed; +/* Demonstrates the ability to iteratively remove objects from + * a hash table: ie. removing the current key being iterated over + * does not break the iterator. */ -int hash_table_foreach_remove_callback(void *key, void *value, void *user_data) -{ - int *number = (int *) key; - - ++hash_table_foreach_remove_count; - - /* Remove every hundredth entry */ - - if (*number % 100 == 0) { - ++hash_table_foreach_remove_removed; - return 1; - } else { - return 0; - } -} - -void test_hash_table_foreach_remove(void) +void test_hash_table_iterating_remove(void) { HashTable *hashtable; + HashTableIterator *iterator; + int *val; + int count; int removed; int i; @@ -226,15 +217,33 @@ void test_hash_table_foreach_remove(void) /* Iterate over all values in the table */ - hash_table_foreach_remove_count = 0; - hash_table_foreach_remove_removed = 0; + count = 0; + removed = 0; + + iterator = hash_table_iterate(hashtable); - removed = hash_table_foreach_remove(hashtable, - hash_table_foreach_remove_callback, - NULL); + while (hash_table_iterator_has_more(iterator)) { + + /* Read the next value */ + + val = (int *) hash_table_iterator_next(iterator); - assert(hash_table_foreach_remove_removed == removed); - assert(hash_table_foreach_remove_count == 10000); + /* Remove every hundredth entry */ + + if (*val % 100 == 0) { + hash_table_remove(hashtable, val); + ++removed; + } + + ++count; + } + + hash_table_iterator_free(iterator); + + /* Check counts */ + + assert(removed == removed); + assert(count == 10000); assert(hash_table_num_entries(hashtable) == 10000 - removed); @@ -247,21 +256,6 @@ void test_hash_table_foreach_remove(void) assert(hash_table_lookup(hashtable, &i) != NULL); } } - - /* Test iterating over an empty table */ - - hashtable = hash_table_new(int_hash, int_equal); - - hash_table_foreach_remove_count = 0; - hash_table_foreach_remove_removed = 0; - - removed = hash_table_foreach_remove(hashtable, - hash_table_foreach_remove_callback, - NULL); - - assert(hash_table_foreach_remove_removed == removed); - assert(hash_table_foreach_remove_removed == 0); - assert(hash_table_foreach_remove_count == 0); } int main(int argc, char *argv[]) @@ -270,8 +264,8 @@ int main(int argc, char *argv[]) test_hash_table_free(); test_hash_table_insert_lookup(); test_hash_table_remove(); - test_hash_table_foreach(); - test_hash_table_foreach_remove(); + test_hash_table_iterating(); + test_hash_table_iterating_remove(); return 0; } From d92ade74171b7155207c67a0569db330a2ed0e72 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 19 Jun 2006 17:18:14 +0000 Subject: [PATCH 003/250] Rename functions with _iterator_ to _iter_ for shorter names. --- src/hashtable.c | 6 +++--- src/hashtable.h | 8 ++++---- src/set.c | 24 ++++++++++++------------ src/set.h | 10 +++++----- test/test-hashtable.c | 16 ++++++++-------- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/hashtable.c b/src/hashtable.c index 478ba58..abb8097 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -411,12 +411,12 @@ HashTableIterator *hash_table_iterate(HashTable *hashtable) return iterator; } -int hash_table_iterator_has_more(HashTableIterator *iterator) +int hash_table_iter_has_more(HashTableIterator *iterator) { return iterator->next_entry != NULL; } -void *hash_table_iterator_next(HashTableIterator *iterator) +void *hash_table_iter_next(HashTableIterator *iterator) { HashTable *hashtable; void *result; @@ -474,7 +474,7 @@ void *hash_table_iterator_next(HashTableIterator *iterator) return result; } -void hash_table_iterator_free(HashTableIterator *iterator) +void hash_table_iter_free(HashTableIterator *iterator) { free(iterator); } diff --git a/src/hashtable.h b/src/hashtable.h index ec2d6b6..04ffdd4 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -176,7 +176,7 @@ int hash_table_num_entries(HashTable *hashtable); /** * Create a new @ref HashTableIterator to iterate over a hash table. * Note: iterators should be freed back with - * @ref hash_table_iterator_free once iterating has completed. + * @ref hash_table_iter_free once iterating has completed. * * @param hashtable The hash table. * @return A pointer to a new @ref HashTableIterator @@ -195,7 +195,7 @@ HashTableIterator *hash_table_iterate(HashTable *hashtable); * iterate over. */ -int hash_table_iterator_has_more(HashTableIterator *iterator); +int hash_table_iter_has_more(HashTableIterator *iterator); /** * Using a hash table iterator, retrieve the next key. @@ -205,7 +205,7 @@ int hash_table_iterator_has_more(HashTableIterator *iterator); * if there are no more keys to iterate over. */ -void *hash_table_iterator_next(HashTableIterator *iterator); +void *hash_table_iter_next(HashTableIterator *iterator); /** * Free back a hash table iterator object. This must be done once @@ -214,7 +214,7 @@ void *hash_table_iterator_next(HashTableIterator *iterator); * @param iterator The hash table iterator. */ -void hash_table_iterator_free(HashTableIterator *iterator); +void hash_table_iter_free(HashTableIterator *iterator); #ifdef __cplusplus } diff --git a/src/set.c b/src/set.c index 26ce978..c0f3d36 100644 --- a/src/set.c +++ b/src/set.c @@ -404,11 +404,11 @@ Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func) iterator = set_iterate(set1); - while (set_iterator_has_more(iterator)) { + while (set_iter_has_more(iterator)) { /* Read the next value */ - value = set_iterator_next(iterator); + value = set_iter_next(iterator); /* Copy the value into the new set, copying if necessary */ @@ -421,17 +421,17 @@ Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func) set_insert(new_set, copied_value); } - set_iterator_free(iterator); + set_iter_free(iterator); /* Add all values from the second set */ iterator = set_iterate(set2); - while (set_iterator_has_more(iterator)) { + while (set_iter_has_more(iterator)) { /* Read the next value */ - value = set_iterator_next(iterator); + value = set_iter_next(iterator); /* Has this value been put into the new set already? * If so, do not insert this again */ @@ -451,7 +451,7 @@ Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func) } } - set_iterator_free(iterator); + set_iter_free(iterator); return new_set; } @@ -470,11 +470,11 @@ Set *set_intersection(Set *set1, Set *set2, iterator = set_iterate(set1); - while (set_iterator_has_more(iterator)) { + while (set_iter_has_more(iterator)) { /* Get the next value */ - value = set_iterator_next(iterator); + value = set_iter_next(iterator); /* Is this value in set 2 as well? If so, it should be * in the new set. */ @@ -494,7 +494,7 @@ Set *set_intersection(Set *set1, Set *set2, } } - set_iterator_free(iterator); + set_iter_free(iterator); return new_set; } @@ -529,7 +529,7 @@ SetIterator *set_iterate(Set *set) return iter; } -void *set_iterator_next(SetIterator *iterator) +void *set_iter_next(SetIterator *iterator) { Set *set; void *result; @@ -589,12 +589,12 @@ void *set_iterator_next(SetIterator *iterator) return result; } -int set_iterator_has_more(SetIterator *iterator) +int set_iter_has_more(SetIterator *iterator) { return iterator->next_entry != NULL; } -void set_iterator_free(SetIterator *iterator) +void set_iter_free(SetIterator *iterator) { free(iterator); } diff --git a/src/set.h b/src/set.h index 37cd07f..c07d110 100644 --- a/src/set.h +++ b/src/set.h @@ -224,7 +224,7 @@ Set *set_intersection(Set *set1, Set *set2, /** * Create an iterator to iterate over the values in a set. * It should be noted that a set iterator must be freed once iterating - * has been completed. This should be done using @ref set_iterator_free. + * has been completed. This should be done using @ref set_iter_free. * * @param set The set to iterate over. * @return A new iterator object. @@ -235,7 +235,7 @@ SetIterator *set_iterate(Set *set); /** * Determine if there are more values in the set to iterate over. * It should be noted that a set iterator is not freed when iterating - * has finished. This should be done using @ref set_iterator_free. + * has finished. This should be done using @ref set_iter_free. * * @param iterator The set iterator object. * @return Zero if there are no more values in the set @@ -243,7 +243,7 @@ SetIterator *set_iterate(Set *set); * values to be read. */ -int set_iterator_has_more(SetIterator *iterator); +int set_iter_has_more(SetIterator *iterator); /** * Using a set iterator, retrieve the next value from the set. @@ -253,7 +253,7 @@ int set_iterator_has_more(SetIterator *iterator); * more values are available. */ -void *set_iterator_next(SetIterator *iterator); +void *set_iter_next(SetIterator *iterator); /** * Free back a set iterator object. @@ -261,7 +261,7 @@ void *set_iterator_next(SetIterator *iterator); * @param iterator The iterator to free. */ -void set_iterator_free(SetIterator *iterator); +void set_iter_free(SetIterator *iterator); #ifdef __cplusplus } diff --git a/test/test-hashtable.c b/test/test-hashtable.c index 750828f..19a76c1 100644 --- a/test/test-hashtable.c +++ b/test/test-hashtable.c @@ -179,13 +179,13 @@ void test_hash_table_iterating(void) iterator = hash_table_iterate(hashtable); - while (hash_table_iterator_has_more(iterator)) { - hash_table_iterator_next(iterator); + while (hash_table_iter_has_more(iterator)) { + hash_table_iter_next(iterator); ++count; } - hash_table_iterator_free(iterator); + hash_table_iter_free(iterator); assert(count == 10000); @@ -195,9 +195,9 @@ void test_hash_table_iterating(void) iterator = hash_table_iterate(hashtable); - assert(hash_table_iterator_has_more(iterator) == 0); + assert(hash_table_iter_has_more(iterator) == 0); - hash_table_iterator_free(iterator); + hash_table_iter_free(iterator); } /* Demonstrates the ability to iteratively remove objects from @@ -222,11 +222,11 @@ void test_hash_table_iterating_remove(void) iterator = hash_table_iterate(hashtable); - while (hash_table_iterator_has_more(iterator)) { + while (hash_table_iter_has_more(iterator)) { /* Read the next value */ - val = (int *) hash_table_iterator_next(iterator); + val = (int *) hash_table_iter_next(iterator); /* Remove every hundredth entry */ @@ -238,7 +238,7 @@ void test_hash_table_iterating_remove(void) ++count; } - hash_table_iterator_free(iterator); + hash_table_iter_free(iterator); /* Check counts */ From 6af8fcf91f5487395a6d9ae23d207d6f5c3884ee Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 19 Jun 2006 17:22:21 +0000 Subject: [PATCH 004/250] Convert spaces to tabs. --- src/hashtable.c | 4 ++-- src/set.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hashtable.c b/src/hashtable.c index abb8097..3f43e35 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -463,9 +463,9 @@ void *hash_table_iter_next(HashTableIterator *iterator) break; } - /* Try the next chain */ + /* Try the next chain */ - ++chain; + ++chain; } iterator->next_chain = chain; diff --git a/src/set.c b/src/set.c index c0f3d36..6127dd3 100644 --- a/src/set.c +++ b/src/set.c @@ -508,7 +508,7 @@ SetIterator *set_iterate(Set *set) iter = malloc(sizeof(SetIterator)); - iter->set = set; + iter->set = set; iter->current_entry = NULL; iter->next_entry = NULL; @@ -533,7 +533,7 @@ void *set_iter_next(SetIterator *iterator) { Set *set; void *result; - int chain; + int chain; set = iterator->set; @@ -563,9 +563,9 @@ void *set_iter_next(SetIterator *iterator) /* No more entries in this chain. Search the next chain */ - chain = iterator->next_chain + 1; + chain = iterator->next_chain + 1; - while (chain < set->table_size) { + while (chain < set->table_size) { /* Is there a chain at this table entry? */ @@ -580,10 +580,10 @@ void *set_iter_next(SetIterator *iterator) /* Keep searching until we find an empty chain */ - ++chain; + ++chain; } - iterator->next_chain = chain; + iterator->next_chain = chain; } return result; From 138b6677ff6d4a19cef620d2ddf975e2ec194f8c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 19 Jun 2006 17:32:33 +0000 Subject: [PATCH 005/250] Add test cases for set iterator functions. --- test/test-set.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/test/test-set.c b/test/test-set.c index 449536b..1e28bf6 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -267,6 +267,94 @@ void test_set_to_array(void) } } +void test_set_iterating(void) +{ + Set *set; + SetIterator *iterator; + int count; + + set = generate_set(); + + /* Iterate over all values in the set */ + + count = 0; + iterator = set_iterate(set); + + while (set_iter_has_more(iterator)) { + + set_iter_next(iterator); + + ++count; + } + + set_iter_free(iterator); + + /* Check final count */ + + assert(count == 10000); + + set_free(set); + + /* Test iterating over an empty set */ + + set = set_new(int_hash, int_equal); + + iterator = set_iterate(set); + + assert(set_iter_has_more(iterator) == 0); + + set_iter_free(iterator); + set_free(set); +} + +/* Test the ability to remove the current value while iterating over + * a set. ie. the act of removing the current value should not affect + * the iterator. */ + +void test_set_iterating_remove(void) +{ + Set *set; + SetIterator *iterator; + int count; + int removed; + int *val; + + set = generate_set(); + + count = 0; + removed = 0; + + /* Iterate over all values in the set */ + + iterator = set_iterate(set); + + while (set_iter_has_more(iterator)) { + + val = (int *) set_iter_next(iterator); + + if ((*val % 100) == 0) { + + /* Remove this value */ + + set_remove(set, val); + + ++removed; + } + + ++count; + } + + set_iter_free(iterator); + + /* Check final counts */ + + assert(count == 10000); + assert(removed == 100); + assert(set_num_entries(set) == 10000 - removed); + + set_free(set); +} + int main(int argc, char *argv[]) { test_set_new(); @@ -276,6 +364,8 @@ int main(int argc, char *argv[]) test_set_remove(); test_set_intersection(); test_set_union(); + test_set_iterating(); + test_set_iterating_remove(); return 0; } From 9f8806748d2f8c867084c30072f568ed59362390 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 19 Jun 2006 17:50:38 +0000 Subject: [PATCH 006/250] Remove the double-pointer usage (breaks remove while iterating). --- src/hashtable.c | 15 +++++++-------- src/set.c | 14 +++++++------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/hashtable.c b/src/hashtable.c index 3f43e35..c107540 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -61,8 +61,8 @@ struct _HashTable { struct _HashTableIterator { HashTable *hashtable; - HashTableEntry **current_entry; - HashTableEntry **next_entry; + HashTableEntry *current_entry; + HashTableEntry *next_entry; int next_chain; }; @@ -402,7 +402,7 @@ HashTableIterator *hash_table_iterate(HashTable *hashtable) for (chain=0; chaintable_size; ++chain) { if (hashtable->table[chain] != NULL) { - iterator->next_entry = &hashtable->table[chain]; + iterator->next_entry = hashtable->table[chain]; iterator->next_chain = chain; break; } @@ -433,15 +433,15 @@ void *hash_table_iter_next(HashTableIterator *iterator) /* Result is immediately available */ iterator->current_entry = iterator->next_entry; - result = (*iterator->current_entry)->key; + result = iterator->current_entry->key; /* Find the next entry */ - if ((*iterator->current_entry)->next != NULL) { + if (iterator->current_entry->next != NULL) { /* Next entry in current chain */ - iterator->next_entry = &(*iterator->current_entry)->next; + iterator->next_entry = iterator->current_entry->next; } else { @@ -458,8 +458,7 @@ void *hash_table_iter_next(HashTableIterator *iterator) /* Is there anything in this chain? */ if (hashtable->table[chain] != NULL) { - iterator->next_entry - = &hashtable->table[chain]; + iterator->next_entry = hashtable->table[chain]; break; } diff --git a/src/set.c b/src/set.c index 6127dd3..bba662b 100644 --- a/src/set.c +++ b/src/set.c @@ -58,8 +58,8 @@ struct _Set { struct _SetIterator { Set *set; - SetEntry **current_entry; - SetEntry **next_entry; + SetEntry *current_entry; + SetEntry *next_entry; int next_chain; }; @@ -519,7 +519,7 @@ SetIterator *set_iterate(Set *set) /* There is a value at the start of this chain */ if (set->table[chain] != NULL) { - iter->next_entry = &set->table[chain]; + iter->next_entry = set->table[chain]; break; } } @@ -545,15 +545,15 @@ void *set_iter_next(SetIterator *iterator) /* We have the result immediately */ iterator->current_entry = iterator->next_entry; - result = (*iterator->current_entry)->data; + result = iterator->current_entry->data; /* Advance next_entry to the next SetEntry in the Set. */ - if ((*iterator->current_entry)->next != NULL) { + if (iterator->current_entry->next != NULL) { /* Use the next value in this chain */ - iterator->next_entry = &((*iterator->current_entry)->next); + iterator->next_entry = iterator->current_entry->next; } else { @@ -573,7 +573,7 @@ void *set_iter_next(SetIterator *iterator) /* Valid chain found! */ - iterator->next_entry = &set->table[chain]; + iterator->next_entry = set->table[chain]; break; } From 9cad5c6248ec8eec8492a06bbecf56b19b7ad80e Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 20 Oct 2006 23:34:08 +0000 Subject: [PATCH 007/250] Add a binary heap implementation. --- src/Makefile.am | 8 +- src/binary-heap.c | 215 ++++++++++++++++++++++++++++++++++++++++++++++ src/binary-heap.h | 138 +++++++++++++++++++++++++++++ 3 files changed, 357 insertions(+), 4 deletions(-) create mode 100644 src/binary-heap.c create mode 100644 src/binary-heap.h diff --git a/src/Makefile.am b/src/Makefile.am index 5e00fc5..dfcaab8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,14 +6,14 @@ lib_LTLIBRARIES=libcalg.la MAIN_HEADERFILES = libcalg.h CALG_HEADERFILES=\ -arraylist.h compare-int.h hash-int.h hashtable.h set.h \ -avltree.h compare-pointer.h hash-pointer.h list.h slist.h \ -queue.h compare-string.h hash-string.h trie.h +arraylist.h compare-int.h hash-int.h hashtable.h set.h \ +avltree.h compare-pointer.h hash-pointer.h list.h slist.h \ +queue.h compare-string.h hash-string.h trie.h binary-heap.h SRC=\ arraylist.c compare-pointer.c hash-pointer.c list.c slist.c \ avltree.c compare-string.c hash-string.c queue.c trie.c \ -compare-int.c hash-int.c hashtable.c set.c +compare-int.c hash-int.c hashtable.c set.c binary-heap.c libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) diff --git a/src/binary-heap.c b/src/binary-heap.c new file mode 100644 index 0000000..18f87f0 --- /dev/null +++ b/src/binary-heap.c @@ -0,0 +1,215 @@ + +/* + +Copyright (c) 2005, Simon Howard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include + +#include "binary-heap.h" + +struct _BinaryHeap { + BinaryHeapType heap_type; + void **values; + int num_values; + int alloced_size; + BinaryHeapCompareFunc compare_func; +}; + +static int binary_heap_cmp(BinaryHeap *heap, void *data1, void *data2) +{ + if (heap->heap_type == BINARY_HEAP_TYPE_MIN) { + return heap->compare_func(data1, data2); + } else { + return -heap->compare_func(data1, data2); + } +} + +BinaryHeap *binary_heap_new(BinaryHeapType heap_type, + BinaryHeapCompareFunc compare_func) +{ + BinaryHeap *heap; + + heap = malloc(sizeof(BinaryHeap)); + heap->heap_type = heap_type; + heap->num_values = 0; + heap->compare_func = compare_func; + + /* Initial size of 16 elements */ + + heap->alloced_size = 16; + heap->values = malloc(sizeof(void *) * heap->alloced_size); + + return heap; +} + +void binary_heap_insert(BinaryHeap *heap, void *value) +{ + int index; + int parent; + + /* Possibly realloc the heap to a larger size */ + + if (heap->num_values >= heap->alloced_size) { + + /* Double the table size */ + + heap->alloced_size *= 2; + heap->values = realloc(heap->values, + sizeof(void *) * heap->alloced_size); + } + + /* Add to the bottom of the heap and start from there */ + + index = heap->num_values; + ++heap->num_values; + + /* Percolate the value up to the top of the heap */ + + while (index > 0) { + + /* The parent index is found by halving the node index */ + + parent = index / 2; + + /* Compare the node with its parent */ + + if (binary_heap_cmp(heap, heap->values[parent], value) < 0) { + + /* Ordered correctly - insertion is complete */ + + break; + + } else { + + /* Need to swap this node with its parent */ + + heap->values[index] = heap->values[parent]; + + /* Advance up to the parent */ + + index = parent; + } + } + + /* Save the new value in the final location */ + + heap->values[index] = value; +} + +void *binary_heap_pop(BinaryHeap *heap) +{ + void *result; + void *new_value; + int index; + int next_index; + int child1, child2; + + /* Empty heap? */ + + if (heap->num_values == 0) { + return NULL; + } + + /* Take the value from the top of the heap */ + + result = heap->values[0]; + + /* Remove the last value from the heap; we will percolate this down + * from the top. */ + + new_value = heap->values[heap->num_values - 1]; + --heap->num_values; + + /* Percolate the new top value down */ + + index = 0; + + for (;;) { + + /* Calculate the array indexes of the children of this node */ + + child1 = index * 2 + 1; + child2 = index * 2 + 2; + + if (child1 < heap->num_values + && binary_heap_cmp(heap, + new_value, + heap->values[child1]) > 0) { + + /* Left child is less than the node. We need to swap + * with one of the children, whichever is less. */ + + if (child2 < heap->num_values + && binary_heap_cmp(heap, + heap->values[child1], + heap->values[child2]) < 0) { + next_index = child1; + } else { + next_index = child2; + } + + } else if (child2 < heap->num_values + && binary_heap_cmp(heap, + new_value, + heap->values[child2]) > 0) { + + /* Right child is less than the node. Swap with the + * right child. */ + + next_index = child2; + + } else { + /* Node is less than both its children. The heap condition + * is satisfied. We can stop percolating down. */ + + heap->values[index] = new_value; + break; + } + + /* Swap the current node with the least of the child nodes. */ + + heap->values[index] = heap->values[next_index]; + + /* Advance to the child we chose */ + + index = next_index; + } + + return result; +} + +int binary_heap_num_entries(BinaryHeap *heap) +{ + return heap->num_values; +} + diff --git a/src/binary-heap.h b/src/binary-heap.h new file mode 100644 index 0000000..ac70395 --- /dev/null +++ b/src/binary-heap.h @@ -0,0 +1,138 @@ + +/* + +Copyright (c) 2005, Simon Howard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +/** + * @file binary-heap.h + * + * @brief Binary heap. + * + * A binary heap is a heap data structure implemented using a + * binary tree. In a heap, values are ordered by priority. + * + * To create a binary heap, use @ref binary_heap_new. To destroy a + * binary heap, use @ref binary_heap_free. + * + * To insert a value into a binary heap, use @ref binary_heap_insert. + * + * To remove the first value from a binary heap, use @ref binary_heap_pop. + * + */ + +#ifndef ALGORITHM_BINARY_HEAP_H +#define ALGORITHM_BINARY_HEAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Heap type. If a heap is a min heap, the values with the lowest + * priority are stored at the top of the heap and will be the first + * returned. If a heap is a max heap, the values with the + * greatest priority are stored at the top of the heap. + */ + +typedef enum { + BINARY_HEAP_TYPE_MIN, + BINARY_HEAP_TYPE_MAX, +} BinaryHeapType; + +/** + * Type of function used to compare values in a binary heap. + * + * @param data1 The first value. + * @param data2 The second value. + * @return A negative number if data1 is less than data2, + * a positive number if data1 is greater than data2, + * zero if the two are equal. + */ + +typedef int (*BinaryHeapCompareFunc)(void *data1, void *data2); + +/** + * A binary heap data structure. + */ + +typedef struct _BinaryHeap BinaryHeap; + +/** + * Create a new @ref BinaryHeap. + * + * @param heap_type The type of heap: min heap or max heap. + * @param compare_func Pointer to a function used to compare the priority + * of values in the heap. + * @return A new binary heap. + */ + +BinaryHeap *binary_heap_new(BinaryHeapType heap_type, + BinaryHeapCompareFunc compare_func); + +/** + * Destroy a binary heap. + * + * @param heap The heap to destroy. + */ + +void binary_heap_free(BinaryHeap *heap); + +/** + * Insert a value into a binary heap. + * + * @param heap The heap to insert into. + * @param value The value to insert. + */ + +void binary_heap_insert(BinaryHeap *heap, void *value); + +/** + * Remove the first value from a binary heap. + * + * @param heap The heap. + * @return The first value in the heap. + */ + +void *binary_heap_pop(BinaryHeap *heap); + +/** + * Find the number of values stored in a binary heap. + * + * @param heap The heap. + * @return The number of values in the heap. + */ + +int binary_heap_num_entries(BinaryHeap *heap); + +#endif /* #ifndef ALGORITHM_BINARY_HEAP_H */ + From 999a286cc3b690523251fdbe88da29df8a078019 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 21 Oct 2006 22:27:40 +0000 Subject: [PATCH 008/250] Use calloc/malloc more appropriately (don't clear memory unnecessarily), don't use memset where it isn't needed. --- src/arraylist.c | 2 +- src/avltree.c | 2 +- src/hashtable.c | 2 -- src/list.c | 2 +- src/set.c | 1 - src/trie.c | 3 +-- 6 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/arraylist.c b/src/arraylist.c index 0e0fe09..e49a53a 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -59,7 +59,7 @@ ArrayList *arraylist_new(int length) /* Allocate the data array */ - new_arraylist->data = calloc(length, sizeof(void *)); + new_arraylist->data = malloc(length * sizeof(void *)); return new_arraylist; } diff --git a/src/avltree.c b/src/avltree.c index 088d08d..854b34d 100644 --- a/src/avltree.c +++ b/src/avltree.c @@ -676,7 +676,7 @@ void **avltree_to_array(AVLTree *tree) /* Allocate the array */ - array = calloc(sizeof(void *), tree->num_nodes); + array = malloc(sizeof(void *) * tree->num_nodes); index = 0; /* Add all keys */ diff --git a/src/hashtable.c b/src/hashtable.c index c107540..4cec414 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -100,8 +100,6 @@ static void hash_table_allocate_table(HashTable *hashtable) hashtable->table = calloc(hashtable->table_size, sizeof(HashTableEntry *)); - memset(hashtable->table, 0, - hashtable->table_size * sizeof(HashTableEntry *)); } /* Free an entry, calling the free functions if there are any registered */ diff --git a/src/list.c b/src/list.c index 0f98346..31c5ab8 100644 --- a/src/list.c +++ b/src/list.c @@ -211,7 +211,7 @@ void **list_to_array(ListEntry *list) listlen = list_length(list); - array = calloc(sizeof(void *), listlen); + array = malloc(sizeof(void *) * listlen); /* Add all entries to the array */ diff --git a/src/set.c b/src/set.c index bba662b..c8c9f37 100644 --- a/src/set.c +++ b/src/set.c @@ -93,7 +93,6 @@ static void set_allocate_table(Set *set) /* Allocate the table and initialise to NULL */ set->table = calloc(set->table_size, sizeof(SetEntry *)); - memset(set->table, 0, set->table_size * sizeof(SetEntry *)); } static void set_free_entry(Set *set, SetEntry *entry) diff --git a/src/trie.c b/src/trie.c index cb00442..7e95c92 100644 --- a/src/trie.c +++ b/src/trie.c @@ -118,8 +118,7 @@ void trie_insert(Trie *trie, char *key, void *value) /* Node does not exist, so create it */ - node = (TrieNode *) malloc(sizeof(TrieNode)); - memset(node, 0, sizeof(TrieNode)); + node = (TrieNode *) calloc(1, sizeof(TrieNode)); /* Link in to the trie */ From e661c3dd6efc1111c5036c6ddcf5a7bb76a45348 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 22 Oct 2006 00:04:59 +0000 Subject: [PATCH 009/250] Add binary_heap_free. --- src/binary-heap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/binary-heap.c b/src/binary-heap.c index 18f87f0..4a68c46 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -72,6 +72,12 @@ BinaryHeap *binary_heap_new(BinaryHeapType heap_type, return heap; } +void binary_heap_free(BinaryHeap *heap) +{ + free(heap->values); + free(heap); +} + void binary_heap_insert(BinaryHeap *heap, void *value) { int index; From 0fc1191a6af9e0a23587bc6a4d411a2e5ce21479 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 22 Oct 2006 01:45:15 +0000 Subject: [PATCH 010/250] Fix errors: (i - 1) / 2 to get parent index, do not use child 2 when it does not exist. --- src/binary-heap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/binary-heap.c b/src/binary-heap.c index 4a68c46..de7d20c 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -105,7 +105,7 @@ void binary_heap_insert(BinaryHeap *heap, void *value) /* The parent index is found by halving the node index */ - parent = index / 2; + parent = (index - 1) / 2; /* Compare the node with its parent */ @@ -178,10 +178,10 @@ void *binary_heap_pop(BinaryHeap *heap) if (child2 < heap->num_values && binary_heap_cmp(heap, heap->values[child1], - heap->values[child2]) < 0) { - next_index = child1; - } else { + heap->values[child2]) > 0) { next_index = child2; + } else { + next_index = child1; } } else if (child2 < heap->num_values From 491be5944883ebbf886ee744ba519abf670060d6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 22 Oct 2006 01:49:08 +0000 Subject: [PATCH 011/250] Add test suite for binary heap. --- test/Makefile.am | 1 + test/test-binary-heap.c | 137 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 test/test-binary-heap.c diff --git a/test/Makefile.am b/test/Makefile.am index 369c808..45bec85 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,6 +2,7 @@ TESTS = \ test-arraylist \ test-avltree \ + test-binary-heap \ test-list \ test-slist \ test-queue \ diff --git a/test/test-binary-heap.c b/test/test-binary-heap.c new file mode 100644 index 0000000..06e84e0 --- /dev/null +++ b/test/test-binary-heap.c @@ -0,0 +1,137 @@ + +/* + +Copyright (c) 2005, Simon Howard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include + +#include "binary-heap.h" +#include "compare-int.h" + +void test_binary_heap_new_free(void) +{ + BinaryHeap *heap; + int i; + + for (i=0; i<1000; ++i) { + heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); + binary_heap_free(heap); + } +} + +void test_binary_heap_insert(void) +{ + BinaryHeap *heap; + int *val; + int i; + + heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); + + for (i=0; i<1000; ++i) { + val = malloc(sizeof(int)); + *val = i; + binary_heap_insert(heap, val); + } + assert(binary_heap_num_entries(heap) == 1000); + + binary_heap_free(heap); +} + +void test_min_heap(void) +{ + BinaryHeap *heap; + int *val; + int i; + + heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); + + /* Push a load of values onto the heap */ + + for (i=0; i<1000; ++i) { + val = malloc(sizeof(int)); + *val = i; + binary_heap_insert(heap, val); + } + + /* Pop values off the heap and check they are in order */ + + i = -1; + while (binary_heap_num_entries(heap) > 0) { + val = (int *) binary_heap_pop(heap); + + assert(*val == i + 1); + i = *val; + } + + binary_heap_free(heap); +} + +void test_max_heap(void) +{ + BinaryHeap *heap; + int *val; + int i; + + heap = binary_heap_new(BINARY_HEAP_TYPE_MAX, int_compare); + + /* Push a load of values onto the heap */ + + for (i=0; i<1000; ++i) { + val = malloc(sizeof(int)); + *val = i; + binary_heap_insert(heap, val); + } + + /* Pop values off the heap and check they are in order */ + + i = 1000; + while (binary_heap_num_entries(heap) > 0) { + val = (int *) binary_heap_pop(heap); + + assert(*val == i - 1); + i = *val; + } + + binary_heap_free(heap); +} + +int main(int argc, char *argv[]) +{ + test_binary_heap_new_free(); + test_min_heap(); + test_max_heap(); + + return 0; +} + From ff1bfffa57e6276930d03dfb45367ede6f63c3f0 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 26 Oct 2006 18:39:38 +0000 Subject: [PATCH 012/250] Use "good hash table primes" from http://planetmath.org/encyclopedia/GoodHashTablePrimes.html --- src/hashtable.c | 23 ++++++++++++----------- src/set.c | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/hashtable.c b/src/hashtable.c index 4cec414..dd1c25f 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -66,19 +66,20 @@ struct _HashTableIterator { int next_chain; }; -/* Prime numbers on an escalating exponential scale, used for the table - * size. Each value is approximately 1.5 * the previous value, so the - * table size increases by 50% with each enlargement */ - -static unsigned int hash_table_primes[] = { - 251, 383, 571, 863, 1291, 1933, 2909, 4373, 6553, 9839, 14759, 22133, - 33211, 49811, 74719, 112069, 168127, 252193, 378289, 567407, 851131, - 1276721, 1915057, 2872621, 4308937, 6463399, 9695099, 14542651, - 21813997, 32721001, 49081441, 73622251, 110433383, 165650033, - 248475107, 372712667, 559068997, 838603499, 1257905249, 1886857859, +/* This is a set of good hash table prime numbers, from: + * http://planetmath.org/encyclopedia/GoodHashTablePrimes.html + * Each prime is roughly double the previous value, and as far as + * possible from the nearest powers of two. */ + +static const unsigned int hash_table_primes[] = { + 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, + 196613, 393241, 786433, 1572869, 3145739, 6291469, + 12582917, 25165843, 50331653, 100663319, 201326611, + 402653189, 805306457, 1610612741, }; -static int hash_table_num_primes = sizeof(hash_table_primes) / sizeof(int); +static const int hash_table_num_primes + = sizeof(hash_table_primes) / sizeof(int); /* Internal function used to allocate the table on hashtable creation * and when enlarging the table */ diff --git a/src/set.c b/src/set.c index c8c9f37..4636806 100644 --- a/src/set.c +++ b/src/set.c @@ -63,19 +63,19 @@ struct _SetIterator { int next_chain; }; -/* Prime numbers on an escalating exponential scale, used for the table - * size. Each value is approximately 1.5 * the previous value, so the - * table size increases by 50% with each enlargement */ - -static unsigned int set_primes[] = { - 251, 383, 571, 863, 1291, 1933, 2909, 4373, 6553, 9839, 14759, 22133, - 33211, 49811, 74719, 112069, 168127, 252193, 378289, 567407, 851131, - 1276721, 1915057, 2872621, 4308937, 6463399, 9695099, 14542651, - 21813997, 32721001, 49081441, 73622251, 110433383, 165650033, - 248475107, 372712667, 559068997, 838603499, 1257905249, 1886857859, +/* This is a set of good hash table prime numbers, from: + * http://planetmath.org/encyclopedia/GoodHashTablePrimes.html + * Each prime is roughly double the previous value, and as far as + * possible from the nearest powers of two. */ + +static const unsigned int set_primes[] = { + 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, + 196613, 393241, 786433, 1572869, 3145739, 6291469, + 12582917, 25165843, 50331653, 100663319, 201326611, + 402653189, 805306457, 1610612741, }; -static int set_num_primes = sizeof(set_primes) / sizeof(int); +static const int set_num_primes = sizeof(set_primes) / sizeof(int); static void set_allocate_table(Set *set) { From 97539be8d3bd75bf926ca978394d30500adeacaf Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 27 Oct 2006 17:16:26 +0000 Subject: [PATCH 013/250] Fix lockup when removing entries from sets. --- src/set.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/set.c b/src/set.c index 4636806..1d13988 100644 --- a/src/set.c +++ b/src/set.c @@ -313,6 +313,10 @@ int set_remove(Set *set, void *data) return 1; } + + /* Advance to the next entry */ + + rover = &((*rover)->next); } /* Not found in set */ @@ -541,6 +545,7 @@ void *set_iter_next(SetIterator *iterator) if (iterator->next_entry == NULL) { return NULL; } + /* We have the result immediately */ iterator->current_entry = iterator->next_entry; From 45beabc373e78bd354a1209db3bc06a26c267715 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 27 Oct 2006 17:23:14 +0000 Subject: [PATCH 014/250] Improve the set_remove test function. --- test/test-set.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/test/test-set.c b/test/test-set.c index 1e28bf6..2214cb8 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -146,24 +146,46 @@ void test_set_remove(void) { Set *set; int i; + int num_entries; set = generate_set(); - i = 5000; - assert(set_query(set, &i) != 0); - assert(set_num_entries(set) == 10000); + num_entries = set_num_entries(set); + assert(num_entries == 10000); - /* Remove an entry */ + /* Remove some entries */ - set_remove(set, &i); - assert(set_num_entries(set) == 9999); - assert(set_query(set, &i) == 0); + for (i=4000; i<6000; ++i) { + /* Check this is in the set */ + + assert(set_query(set, &i) != 0); + + /* Remove it */ + + assert(set_remove(set, &i) != 0); + + /* Check the number of entries decreases */ + + assert(set_num_entries(set) == num_entries - 1); + + /* Check it is no longer in the set */ + + assert(set_query(set, &i) == 0); + + --num_entries; + } + + /* Try to remove some invalid entries */ - /* Try to remove an invalid entry */ + for (i=-1000; i<-500; ++i) { + assert(set_remove(set, &i) == 0); + assert(set_num_entries(set) == num_entries); + } - i = 50000; - set_remove(set, &i); - assert(set_num_entries(set) == 9999); + for (i=50000; i<51000; ++i) { + assert(set_remove(set, &i) == 0); + assert(set_num_entries(set) == num_entries); + } } void test_set_union(void) From ff24ce9faefdbee16a3bde69223d6a27eede306b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 27 Oct 2006 18:34:18 +0000 Subject: [PATCH 015/250] Replace list_foreach with iterator objects. --- src/list.c | 139 ++++++++++++++++++++++++++++++++++++++--------- src/list.h | 70 ++++++++++++++++++------ test/test-list.c | 42 ++++++++------ 3 files changed, 194 insertions(+), 57 deletions(-) diff --git a/src/list.c b/src/list.c index 31c5ab8..06049b2 100644 --- a/src/list.c +++ b/src/list.c @@ -45,6 +45,14 @@ struct _ListEntry { ListEntry *next; }; +/* Iterator for iterating over a doubly-linked list. */ + +struct _ListIterator { + ListEntry **list; + ListEntry **prev_next; + ListEntry *current; +}; + void list_free(ListEntry *list) { ListEntry *entry; @@ -231,26 +239,6 @@ void **list_to_array(ListEntry *list) return array; } -void list_foreach(ListEntry *list, ListIterator callback, void *user_data) -{ - ListEntry *entry; - - /* Iterate over each entry in the list */ - - entry = list; - - while (entry != NULL) { - - /* Invoke the callback function */ - - callback(entry->data, user_data); - - /* Advance to the next entry */ - - entry = entry->next; - } -} - int list_remove_entry(ListEntry **list, ListEntry *entry) { /* If the list is empty, or entry is NULL, always fail */ @@ -277,7 +265,8 @@ int list_remove_entry(ListEntry **list, ListEntry *entry) } else { /* This is not the first in the list, so we must have a - * previous entry. Update its 'next' pointer to the new value */ + * previous entry. Update its 'next' pointer to the new + * value */ entry->prev->next = entry->next; @@ -316,8 +305,8 @@ int list_remove_data(ListEntry **list, ListEqualFunc callback, void *data) if (callback(rover->data, data)) { - /* This data needs to be removed. Unlink this entry from - * the list. */ + /* This data needs to be removed. Unlink this entry + * from the list. */ if (rover->prev == NULL) { @@ -326,7 +315,8 @@ int list_remove_data(ListEntry **list, ListEqualFunc callback, void *data) *list = rover->next; } else { - /* Point the previous entry at its new location */ + /* Point the previous entry at its new + * location */ rover->prev->next = rover->next; } @@ -471,5 +461,104 @@ ListEntry *list_find_data(ListEntry *list, return NULL; } - +ListIterator *list_iterate(ListEntry **list) +{ + ListIterator *iter; + + /* Create a new iterator */ + + iter = malloc(sizeof(ListIterator)); + + if (iter == NULL) { + return NULL; + } + + /* Save pointer to the list */ + + iter->list = list; + + /* These are NULL until the first call to list_iter_next: */ + + iter->prev_next = NULL; + iter->current = NULL; + + return iter; +} + +int list_iter_has_more(ListIterator *iter) +{ + if (iter->prev_next == NULL) { + + /* The list has just been created. list_iter_next + * has not been called yet. There are more entries + * if the list is not empty. */ + + return *iter->list != NULL; + + } else if (*iter->prev_next != iter->current) { + + /* Current entry has been deleted since the last call + * to list_iter_next. Use prev_next as an indicator + * of the next entry. */ + + return *iter->prev_next != NULL; + + } else { + /* The current entry as not been deleted since the last + * call to list_iter_next: there is a next entry if + * current->next is not NULL */ + + return iter->current->next != NULL; + } +} + +void *list_iter_next(ListIterator *iter) +{ + if (iter->prev_next == NULL) { + /* First call to list_iter_next. Initialise. */ + + /* Initial previous next link is the pointer to the list + * start variable */ + + iter->prev_next = iter->list; + + /* Start at the first element */ + + iter->current = *iter->list; + + } else if (*iter->prev_next != iter->current) { + + /* The current value has been deleted since the last call + * to list_iter_next. Use what prev_next is pointing to + * now as the next entry. */ + + iter->current = *iter->prev_next; + + } else { + + /* Current entry has not been deleted since the last call + * to list_iter_next. Simply advance to the next entry + * in the list. */ + + if (iter->current != NULL) { + iter->prev_next = &iter->current->next; + iter->current = iter->current->next; + } + + } + + /* Return data from the current entry */ + + return iter->current->data; +} + +void list_iter_remove(ListIterator *iter) +{ + list_remove_entry(iter->list, iter->current); +} + +void list_iter_free(ListIterator *iter) +{ + free(iter); +} diff --git a/src/list.h b/src/list.h index e0b1c0f..4f0ce73 100644 --- a/src/list.h +++ b/src/list.h @@ -75,14 +75,11 @@ POSSIBILITY OF SUCH DAMAGE. typedef struct _ListEntry ListEntry; -/** - * Callback function used for iterating over a list. - * - * @param data The element being iterated over. - * @param user_data Extra data specified by the user. +/** + * Structure used to iterate over a list. */ -typedef void (*ListIterator)(void *data, void *user_data); +typedef struct _ListIterator ListIterator; /** * Callback function used to compare values in a list when sorting. @@ -206,16 +203,6 @@ int list_length(ListEntry *list); void **list_to_array(ListEntry *list); -/** - * Iterate over all entries in a list. - * - * @param list The list. - * @param callback Callback function to invoke for each entry in the list. - * @param user_data Extra data to pass to the callback function. - */ - -void list_foreach(ListEntry *list, ListIterator callback, void *user_data); - /** * Remove an entry from a list. * @@ -263,5 +250,56 @@ ListEntry *list_find_data(ListEntry *list, ListEqualFunc callback, void *data); +/** + * Create an iterator to iterate over the values in a list. + * The iterator should be freed once iterating has completed, using + * the function @ref list_iter_free. + * + * @param list A pointer to the list to iterate over. + * @return A new iterator. + */ + +ListIterator *list_iterate(ListEntry **list); + +/** + * Determine if there are more values in the list to iterate over. When + * iteration is finished, the iterator should be freed using + * @ref list_iter_free. + * + * @param iterator The list iterator. + * @return Zero if there are no more values in the list to + * iterate over, non-zero if there are more values to + * read. + */ + +int list_iter_has_more(ListIterator *iter); + +/** + * Using a list iterator, retrieve the next value from the list. + * + * @param iterator The list iterator. + * @return The next value from the list, or NULL if there are + * no more values in the list. + */ + +void *list_iter_next(ListIterator *iter); + +/** + * Delete the current entry in the list (the value last returned from + * list_iter_next) + * + * @param iterator The list iterator. + */ + +void list_iter_remove(ListIterator *iter); + +/** + * Free back a list iterator. + * + * @param iterator The list iterator. + */ + +void list_iter_free(ListIterator *iter); + #endif /* #ifndef ALGORITHM_LIST_H */ diff --git a/test/test-list.c b/test/test-list.c index 47821e1..67e44b1 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -386,21 +386,14 @@ void test_list_to_array(void) assert(array[3] == &variable4); } -static void test_list_foreach_foreach(void *data, void *vcounter) +void test_list_iterate(void) { - int *counter; - - counter = (int *) vcounter; - - ++*counter; -} - -void test_list_foreach(void) -{ - int a; + ListEntry *list; + ListIterator *iter; int i; + int a; int counter; - ListEntry *list; + int *data; /* Create a list with 50 entries */ @@ -414,7 +407,20 @@ void test_list_foreach(void) counter = 0; - list_foreach(list, test_list_foreach_foreach, &counter); + iter = list_iterate(&list); + + while (list_iter_has_more(iter)) { + data = (int *) list_iter_next(iter); + ++counter; + + if ((counter % 2) == 0) { + /* Delete half the entries in the list. */ + + list_iter_remove(iter); + } + } + + list_iter_free(iter); assert(counter == 50); @@ -423,10 +429,14 @@ void test_list_foreach(void) list = NULL; counter = 0; - list_foreach(list, test_list_foreach_foreach, &counter); + iter = list_iterate(&list); - assert(counter == 0); + while (list_iter_has_more(iter)) { + data = (int *) list_iter_next(iter); + ++counter; + } + assert(counter == 0); } int main(int argc, char *argv[]) @@ -443,7 +453,7 @@ int main(int argc, char *argv[]) test_list_sort(); test_list_find_data(); test_list_to_array(); - test_list_foreach(); + test_list_iterate(); return 0; } From d476e899f35f57c06a8f04bc04907e170f6314d5 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 27 Oct 2006 19:50:36 +0000 Subject: [PATCH 016/250] Check the return value from malloc() and return error conditions if it fails. --- src/arraylist.c | 40 +++++++++++++----- src/arraylist.h | 16 ++++++-- src/avltree.c | 15 +++++++ src/avltree.h | 6 ++- src/binary-heap.c | 25 ++++++++++-- src/binary-heap.h | 8 +++- src/hashtable.c | 63 ++++++++++++++++++++++++----- src/hashtable.h | 13 ++++-- src/list.c | 14 +++++++ src/list.h | 40 +++++++++--------- src/queue.c | 22 +++++++++- src/queue.h | 13 ++++-- src/set.c | 101 +++++++++++++++++++++++++++++++--------------- src/set.h | 35 +++++----------- src/slist.c | 16 +++++++- src/slist.h | 11 +++-- src/trie.c | 15 ++++++- src/trie.h | 9 ++++- test/test-set.c | 4 +- 19 files changed, 343 insertions(+), 123 deletions(-) diff --git a/src/arraylist.c b/src/arraylist.c index e49a53a..8d72d6f 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -54,6 +54,11 @@ ArrayList *arraylist_new(int length) * initially no entries. */ new_arraylist = (ArrayList *) malloc(sizeof(ArrayList)); + + if (new_arraylist == NULL) { + return NULL; + } + new_arraylist->_alloced = length; new_arraylist->length = 0; @@ -61,7 +66,12 @@ ArrayList *arraylist_new(int length) new_arraylist->data = malloc(length * sizeof(void *)); - return new_arraylist; + if (new_arraylist->data == NULL) { + free(new_arraylist); + return NULL; + } + + return new_arraylist; } void arraylist_free(ArrayList *arraylist) @@ -74,16 +84,26 @@ void arraylist_free(ArrayList *arraylist) } } -static void arraylist_enlarge(ArrayList *arraylist) +static int arraylist_enlarge(ArrayList *arraylist) { + void **data; + /* Double the allocated size */ arraylist->_alloced *= 2; /* Reallocate the array to the new size */ - arraylist->data = realloc(arraylist->data, - sizeof(void *) * arraylist->_alloced); + data = realloc(arraylist->data, + sizeof(void *) * arraylist->_alloced); + + if (data == NULL) { + return 0; + } else { + arraylist->data = data; + + return 1; + } } int arraylist_insert(ArrayList *arraylist, int index, void *data) @@ -97,7 +117,9 @@ int arraylist_insert(ArrayList *arraylist, int index, void *data) /* Increase the size if necessary */ if (arraylist->length + 1 > arraylist->_alloced) { - arraylist_enlarge(arraylist); + if (!arraylist_enlarge(arraylist)) { + return 0; + } } /* Move the contents of the array forward from the index @@ -115,14 +137,14 @@ int arraylist_insert(ArrayList *arraylist, int index, void *data) return 1; } -void arraylist_append(ArrayList *arraylist, void *data) +int arraylist_append(ArrayList *arraylist, void *data) { - arraylist_insert(arraylist, arraylist->length, data); + return arraylist_insert(arraylist, arraylist->length, data); } -void arraylist_prepend(ArrayList *arraylist, void *data) +int arraylist_prepend(ArrayList *arraylist, void *data) { - arraylist_insert(arraylist, 0, data); + return arraylist_insert(arraylist, 0, data); } void arraylist_remove_range(ArrayList *arraylist, int index, int length) diff --git a/src/arraylist.h b/src/arraylist.h index 8c06cd5..fe06c46 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -107,7 +107,8 @@ typedef int (*ArrayListCompareFunc)(void *data1, void *data2); * * @param length Hint to the initialise function as to the amount * of memory to allocate initially to the ArrayList. - * + * @return A new arraylist, or NULL if it was not possible + * to allocate the memory. * @see arraylist_free */ @@ -126,18 +127,24 @@ void arraylist_free(ArrayList *arraylist); * * @param arraylist The ArrayList. * @param data The data to append. + * @return Non-zero if the request was successful, zero + * if it was not possible to allocate more memory + * for the new entry. */ -void arraylist_append(ArrayList *arraylist, void *data); +int arraylist_append(ArrayList *arraylist, void *data); /** * Prepend data to the beginning of an ArrayList. * * @param arraylist The ArrayList. * @param data The data to prepend. + * @return Non-zero if the request was successful, zero + * if it was not possible to allocate more memory + * for the new entry. */ -void arraylist_prepend(ArrayList *arraylist, void *data); +int arraylist_prepend(ArrayList *arraylist, void *data); /** * Remove the entry at the specified location in an ArrayList. @@ -167,7 +174,8 @@ void arraylist_remove_range(ArrayList *arraylist, int index, int length); * @param index The index at which to insert the data. * @param data The data. * @return Returns zero if unsuccessful, else non-zero - * if successful. + * if successful (due to an invalid index or + * if it was impossible to allocate more memory). */ int arraylist_insert(ArrayList *arraylist, int index, void *data); diff --git a/src/avltree.c b/src/avltree.c index 854b34d..fca921a 100644 --- a/src/avltree.c +++ b/src/avltree.c @@ -59,6 +59,11 @@ AVLTree *avltree_new(AVLTreeCompareFunc compare_func) AVLTree *new_tree; new_tree = (AVLTree *) malloc(sizeof(AVLTree)); + + if (new_tree == NULL) { + return NULL; + } + new_tree->root_node = NULL; new_tree->compare_func = compare_func; new_tree->num_nodes = 0; @@ -353,6 +358,11 @@ AVLTreeNode *avltree_insert(AVLTree *tree, void *key, void *value) /* Create a new node. Use the last node visited as the parent link. */ new_node = (AVLTreeNode *) malloc(sizeof(AVLTreeNode)); + + if (new_node == NULL) { + return NULL; + } + new_node->left_child = NULL; new_node->right_child = NULL; new_node->parent = previous_node; @@ -677,6 +687,11 @@ void **avltree_to_array(AVLTree *tree) /* Allocate the array */ array = malloc(sizeof(void *) * tree->num_nodes); + + if (array == NULL) { + return NULL; + } + index = 0; /* Add all keys */ diff --git a/src/avltree.h b/src/avltree.h index 50cc2e6..fc60d75 100644 --- a/src/avltree.h +++ b/src/avltree.h @@ -111,7 +111,8 @@ typedef int (*AVLTreeCompareFunc)(void *data1, void *data2); * Create a new AVL tree. * * @param compare_func Function to use when comparing keys in the tree. - * @return A new AVL tree. + * @return A new AVL tree, or NULL if it was not possible + * to allocate the memory. */ AVLTree *avltree_new(AVLTreeCompareFunc compare_func); @@ -131,7 +132,8 @@ void avltree_free(AVLTree *tree); * @param key The key to insert. * @param value The value to insert. * @return The newly created tree node containing the - * key and value. + * key and value, or NULL if it was not possible + * to allocate the new memory. */ AVLTreeNode *avltree_insert(AVLTree *tree, void *key, void *value); diff --git a/src/binary-heap.c b/src/binary-heap.c index de7d20c..f632d05 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -60,6 +60,11 @@ BinaryHeap *binary_heap_new(BinaryHeapType heap_type, BinaryHeap *heap; heap = malloc(sizeof(BinaryHeap)); + + if (heap == NULL) { + return NULL; + } + heap->heap_type = heap_type; heap->num_values = 0; heap->compare_func = compare_func; @@ -68,6 +73,11 @@ BinaryHeap *binary_heap_new(BinaryHeapType heap_type, heap->alloced_size = 16; heap->values = malloc(sizeof(void *) * heap->alloced_size); + + if (heap->values == NULL) { + free(heap); + return NULL; + } return heap; } @@ -78,8 +88,9 @@ void binary_heap_free(BinaryHeap *heap) free(heap); } -void binary_heap_insert(BinaryHeap *heap, void *value) +int binary_heap_insert(BinaryHeap *heap, void *value) { + void **new_values; int index; int parent; @@ -90,8 +101,14 @@ void binary_heap_insert(BinaryHeap *heap, void *value) /* Double the table size */ heap->alloced_size *= 2; - heap->values = realloc(heap->values, - sizeof(void *) * heap->alloced_size); + new_values = realloc(heap->values, + sizeof(void *) * heap->alloced_size); + + if (new_values == NULL) { + return 0; + } + + heap->values = new_values; } /* Add to the bottom of the heap and start from there */ @@ -130,6 +147,8 @@ void binary_heap_insert(BinaryHeap *heap, void *value) /* Save the new value in the final location */ heap->values[index] = value; + + return 1; } void *binary_heap_pop(BinaryHeap *heap) diff --git a/src/binary-heap.h b/src/binary-heap.h index ac70395..b0db265 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -93,7 +93,8 @@ typedef struct _BinaryHeap BinaryHeap; * @param heap_type The type of heap: min heap or max heap. * @param compare_func Pointer to a function used to compare the priority * of values in the heap. - * @return A new binary heap. + * @return A new binary heap, or NULL if it was not possible + * to allocate the memory. */ BinaryHeap *binary_heap_new(BinaryHeapType heap_type, @@ -112,9 +113,12 @@ void binary_heap_free(BinaryHeap *heap); * * @param heap The heap to insert into. * @param value The value to insert. + * @return Non-zero if the entry was added, or zero if it + * was not possible to allocate memory for the new + * entry. */ -void binary_heap_insert(BinaryHeap *heap, void *value); +int binary_heap_insert(BinaryHeap *heap, void *value); /** * Remove the first value from a binary heap. diff --git a/src/hashtable.c b/src/hashtable.c index dd1c25f..d85b5ce 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -84,7 +84,7 @@ static const int hash_table_num_primes /* Internal function used to allocate the table on hashtable creation * and when enlarging the table */ -static void hash_table_allocate_table(HashTable *hashtable) +static int hash_table_allocate_table(HashTable *hashtable) { /* Determine the table size based on the current prime index. * An attempt is made here to ensure sensible behavior if the @@ -101,6 +101,8 @@ static void hash_table_allocate_table(HashTable *hashtable) hashtable->table = calloc(hashtable->table_size, sizeof(HashTableEntry *)); + + return hashtable->table != NULL; } /* Free an entry, calling the free functions if there are any registered */ @@ -133,6 +135,11 @@ HashTable *hash_table_new(HashTableHashFunc hash_func, /* Allocate a new hash table structure */ hashtable = (HashTable *) malloc(sizeof(HashTable)); + + if (hashtable == NULL) { + return NULL; + } + hashtable->hash_func = hash_func; hashtable->equal_func = equal_func; hashtable->key_free_func = NULL; @@ -142,7 +149,11 @@ HashTable *hash_table_new(HashTableHashFunc hash_func, /* Allocate the table */ - hash_table_allocate_table(hashtable); + if (!hash_table_allocate_table(hashtable)) { + free(hashtable); + + return NULL; + } return hashtable; } @@ -182,10 +193,11 @@ void hash_table_register_free_functions(HashTable *hashtable, } -static void hash_table_enlarge(HashTable *hashtable) +static int hash_table_enlarge(HashTable *hashtable) { HashTableEntry **old_table; int old_table_size; + int old_prime_index; HashTableEntry *rover; HashTableEntry *next; int index; @@ -195,11 +207,22 @@ static void hash_table_enlarge(HashTable *hashtable) old_table = hashtable->table; old_table_size = hashtable->table_size; + old_prime_index = hashtable->prime_index; /* Allocate a new, larger table */ ++hashtable->prime_index; - hash_table_allocate_table(hashtable); + + if (!hash_table_allocate_table(hashtable)) { + + /* Failed to allocate the new table */ + + hashtable->table = old_table; + hashtable->table_size = old_table_size; + hashtable->prime_index = old_prime_index; + + return 0; + } /* Link all entries from all chains into the new table */ @@ -222,10 +245,12 @@ static void hash_table_enlarge(HashTable *hashtable) rover = next; } - } + } + + return 1; } -void hash_table_insert(HashTable *hashtable, void *key, void *value) +int hash_table_insert(HashTable *hashtable, void *key, void *value) { HashTableEntry *rover; HashTableEntry *newentry; @@ -239,7 +264,12 @@ void hash_table_insert(HashTable *hashtable, void *key, void *value) /* Table is more than 1/3 full */ - hash_table_enlarge(hashtable); + if (!hash_table_enlarge(hashtable)) { + + /* Failed to enlarge the table */ + + return 0; + } } /* Generate the hash of the key and hence the index into the table */ @@ -263,8 +293,8 @@ void hash_table_insert(HashTable *hashtable, void *key, void *value) hashtable->value_free_func(rover->value); } - /* Same with the key: use the new key value and free the - * old one */ + /* Same with the key: use the new key value and free + * the old one */ if (hashtable->key_free_func != NULL) { hashtable->key_free_func(rover->key); @@ -275,7 +305,7 @@ void hash_table_insert(HashTable *hashtable, void *key, void *value) /* Finished */ - return; + return 1; } rover = rover->next; } @@ -284,6 +314,10 @@ void hash_table_insert(HashTable *hashtable, void *key, void *value) newentry = (HashTableEntry *) malloc(sizeof(HashTableEntry)); + if (newentry == NULL) { + return 0; + } + newentry->key = key; newentry->value = value; @@ -295,6 +329,10 @@ void hash_table_insert(HashTable *hashtable, void *key, void *value) /* Maintain the count of the number of entries */ ++hashtable->entries; + + /* Added successfully */ + + return 1; } void *hash_table_lookup(HashTable *hashtable, void *key) @@ -389,6 +427,11 @@ HashTableIterator *hash_table_iterate(HashTable *hashtable) int chain; iterator = (HashTableIterator *) malloc(sizeof(HashTableIterator)); + + if (iterator == NULL) { + return NULL; + } + iterator->hashtable = hashtable; iterator->current_entry = NULL; diff --git a/src/hashtable.h b/src/hashtable.h index 04ffdd4..c70e632 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -104,7 +104,9 @@ typedef void (*HashTableFreeFunc)(void *data); * keys used in the table. * @param equal_func Function used to test keys used in the table * for equality. - * @return A new hash table structure. + * @return A new hash table structure, or NULL if it + * was not possible to allocate the new hash + * table. */ HashTable *hash_table_new(HashTableHashFunc hash_func, @@ -138,9 +140,12 @@ void hash_table_register_free_functions(HashTable *hashtable, * @param hashtable The hash table. * @param key The key for the new value. * @param value The value to insert. + * @return Non-zero if the value was added successfully, + * or zero if it was not possible to allocate + * memory for the new entry. */ -void hash_table_insert(HashTable *hashtable, void *key, void *value); +int hash_table_insert(HashTable *hashtable, void *key, void *value); /** * Look up a value in a hash table by key. @@ -180,7 +185,9 @@ int hash_table_num_entries(HashTable *hashtable); * * @param hashtable The hash table. * @return A pointer to a new @ref HashTableIterator - * to iterate over the hash table. + * to iterate over the hash table, or NULL + * if it was not possible to allocate the + * memory. */ HashTableIterator *hash_table_iterate(HashTable *hashtable); diff --git a/src/list.c b/src/list.c index 06049b2..f71f85d 100644 --- a/src/list.c +++ b/src/list.c @@ -80,6 +80,11 @@ ListEntry *list_prepend(ListEntry **list, void *data) /* Create new entry */ newentry = malloc(sizeof(ListEntry)); + + if (newentry == NULL) { + return NULL; + } + newentry->data = data; /* Hook into the list start */ @@ -102,6 +107,11 @@ ListEntry *list_append(ListEntry **list, void *data) /* Create new list entry */ newentry = malloc(sizeof(ListEntry)); + + if (newentry == NULL) { + return NULL; + } + newentry->data = data; newentry->next = NULL; @@ -220,6 +230,10 @@ void **list_to_array(ListEntry *list) listlen = list_length(list); array = malloc(sizeof(void *) * listlen); + + if (array == NULL) { + return NULL; + } /* Add all entries to the array */ diff --git a/src/list.h b/src/list.h index 4f0ce73..e716e65 100644 --- a/src/list.h +++ b/src/list.h @@ -108,7 +108,7 @@ typedef int (*ListEqualFunc)(void *data1, void *data2); /** * Free an entire list. * - * @param list The list to free. + * @param list The list to free. */ void list_free(ListEntry *list); @@ -116,9 +116,10 @@ void list_free(ListEntry *list); /** * Prepend data to the start of a list. * - * @param list Pointer to the list to prepend to. - * @param data Data to prepend. - * @return The new entry in the list. + * @param list Pointer to the list to prepend to. + * @param data Data to prepend. + * @return The new entry in the list, or NULL if it was not possible + * to allocate the memory for the new entry. */ ListEntry *list_prepend(ListEntry **list, void *data); @@ -126,9 +127,10 @@ ListEntry *list_prepend(ListEntry **list, void *data); /** * Append data to the end of a list. * - * @param list Pointer to the list to append to. - * @param data Data to append. - * @return The new entry in the list. + * @param list Pointer to the list to append to. + * @param data Data to append. + * @return The new entry in the list, or NULL if it was not possible + * to allocate the memory for the new entry. */ ListEntry *list_append(ListEntry **list, void *data); @@ -197,7 +199,8 @@ int list_length(ListEntry *list); * * @param list The list. * @return A newly-allocated C array containing all values in the - * list. The length of the array is equal to the length + * list, or NULL if it was not possible to allocate the + * memory. The length of the array is equal to the length * of the list (see @ref list_length). */ @@ -256,7 +259,8 @@ ListEntry *list_find_data(ListEntry *list, * the function @ref list_iter_free. * * @param list A pointer to the list to iterate over. - * @return A new iterator. + * @return A new iterator, or NULL if it was not possible + * to allocate the memory for the iterator. */ ListIterator *list_iterate(ListEntry **list); @@ -266,10 +270,10 @@ ListIterator *list_iterate(ListEntry **list); * iteration is finished, the iterator should be freed using * @ref list_iter_free. * - * @param iterator The list iterator. - * @return Zero if there are no more values in the list to - * iterate over, non-zero if there are more values to - * read. + * @param iterator The list iterator. + * @return Zero if there are no more values in the list to + * iterate over, non-zero if there are more values to + * read. */ int list_iter_has_more(ListIterator *iter); @@ -277,9 +281,9 @@ int list_iter_has_more(ListIterator *iter); /** * Using a list iterator, retrieve the next value from the list. * - * @param iterator The list iterator. - * @return The next value from the list, or NULL if there are - * no more values in the list. + * @param iterator The list iterator. + * @return The next value from the list, or NULL if there are + * no more values in the list. */ void *list_iter_next(ListIterator *iter); @@ -288,7 +292,7 @@ void *list_iter_next(ListIterator *iter); * Delete the current entry in the list (the value last returned from * list_iter_next) * - * @param iterator The list iterator. + * @param iterator The list iterator. */ void list_iter_remove(ListIterator *iter); @@ -296,7 +300,7 @@ void list_iter_remove(ListIterator *iter); /** * Free back a list iterator. * - * @param iterator The list iterator. + * @param iterator The list iterator. */ void list_iter_free(ListIterator *iter); diff --git a/src/queue.c b/src/queue.c index c0b58b7..5faa611 100644 --- a/src/queue.c +++ b/src/queue.c @@ -57,6 +57,10 @@ Queue *queue_new(void) Queue *queue; queue = (Queue *) malloc(sizeof(Queue)); + + if (queue == NULL) { + return NULL; + } queue->head = NULL; queue->tail = NULL; @@ -77,13 +81,18 @@ void queue_free(Queue *queue) free(queue); } -void queue_push_head(Queue *queue, void *data) +int queue_push_head(Queue *queue, void *data) { QueueEntry *new_entry; /* Create the new entry and fill in the fields in the structure */ new_entry = malloc(sizeof(QueueEntry)); + + if (new_entry == NULL) { + return 0; + } + new_entry->data = data; new_entry->prev = NULL; new_entry->next = queue->head; @@ -109,6 +118,8 @@ void queue_push_head(Queue *queue, void *data) queue->head = new_entry; } + + return 1; } void *queue_pop_head(Queue *queue) @@ -157,13 +168,18 @@ void *queue_peek_head(Queue *queue) } } -void queue_push_tail(Queue *queue, void *data) +int queue_push_tail(Queue *queue, void *data) { QueueEntry *new_entry; /* Create the new entry and fill in the fields in the structure */ new_entry = malloc(sizeof(QueueEntry)); + + if (new_entry == NULL) { + return 0; + } + new_entry->data = data; new_entry->prev = queue->tail; new_entry->next = NULL; @@ -189,6 +205,8 @@ void queue_push_tail(Queue *queue, void *data) queue->tail = new_entry; } + + return 1; } void *queue_pop_tail(Queue *queue) diff --git a/src/queue.h b/src/queue.h index 5b3bc9a..86eda52 100644 --- a/src/queue.h +++ b/src/queue.h @@ -70,7 +70,8 @@ typedef struct _Queue Queue; /** * Create a new double-ended queue. * - * @return A new queue. + * @return A new queue, or NULL if it was not possible to allocate + * the memory. */ Queue *queue_new(void); @@ -88,9 +89,12 @@ void queue_free(Queue *queue); * * @param queue The queue. * @param data The data to add. + * @return Non-zero if the value was added successfully, or zero + * if it was not possible to allocate the memory for the + * new entry. */ -void queue_push_head(Queue *queue, void *data); +int queue_push_head(Queue *queue, void *data); /** * Remove data from the head of a queue. @@ -118,9 +122,12 @@ void *queue_peek_head(Queue *queue); * * @param queue The queue. * @param data The data to add. + * @return Non-zero if the value was added successfully, or zero + * if it was not possible to allocate the memory for the + * new entry. */ -void queue_push_tail(Queue *queue, void *data); +int queue_push_tail(Queue *queue, void *data); /** * Remove data from the tail of a queue. diff --git a/src/set.c b/src/set.c index 1d13988..da07d8d 100644 --- a/src/set.c +++ b/src/set.c @@ -77,7 +77,7 @@ static const unsigned int set_primes[] = { static const int set_num_primes = sizeof(set_primes) / sizeof(int); -static void set_allocate_table(Set *set) +static int set_allocate_table(Set *set) { /* Determine the table size based on the current prime index. * An attempt is made here to ensure sensible behavior if the @@ -93,6 +93,8 @@ static void set_allocate_table(Set *set) /* Allocate the table and initialise to NULL */ set->table = calloc(set->table_size, sizeof(SetEntry *)); + + return set->table != NULL; } static void set_free_entry(Set *set, SetEntry *entry) @@ -116,6 +118,11 @@ Set *set_new(SetHashFunc hash_func, SetEqualFunc equal_func) /* Allocate a new set and fill in the fields */ new_set = (Set *) malloc(sizeof(Set)); + + if (new_set == NULL) { + return NULL; + } + new_set->hash_func = hash_func; new_set->equal_func = equal_func; new_set->entries = 0; @@ -124,7 +131,10 @@ Set *set_new(SetHashFunc hash_func, SetEqualFunc equal_func) /* Allocate the table */ - set_allocate_table(new_set); + if (!set_allocate_table(new_set)) { + free(new_set); + return NULL; + } return new_set; } @@ -167,12 +177,13 @@ void set_register_free_function(Set *set, SetFreeFunc free_func) set->free_func = free_func; } -static void set_enlarge(Set *set) +static int set_enlarge(Set *set) { SetEntry *rover; SetEntry *next; SetEntry **old_table; int old_table_size; + int old_prime_index; int index; int i; @@ -180,6 +191,7 @@ static void set_enlarge(Set *set) old_table = set->table; old_table_size = set->table_size; + old_prime_index = set->prime_index; /* Use the next table size from the prime number array */ @@ -187,7 +199,13 @@ static void set_enlarge(Set *set) /* Allocate the new table */ - set_allocate_table(set); + if (!set_allocate_table(set)) { + set->table = old_table; + set->table_size = old_table_size; + set->prime_index = old_prime_index; + + return 0; + } /* Iterate through all entries in the old table and add them * to the new one */ @@ -217,6 +235,10 @@ static void set_enlarge(Set *set) /* Free back the old table */ free(old_table); + + /* Resized successfully */ + + return 1; } int set_insert(Set *set, void *data) @@ -232,7 +254,9 @@ int set_insert(Set *set, void *data) /* The table is more than 1/3 full and must be increased in size */ - set_enlarge(set); + if (!set_enlarge(set)) { + return 0; + } } /* Use the hash of the data to determine an index to insert into the @@ -262,6 +286,11 @@ int set_insert(Set *set, void *data) /* Make a new entry for this data */ newentry = (SetEntry *) malloc(sizeof(SetEntry)); + + if (newentry == NULL) { + return 0; + } + newentry->data = data; /* Link into chain */ @@ -370,6 +399,11 @@ void **set_to_array(Set *set) /* Create an array to hold the set entries */ array = malloc(sizeof(void *) * set->entries); + + if (array == NULL) { + return NULL; + } + array_counter = 0; /* Iterate over all entries in all chains */ @@ -394,15 +428,18 @@ void **set_to_array(Set *set) return array; } -Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func) +Set *set_union(Set *set1, Set *set2) { SetIterator *iterator; Set *new_set; void *value; - void *copied_value; new_set = set_new(set1->hash_func, set1->equal_func); + if (new_set == NULL) { + return NULL; + } + /* Add all values from the first set */ iterator = set_iterate(set1); @@ -413,15 +450,15 @@ Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func) value = set_iter_next(iterator); - /* Copy the value into the new set, copying if necessary */ + /* Copy the value into the new set */ - if (copy_func != NULL) { - copied_value = copy_func(value); - } else { - copied_value = value; - } + if (!set_insert(new_set, value)) { - set_insert(new_set, copied_value); + /* Failed to insert */ + + set_free(new_set); + return NULL; + } } set_iter_free(iterator); @@ -440,17 +477,13 @@ Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func) * If so, do not insert this again */ if (set_query(new_set, value) == 0) { + if (!set_insert(new_set, value)) { - /* Insert the value into the new set, copying - * if necessary */ - - if (copy_func != NULL) { - copied_value = copy_func(value); - } else { - copied_value = value; - } + /* Failed to insert */ - set_insert(new_set, copied_value); + set_free(new_set); + return NULL; + } } } @@ -459,16 +492,18 @@ Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func) return new_set; } -Set *set_intersection(Set *set1, Set *set2, - SetCopyFunc copy_func) +Set *set_intersection(Set *set1, Set *set2) { Set *new_set; SetIterator *iterator; void *value; - void *copied_value; new_set = set_new(set1->hash_func, set2->equal_func); + if (new_set == NULL) { + return NULL; + } + /* Iterate over all values in set 1. */ iterator = set_iterate(set1); @@ -487,13 +522,11 @@ Set *set_intersection(Set *set1, Set *set2, /* Copy the value first before inserting, * if necessary */ - if (copy_func != NULL) { - copied_value = copy_func(value); - } else { - copied_value = value; - } + if (!set_insert(new_set, value)) { + set_free(new_set); - set_insert(new_set, copied_value); + return NULL; + } } } @@ -511,6 +544,10 @@ SetIterator *set_iterate(Set *set) iter = malloc(sizeof(SetIterator)); + if (iter == NULL) { + return NULL; + } + iter->set = set; iter->current_entry = NULL; iter->next_entry = NULL; diff --git a/src/set.h b/src/set.h index c07d110..e19f561 100644 --- a/src/set.h +++ b/src/set.h @@ -92,13 +92,6 @@ typedef unsigned long (*SetHashFunc)(void *data); typedef int (*SetEqualFunc)(void *data1, void *data2); -/** - * Copy function. Given a pointer to some data, return a - * copy of it. Used by @ref set_intersection and @ref set_union. - */ - -typedef void *(*SetCopyFunc)(void *data); - /** * Function used to free values stored in a set. See * @ref set_register_free_function. @@ -112,7 +105,8 @@ typedef void (*SetFreeFunc)(void *data); * @param hash_func Hash function used on data in the set . * @param equal_func Compares two values in the set to determine * if they are equal. - * @return A new set. + * @return A new set, or NULL if it was not possible to + * allocate the memory for the set. */ Set *set_new(SetHashFunc hash_func, SetEqualFunc equal_func); @@ -142,7 +136,9 @@ void set_register_free_function(Set *set, SetFreeFunc free_func); * @param set The set. * @param data The data to add to the set . * @return Non-zero (true) if the value was added to the set, - * zero (false) if it already exists in the set. + * zero (false) if it already exists in the set, or + * if it was not possible to allocate memory for the + * new entry. */ int set_insert(Set *set, void *data); @@ -193,33 +189,24 @@ void **set_to_array(Set *set); * * @param set1 The first set. * @param set2 The second set. - * @param copy_func Pointer to a function to use to copy data. - * When values are inserted into the new set, they - * are first copied using the copy function. - * If NULL is passed, no copying is performed and - * the reference from the first set is added. * @return A new set containing all values which are in the - * first or second sets. + * first or second sets, or NULL if it was not + * possible to allocate memory for the new set. */ -Set *set_union(Set *set1, Set *set2, SetCopyFunc copy_func); +Set *set_union(Set *set1, Set *set2); /** * Perform an intersection of two sets. * * @param set1 The first set. * @param set2 The second set. - * @param copy_func Pointer to a function to use to copy data. - * When values are inserted into the new set, they - * are first copied using the copy function. - * If NULL is passed, no copying is performed and - * the reference from the first set is added. * @return A new set containing all values which are in both - * sets. + * set, or NULL if it was not possible to allocate + * memory for the new set. */ -Set *set_intersection(Set *set1, Set *set2, - SetCopyFunc copy_func); +Set *set_intersection(Set *set1, Set *set2); /** * Create an iterator to iterate over the values in a set. diff --git a/src/slist.c b/src/slist.c index b66c190..d627cd7 100644 --- a/src/slist.c +++ b/src/slist.c @@ -71,6 +71,11 @@ SListEntry *slist_prepend(SListEntry **list, void *data) /* Create new entry */ newentry = malloc(sizeof(SListEntry)); + + if (newentry == NULL) { + return NULL; + } + newentry->data = data; /* Hook into the list start */ @@ -89,6 +94,11 @@ SListEntry *slist_append(SListEntry **list, void *data) /* Create new list entry */ newentry = malloc(sizeof(SListEntry)); + + if (newentry == NULL) { + return NULL; + } + newentry->data = data; newentry->next = NULL; @@ -199,7 +209,11 @@ void **slist_to_array(SListEntry *list) listlen = slist_length(list); - array = calloc(sizeof(void *), listlen); + array = malloc(sizeof(void *) * listlen); + + if (array == NULL) { + return NULL; + } /* Add all entries to the array */ diff --git a/src/slist.h b/src/slist.h index 516358e..1ace58a 100644 --- a/src/slist.h +++ b/src/slist.h @@ -125,7 +125,8 @@ void slist_free(SListEntry *list); * * @param list Pointer to the list to prepend to. * @param data Data to prepend. - * @return The new entry in the list. + * @return The new entry in the list, or NULL if it was not possible + * to allocate a new entry. */ SListEntry *slist_prepend(SListEntry **list, void *data); @@ -135,7 +136,8 @@ SListEntry *slist_prepend(SListEntry **list, void *data); * * @param list Pointer to the list to append to. * @param data Data to append. - * @return The new entry in the list. + * @return The new entry in the list, or NULL if it was not possible + * to allocate a new entry. */ SListEntry *slist_append(SListEntry **list, void *data); @@ -193,8 +195,9 @@ int slist_length(SListEntry *list); * * @param list The list. * @return A newly-allocated C array containing all values in the - * list. The length of the array is equal to the length - * of the list (see @ref slist_length). + * list, or NULL if it was not possible to allocate the + * memory for the array. The length of the array is + * equal to the length of the list (see @ref slist_length). */ void **slist_to_array(SListEntry *list); diff --git a/src/trie.c b/src/trie.c index 7e95c92..e1825ca 100644 --- a/src/trie.c +++ b/src/trie.c @@ -75,6 +75,11 @@ Trie *trie_new(void) Trie *new_trie; new_trie = (Trie *) malloc(sizeof(Trie)); + + if (new_trie == NULL) { + return NULL; + } + new_trie->root_node = NULL; return new_trie; @@ -91,7 +96,7 @@ void trie_free(Trie *trie) free(trie); } -void trie_insert(Trie *trie, char *key, void *value) +int trie_insert(Trie *trie, char *key, void *value) { TrieNode **rover; TrieNode *node; @@ -101,7 +106,7 @@ void trie_insert(Trie *trie, char *key, void *value) /* Cannot insert NULL values */ if (value == NULL) { - return; + return 0; } /* Search down the trie until we reach the end of string, @@ -120,6 +125,10 @@ void trie_insert(Trie *trie, char *key, void *value) node = (TrieNode *) calloc(1, sizeof(TrieNode)); + if (node == NULL) { + return 0; + } + /* Link in to the trie */ *rover = node; @@ -149,6 +158,8 @@ void trie_insert(Trie *trie, char *key, void *value) rover = &node->next[c]; ++p; } + + return 1; } void trie_remove(Trie *trie, char *key) diff --git a/src/trie.h b/src/trie.h index 787aa15..5b3d878 100644 --- a/src/trie.h +++ b/src/trie.h @@ -64,7 +64,9 @@ typedef struct _Trie Trie; /** * Create a new trie. * - * @return Pointer to a new trie structure. + * @return Pointer to a new trie structure, or NULL if it + * was not possible to allocate memory for the + * new trie. */ Trie *trie_new(void); @@ -83,9 +85,12 @@ void trie_free(Trie *trie); * @param trie The trie. * @param key The key to access the new value. * @param value The value. + * @return Non-zero if the value was inserted successfully, + * or zero if it was not possible to allocate + * memory for the new entry. */ -void trie_insert(Trie *trie, char *key, void *value); +int trie_insert(Trie *trie, char *key, void *value); /** * Look up a value from its key in a trie. diff --git a/test/test-set.c b/test/test-set.c index 2214cb8..9432990 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -216,7 +216,7 @@ void test_set_union(void) /* Perform the union */ - result_set = set_union(set1, set2, NULL); + result_set = set_union(set1, set2); assert(set_num_entries(result_set) == 11); @@ -253,7 +253,7 @@ void test_set_intersection(void) /* Perform the intersection */ - result_set = set_intersection(set1, set2, NULL); + result_set = set_intersection(set1, set2); assert(set_num_entries(result_set) == 3); From d630a2748e08213131728f4eeb299d91266abf7a Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 27 Oct 2006 19:57:06 +0000 Subject: [PATCH 017/250] Smart indent all source code. --- src/arraylist.c | 34 ++++----- src/avltree.c | 24 +++---- src/binary-heap.c | 60 ++++++++-------- src/hashtable.c | 72 +++++++++---------- src/list.c | 150 ++++++++++++++++++++-------------------- src/queue.c | 26 +++---- src/set.c | 108 ++++++++++++++--------------- src/slist.c | 22 +++--- src/trie.c | 16 ++--- test/test-binary-heap.c | 114 +++++++++++++++--------------- test/test-list.c | 36 +++++----- test/test-set.c | 44 ++++++------ 12 files changed, 353 insertions(+), 353 deletions(-) diff --git a/src/arraylist.c b/src/arraylist.c index 8d72d6f..bef16ef 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -55,10 +55,10 @@ ArrayList *arraylist_new(int length) new_arraylist = (ArrayList *) malloc(sizeof(ArrayList)); - if (new_arraylist == NULL) { - return NULL; - } - + if (new_arraylist == NULL) { + return NULL; + } + new_arraylist->_alloced = length; new_arraylist->length = 0; @@ -66,10 +66,10 @@ ArrayList *arraylist_new(int length) new_arraylist->data = malloc(length * sizeof(void *)); - if (new_arraylist->data == NULL) { - free(new_arraylist); - return NULL; - } + if (new_arraylist->data == NULL) { + free(new_arraylist); + return NULL; + } return new_arraylist; } @@ -86,7 +86,7 @@ void arraylist_free(ArrayList *arraylist) static int arraylist_enlarge(ArrayList *arraylist) { - void **data; + void **data; /* Double the allocated size */ @@ -97,13 +97,13 @@ static int arraylist_enlarge(ArrayList *arraylist) data = realloc(arraylist->data, sizeof(void *) * arraylist->_alloced); - if (data == NULL) { - return 0; - } else { - arraylist->data = data; + if (data == NULL) { + return 0; + } else { + arraylist->data = data; - return 1; - } + return 1; + } } int arraylist_insert(ArrayList *arraylist, int index, void *data) @@ -118,8 +118,8 @@ int arraylist_insert(ArrayList *arraylist, int index, void *data) if (arraylist->length + 1 > arraylist->_alloced) { if (!arraylist_enlarge(arraylist)) { - return 0; - } + return 0; + } } /* Move the contents of the array forward from the index diff --git a/src/avltree.c b/src/avltree.c index fca921a..39e13e5 100644 --- a/src/avltree.c +++ b/src/avltree.c @@ -60,10 +60,10 @@ AVLTree *avltree_new(AVLTreeCompareFunc compare_func) new_tree = (AVLTree *) malloc(sizeof(AVLTree)); - if (new_tree == NULL) { - return NULL; - } - + if (new_tree == NULL) { + return NULL; + } + new_tree->root_node = NULL; new_tree->compare_func = compare_func; new_tree->num_nodes = 0; @@ -359,10 +359,10 @@ AVLTreeNode *avltree_insert(AVLTree *tree, void *key, void *value) new_node = (AVLTreeNode *) malloc(sizeof(AVLTreeNode)); - if (new_node == NULL) { - return NULL; - } - + if (new_node == NULL) { + return NULL; + } + new_node->left_child = NULL; new_node->right_child = NULL; new_node->parent = previous_node; @@ -688,10 +688,10 @@ void **avltree_to_array(AVLTree *tree) array = malloc(sizeof(void *) * tree->num_nodes); - if (array == NULL) { - return NULL; - } - + if (array == NULL) { + return NULL; + } + index = 0; /* Add all keys */ diff --git a/src/binary-heap.c b/src/binary-heap.c index f632d05..04f4606 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -38,7 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "binary-heap.h" struct _BinaryHeap { - BinaryHeapType heap_type; + BinaryHeapType heap_type; void **values; int num_values; int alloced_size; @@ -47,11 +47,11 @@ struct _BinaryHeap { static int binary_heap_cmp(BinaryHeap *heap, void *data1, void *data2) { - if (heap->heap_type == BINARY_HEAP_TYPE_MIN) { - return heap->compare_func(data1, data2); - } else { - return -heap->compare_func(data1, data2); - } + if (heap->heap_type == BINARY_HEAP_TYPE_MIN) { + return heap->compare_func(data1, data2); + } else { + return -heap->compare_func(data1, data2); + } } BinaryHeap *binary_heap_new(BinaryHeapType heap_type, @@ -61,11 +61,11 @@ BinaryHeap *binary_heap_new(BinaryHeapType heap_type, heap = malloc(sizeof(BinaryHeap)); - if (heap == NULL) { - return NULL; - } - - heap->heap_type = heap_type; + if (heap == NULL) { + return NULL; + } + + heap->heap_type = heap_type; heap->num_values = 0; heap->compare_func = compare_func; @@ -74,23 +74,23 @@ BinaryHeap *binary_heap_new(BinaryHeapType heap_type, heap->alloced_size = 16; heap->values = malloc(sizeof(void *) * heap->alloced_size); - if (heap->values == NULL) { - free(heap); - return NULL; - } + if (heap->values == NULL) { + free(heap); + return NULL; + } return heap; } void binary_heap_free(BinaryHeap *heap) { - free(heap->values); - free(heap); + free(heap->values); + free(heap); } int binary_heap_insert(BinaryHeap *heap, void *value) { - void **new_values; + void **new_values; int index; int parent; @@ -104,11 +104,11 @@ int binary_heap_insert(BinaryHeap *heap, void *value) new_values = realloc(heap->values, sizeof(void *) * heap->alloced_size); - if (new_values == NULL) { - return 0; - } - - heap->values = new_values; + if (new_values == NULL) { + return 0; + } + + heap->values = new_values; } /* Add to the bottom of the heap and start from there */ @@ -148,7 +148,7 @@ int binary_heap_insert(BinaryHeap *heap, void *value) heap->values[index] = value; - return 1; + return 1; } void *binary_heap_pop(BinaryHeap *heap) @@ -188,15 +188,15 @@ void *binary_heap_pop(BinaryHeap *heap) if (child1 < heap->num_values && binary_heap_cmp(heap, - new_value, - heap->values[child1]) > 0) { + new_value, + heap->values[child1]) > 0) { /* Left child is less than the node. We need to swap * with one of the children, whichever is less. */ if (child2 < heap->num_values && binary_heap_cmp(heap, - heap->values[child1], + heap->values[child1], heap->values[child2]) > 0) { next_index = child2; } else { @@ -205,8 +205,8 @@ void *binary_heap_pop(BinaryHeap *heap) } else if (child2 < heap->num_values && binary_heap_cmp(heap, - new_value, - heap->values[child2]) > 0) { + new_value, + heap->values[child2]) > 0) { /* Right child is less than the node. Swap with the * right child. */ @@ -230,7 +230,7 @@ void *binary_heap_pop(BinaryHeap *heap) index = next_index; } - return result; + return result; } int binary_heap_num_entries(BinaryHeap *heap) diff --git a/src/hashtable.c b/src/hashtable.c index d85b5ce..a56d0a0 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -72,14 +72,14 @@ struct _HashTableIterator { * possible from the nearest powers of two. */ static const unsigned int hash_table_primes[] = { - 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, - 196613, 393241, 786433, 1572869, 3145739, 6291469, - 12582917, 25165843, 50331653, 100663319, 201326611, - 402653189, 805306457, 1610612741, + 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, + 196613, 393241, 786433, 1572869, 3145739, 6291469, + 12582917, 25165843, 50331653, 100663319, 201326611, + 402653189, 805306457, 1610612741, }; static const int hash_table_num_primes - = sizeof(hash_table_primes) / sizeof(int); + = sizeof(hash_table_primes) / sizeof(int); /* Internal function used to allocate the table on hashtable creation * and when enlarging the table */ @@ -102,7 +102,7 @@ static int hash_table_allocate_table(HashTable *hashtable) hashtable->table = calloc(hashtable->table_size, sizeof(HashTableEntry *)); - return hashtable->table != NULL; + return hashtable->table != NULL; } /* Free an entry, calling the free functions if there are any registered */ @@ -136,10 +136,10 @@ HashTable *hash_table_new(HashTableHashFunc hash_func, hashtable = (HashTable *) malloc(sizeof(HashTable)); - if (hashtable == NULL) { - return NULL; - } - + if (hashtable == NULL) { + return NULL; + } + hashtable->hash_func = hash_func; hashtable->equal_func = equal_func; hashtable->key_free_func = NULL; @@ -150,10 +150,10 @@ HashTable *hash_table_new(HashTableHashFunc hash_func, /* Allocate the table */ if (!hash_table_allocate_table(hashtable)) { - free(hashtable); + free(hashtable); - return NULL; - } + return NULL; + } return hashtable; } @@ -197,7 +197,7 @@ static int hash_table_enlarge(HashTable *hashtable) { HashTableEntry **old_table; int old_table_size; - int old_prime_index; + int old_prime_index; HashTableEntry *rover; HashTableEntry *next; int index; @@ -207,22 +207,22 @@ static int hash_table_enlarge(HashTable *hashtable) old_table = hashtable->table; old_table_size = hashtable->table_size; - old_prime_index = hashtable->prime_index; + old_prime_index = hashtable->prime_index; /* Allocate a new, larger table */ ++hashtable->prime_index; - + if (!hash_table_allocate_table(hashtable)) { - /* Failed to allocate the new table */ + /* Failed to allocate the new table */ - hashtable->table = old_table; - hashtable->table_size = old_table_size; - hashtable->prime_index = old_prime_index; + hashtable->table = old_table; + hashtable->table_size = old_table_size; + hashtable->prime_index = old_prime_index; - return 0; - } + return 0; + } /* Link all entries from all chains into the new table */ @@ -247,7 +247,7 @@ static int hash_table_enlarge(HashTable *hashtable) } } - return 1; + return 1; } int hash_table_insert(HashTable *hashtable, void *key, void *value) @@ -266,10 +266,10 @@ int hash_table_insert(HashTable *hashtable, void *key, void *value) if (!hash_table_enlarge(hashtable)) { - /* Failed to enlarge the table */ + /* Failed to enlarge the table */ - return 0; - } + return 0; + } } /* Generate the hash of the key and hence the index into the table */ @@ -294,7 +294,7 @@ int hash_table_insert(HashTable *hashtable, void *key, void *value) } /* Same with the key: use the new key value and free - * the old one */ + * the old one */ if (hashtable->key_free_func != NULL) { hashtable->key_free_func(rover->key); @@ -314,9 +314,9 @@ int hash_table_insert(HashTable *hashtable, void *key, void *value) newentry = (HashTableEntry *) malloc(sizeof(HashTableEntry)); - if (newentry == NULL) { - return 0; - } + if (newentry == NULL) { + return 0; + } newentry->key = key; newentry->value = value; @@ -330,9 +330,9 @@ int hash_table_insert(HashTable *hashtable, void *key, void *value) ++hashtable->entries; - /* Added successfully */ + /* Added successfully */ - return 1; + return 1; } void *hash_table_lookup(HashTable *hashtable, void *key) @@ -428,10 +428,10 @@ HashTableIterator *hash_table_iterate(HashTable *hashtable) iterator = (HashTableIterator *) malloc(sizeof(HashTableIterator)); - if (iterator == NULL) { - return NULL; - } - + if (iterator == NULL) { + return NULL; + } + iterator->hashtable = hashtable; iterator->current_entry = NULL; diff --git a/src/list.c b/src/list.c index f71f85d..4a31320 100644 --- a/src/list.c +++ b/src/list.c @@ -48,9 +48,9 @@ struct _ListEntry { /* Iterator for iterating over a doubly-linked list. */ struct _ListIterator { - ListEntry **list; - ListEntry **prev_next; - ListEntry *current; + ListEntry **list; + ListEntry **prev_next; + ListEntry *current; }; void list_free(ListEntry *list) @@ -81,10 +81,10 @@ ListEntry *list_prepend(ListEntry **list, void *data) newentry = malloc(sizeof(ListEntry)); - if (newentry == NULL) { - return NULL; - } - + if (newentry == NULL) { + return NULL; + } + newentry->data = data; /* Hook into the list start */ @@ -108,10 +108,10 @@ ListEntry *list_append(ListEntry **list, void *data) newentry = malloc(sizeof(ListEntry)); - if (newentry == NULL) { - return NULL; - } - + if (newentry == NULL) { + return NULL; + } + newentry->data = data; newentry->next = NULL; @@ -231,9 +231,9 @@ void **list_to_array(ListEntry *list) array = malloc(sizeof(void *) * listlen); - if (array == NULL) { - return NULL; - } + if (array == NULL) { + return NULL; + } /* Add all entries to the array */ @@ -280,7 +280,7 @@ int list_remove_entry(ListEntry **list, ListEntry *entry) /* This is not the first in the list, so we must have a * previous entry. Update its 'next' pointer to the new - * value */ + * value */ entry->prev->next = entry->next; @@ -320,7 +320,7 @@ int list_remove_data(ListEntry **list, ListEqualFunc callback, void *data) if (callback(rover->data, data)) { /* This data needs to be removed. Unlink this entry - * from the list. */ + * from the list. */ if (rover->prev == NULL) { @@ -330,7 +330,7 @@ int list_remove_data(ListEntry **list, ListEqualFunc callback, void *data) } else { /* Point the previous entry at its new - * location */ + * location */ rover->prev->next = rover->next; } @@ -477,102 +477,102 @@ ListEntry *list_find_data(ListEntry *list, ListIterator *list_iterate(ListEntry **list) { - ListIterator *iter; + ListIterator *iter; - /* Create a new iterator */ + /* Create a new iterator */ - iter = malloc(sizeof(ListIterator)); + iter = malloc(sizeof(ListIterator)); - if (iter == NULL) { - return NULL; - } + if (iter == NULL) { + return NULL; + } - /* Save pointer to the list */ - - iter->list = list; + /* Save pointer to the list */ + + iter->list = list; - /* These are NULL until the first call to list_iter_next: */ + /* These are NULL until the first call to list_iter_next: */ - iter->prev_next = NULL; - iter->current = NULL; + iter->prev_next = NULL; + iter->current = NULL; - return iter; + return iter; } int list_iter_has_more(ListIterator *iter) { - if (iter->prev_next == NULL) { - - /* The list has just been created. list_iter_next - * has not been called yet. There are more entries - * if the list is not empty. */ - - return *iter->list != NULL; + if (iter->prev_next == NULL) { + + /* The list has just been created. list_iter_next + * has not been called yet. There are more entries + * if the list is not empty. */ + + return *iter->list != NULL; - } else if (*iter->prev_next != iter->current) { + } else if (*iter->prev_next != iter->current) { - /* Current entry has been deleted since the last call - * to list_iter_next. Use prev_next as an indicator - * of the next entry. */ + /* Current entry has been deleted since the last call + * to list_iter_next. Use prev_next as an indicator + * of the next entry. */ - return *iter->prev_next != NULL; + return *iter->prev_next != NULL; - } else { - /* The current entry as not been deleted since the last - * call to list_iter_next: there is a next entry if - * current->next is not NULL */ + } else { + /* The current entry as not been deleted since the last + * call to list_iter_next: there is a next entry if + * current->next is not NULL */ - return iter->current->next != NULL; - } + return iter->current->next != NULL; + } } void *list_iter_next(ListIterator *iter) { - if (iter->prev_next == NULL) { - /* First call to list_iter_next. Initialise. */ + if (iter->prev_next == NULL) { + /* First call to list_iter_next. Initialise. */ - /* Initial previous next link is the pointer to the list - * start variable */ + /* Initial previous next link is the pointer to the list + * start variable */ - iter->prev_next = iter->list; + iter->prev_next = iter->list; - /* Start at the first element */ + /* Start at the first element */ - iter->current = *iter->list; + iter->current = *iter->list; - } else if (*iter->prev_next != iter->current) { + } else if (*iter->prev_next != iter->current) { - /* The current value has been deleted since the last call - * to list_iter_next. Use what prev_next is pointing to - * now as the next entry. */ + /* The current value has been deleted since the last call + * to list_iter_next. Use what prev_next is pointing to + * now as the next entry. */ - iter->current = *iter->prev_next; + iter->current = *iter->prev_next; - } else { + } else { - /* Current entry has not been deleted since the last call - * to list_iter_next. Simply advance to the next entry - * in the list. */ + /* Current entry has not been deleted since the last call + * to list_iter_next. Simply advance to the next entry + * in the list. */ - if (iter->current != NULL) { - iter->prev_next = &iter->current->next; - iter->current = iter->current->next; - } - - } - - /* Return data from the current entry */ + if (iter->current != NULL) { + iter->prev_next = &iter->current->next; + iter->current = iter->current->next; + } + + } + + /* Return data from the current entry */ - return iter->current->data; + return iter->current->data; } void list_iter_remove(ListIterator *iter) { - list_remove_entry(iter->list, iter->current); + list_remove_entry(iter->list, iter->current); } void list_iter_free(ListIterator *iter) { - free(iter); + free(iter); } diff --git a/src/queue.c b/src/queue.c index 5faa611..1b70dc2 100644 --- a/src/queue.c +++ b/src/queue.c @@ -58,9 +58,9 @@ Queue *queue_new(void) queue = (Queue *) malloc(sizeof(Queue)); - if (queue == NULL) { - return NULL; - } + if (queue == NULL) { + return NULL; + } queue->head = NULL; queue->tail = NULL; @@ -89,10 +89,10 @@ int queue_push_head(Queue *queue, void *data) new_entry = malloc(sizeof(QueueEntry)); - if (new_entry == NULL) { - return 0; - } - + if (new_entry == NULL) { + return 0; + } + new_entry->data = data; new_entry->prev = NULL; new_entry->next = queue->head; @@ -119,7 +119,7 @@ int queue_push_head(Queue *queue, void *data) queue->head = new_entry; } - return 1; + return 1; } void *queue_pop_head(Queue *queue) @@ -176,10 +176,10 @@ int queue_push_tail(Queue *queue, void *data) new_entry = malloc(sizeof(QueueEntry)); - if (new_entry == NULL) { - return 0; - } - + if (new_entry == NULL) { + return 0; + } + new_entry->data = data; new_entry->prev = queue->tail; new_entry->next = NULL; @@ -206,7 +206,7 @@ int queue_push_tail(Queue *queue, void *data) queue->tail = new_entry; } - return 1; + return 1; } void *queue_pop_tail(Queue *queue) diff --git a/src/set.c b/src/set.c index da07d8d..2b30e6b 100644 --- a/src/set.c +++ b/src/set.c @@ -69,10 +69,10 @@ struct _SetIterator { * possible from the nearest powers of two. */ static const unsigned int set_primes[] = { - 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, - 196613, 393241, 786433, 1572869, 3145739, 6291469, - 12582917, 25165843, 50331653, 100663319, 201326611, - 402653189, 805306457, 1610612741, + 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, + 196613, 393241, 786433, 1572869, 3145739, 6291469, + 12582917, 25165843, 50331653, 100663319, 201326611, + 402653189, 805306457, 1610612741, }; static const int set_num_primes = sizeof(set_primes) / sizeof(int); @@ -94,7 +94,7 @@ static int set_allocate_table(Set *set) set->table = calloc(set->table_size, sizeof(SetEntry *)); - return set->table != NULL; + return set->table != NULL; } static void set_free_entry(Set *set, SetEntry *entry) @@ -119,10 +119,10 @@ Set *set_new(SetHashFunc hash_func, SetEqualFunc equal_func) new_set = (Set *) malloc(sizeof(Set)); - if (new_set == NULL) { - return NULL; - } - + if (new_set == NULL) { + return NULL; + } + new_set->hash_func = hash_func; new_set->equal_func = equal_func; new_set->entries = 0; @@ -132,9 +132,9 @@ Set *set_new(SetHashFunc hash_func, SetEqualFunc equal_func) /* Allocate the table */ if (!set_allocate_table(new_set)) { - free(new_set); - return NULL; - } + free(new_set); + return NULL; + } return new_set; } @@ -183,7 +183,7 @@ static int set_enlarge(Set *set) SetEntry *next; SetEntry **old_table; int old_table_size; - int old_prime_index; + int old_prime_index; int index; int i; @@ -191,7 +191,7 @@ static int set_enlarge(Set *set) old_table = set->table; old_table_size = set->table_size; - old_prime_index = set->prime_index; + old_prime_index = set->prime_index; /* Use the next table size from the prime number array */ @@ -200,12 +200,12 @@ static int set_enlarge(Set *set) /* Allocate the new table */ if (!set_allocate_table(set)) { - set->table = old_table; - set->table_size = old_table_size; - set->prime_index = old_prime_index; + set->table = old_table; + set->table_size = old_table_size; + set->prime_index = old_prime_index; - return 0; - } + return 0; + } /* Iterate through all entries in the old table and add them * to the new one */ @@ -236,9 +236,9 @@ static int set_enlarge(Set *set) free(old_table); - /* Resized successfully */ + /* Resized successfully */ - return 1; + return 1; } int set_insert(Set *set, void *data) @@ -255,8 +255,8 @@ int set_insert(Set *set, void *data) /* The table is more than 1/3 full and must be increased in size */ if (!set_enlarge(set)) { - return 0; - } + return 0; + } } /* Use the hash of the data to determine an index to insert into the @@ -287,10 +287,10 @@ int set_insert(Set *set, void *data) newentry = (SetEntry *) malloc(sizeof(SetEntry)); - if (newentry == NULL) { - return 0; - } - + if (newentry == NULL) { + return 0; + } + newentry->data = data; /* Link into chain */ @@ -343,9 +343,9 @@ int set_remove(Set *set, void *data) return 1; } - /* Advance to the next entry */ + /* Advance to the next entry */ - rover = &((*rover)->next); + rover = &((*rover)->next); } /* Not found in set */ @@ -400,10 +400,10 @@ void **set_to_array(Set *set) array = malloc(sizeof(void *) * set->entries); - if (array == NULL) { - return NULL; - } - + if (array == NULL) { + return NULL; + } + array_counter = 0; /* Iterate over all entries in all chains */ @@ -436,9 +436,9 @@ Set *set_union(Set *set1, Set *set2) new_set = set_new(set1->hash_func, set1->equal_func); - if (new_set == NULL) { - return NULL; - } + if (new_set == NULL) { + return NULL; + } /* Add all values from the first set */ @@ -454,11 +454,11 @@ Set *set_union(Set *set1, Set *set2) if (!set_insert(new_set, value)) { - /* Failed to insert */ - - set_free(new_set); - return NULL; - } + /* Failed to insert */ + + set_free(new_set); + return NULL; + } } set_iter_free(iterator); @@ -479,11 +479,11 @@ Set *set_union(Set *set1, Set *set2) if (set_query(new_set, value) == 0) { if (!set_insert(new_set, value)) { - /* Failed to insert */ + /* Failed to insert */ - set_free(new_set); - return NULL; - } + set_free(new_set); + return NULL; + } } } @@ -500,9 +500,9 @@ Set *set_intersection(Set *set1, Set *set2) new_set = set_new(set1->hash_func, set2->equal_func); - if (new_set == NULL) { - return NULL; - } + if (new_set == NULL) { + return NULL; + } /* Iterate over all values in set 1. */ @@ -523,10 +523,10 @@ Set *set_intersection(Set *set1, Set *set2) * if necessary */ if (!set_insert(new_set, value)) { - set_free(new_set); + set_free(new_set); - return NULL; - } + return NULL; + } } } @@ -544,9 +544,9 @@ SetIterator *set_iterate(Set *set) iter = malloc(sizeof(SetIterator)); - if (iter == NULL) { - return NULL; - } + if (iter == NULL) { + return NULL; + } iter->set = set; iter->current_entry = NULL; diff --git a/src/slist.c b/src/slist.c index d627cd7..fa53c59 100644 --- a/src/slist.c +++ b/src/slist.c @@ -72,10 +72,10 @@ SListEntry *slist_prepend(SListEntry **list, void *data) newentry = malloc(sizeof(SListEntry)); - if (newentry == NULL) { - return NULL; - } - + if (newentry == NULL) { + return NULL; + } + newentry->data = data; /* Hook into the list start */ @@ -95,10 +95,10 @@ SListEntry *slist_append(SListEntry **list, void *data) newentry = malloc(sizeof(SListEntry)); - if (newentry == NULL) { - return NULL; - } - + if (newentry == NULL) { + return NULL; + } + newentry->data = data; newentry->next = NULL; @@ -211,9 +211,9 @@ void **slist_to_array(SListEntry *list) array = malloc(sizeof(void *) * listlen); - if (array == NULL) { - return NULL; - } + if (array == NULL) { + return NULL; + } /* Add all entries to the array */ diff --git a/src/trie.c b/src/trie.c index e1825ca..d4886eb 100644 --- a/src/trie.c +++ b/src/trie.c @@ -76,10 +76,10 @@ Trie *trie_new(void) new_trie = (Trie *) malloc(sizeof(Trie)); - if (new_trie == NULL) { - return NULL; - } - + if (new_trie == NULL) { + return NULL; + } + new_trie->root_node = NULL; return new_trie; @@ -125,9 +125,9 @@ int trie_insert(Trie *trie, char *key, void *value) node = (TrieNode *) calloc(1, sizeof(TrieNode)); - if (node == NULL) { - return 0; - } + if (node == NULL) { + return 0; + } /* Link in to the trie */ @@ -159,7 +159,7 @@ int trie_insert(Trie *trie, char *key, void *value) ++p; } - return 1; + return 1; } void trie_remove(Trie *trie, char *key) diff --git a/test/test-binary-heap.c b/test/test-binary-heap.c index 06e84e0..5f87715 100644 --- a/test/test-binary-heap.c +++ b/test/test-binary-heap.c @@ -41,97 +41,97 @@ POSSIBILITY OF SUCH DAMAGE. void test_binary_heap_new_free(void) { - BinaryHeap *heap; - int i; + BinaryHeap *heap; + int i; - for (i=0; i<1000; ++i) { - heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); - binary_heap_free(heap); - } + for (i=0; i<1000; ++i) { + heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); + binary_heap_free(heap); + } } void test_binary_heap_insert(void) { - BinaryHeap *heap; - int *val; - int i; + BinaryHeap *heap; + int *val; + int i; - heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); + heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); - for (i=0; i<1000; ++i) { - val = malloc(sizeof(int)); - *val = i; - binary_heap_insert(heap, val); - } - assert(binary_heap_num_entries(heap) == 1000); + for (i=0; i<1000; ++i) { + val = malloc(sizeof(int)); + *val = i; + binary_heap_insert(heap, val); + } + assert(binary_heap_num_entries(heap) == 1000); - binary_heap_free(heap); + binary_heap_free(heap); } void test_min_heap(void) { - BinaryHeap *heap; - int *val; - int i; + BinaryHeap *heap; + int *val; + int i; - heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); + heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); - /* Push a load of values onto the heap */ + /* Push a load of values onto the heap */ - for (i=0; i<1000; ++i) { - val = malloc(sizeof(int)); - *val = i; - binary_heap_insert(heap, val); - } + for (i=0; i<1000; ++i) { + val = malloc(sizeof(int)); + *val = i; + binary_heap_insert(heap, val); + } - /* Pop values off the heap and check they are in order */ + /* Pop values off the heap and check they are in order */ - i = -1; - while (binary_heap_num_entries(heap) > 0) { - val = (int *) binary_heap_pop(heap); + i = -1; + while (binary_heap_num_entries(heap) > 0) { + val = (int *) binary_heap_pop(heap); - assert(*val == i + 1); - i = *val; - } + assert(*val == i + 1); + i = *val; + } - binary_heap_free(heap); + binary_heap_free(heap); } void test_max_heap(void) { - BinaryHeap *heap; - int *val; - int i; + BinaryHeap *heap; + int *val; + int i; - heap = binary_heap_new(BINARY_HEAP_TYPE_MAX, int_compare); + heap = binary_heap_new(BINARY_HEAP_TYPE_MAX, int_compare); - /* Push a load of values onto the heap */ + /* Push a load of values onto the heap */ - for (i=0; i<1000; ++i) { - val = malloc(sizeof(int)); - *val = i; - binary_heap_insert(heap, val); - } + for (i=0; i<1000; ++i) { + val = malloc(sizeof(int)); + *val = i; + binary_heap_insert(heap, val); + } - /* Pop values off the heap and check they are in order */ + /* Pop values off the heap and check they are in order */ - i = 1000; - while (binary_heap_num_entries(heap) > 0) { - val = (int *) binary_heap_pop(heap); + i = 1000; + while (binary_heap_num_entries(heap) > 0) { + val = (int *) binary_heap_pop(heap); - assert(*val == i - 1); - i = *val; - } + assert(*val == i - 1); + i = *val; + } - binary_heap_free(heap); + binary_heap_free(heap); } int main(int argc, char *argv[]) { - test_binary_heap_new_free(); - test_min_heap(); - test_max_heap(); + test_binary_heap_new_free(); + test_min_heap(); + test_max_heap(); - return 0; + return 0; } diff --git a/test/test-list.c b/test/test-list.c index 67e44b1..9a30ead 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -389,11 +389,11 @@ void test_list_to_array(void) void test_list_iterate(void) { ListEntry *list; - ListIterator *iter; + ListIterator *iter; int i; - int a; + int a; int counter; - int *data; + int *data; /* Create a list with 50 entries */ @@ -407,20 +407,20 @@ void test_list_iterate(void) counter = 0; - iter = list_iterate(&list); + iter = list_iterate(&list); - while (list_iter_has_more(iter)) { - data = (int *) list_iter_next(iter); - ++counter; + while (list_iter_has_more(iter)) { + data = (int *) list_iter_next(iter); + ++counter; - if ((counter % 2) == 0) { - /* Delete half the entries in the list. */ + if ((counter % 2) == 0) { + /* Delete half the entries in the list. */ - list_iter_remove(iter); - } - } + list_iter_remove(iter); + } + } - list_iter_free(iter); + list_iter_free(iter); assert(counter == 50); @@ -429,12 +429,12 @@ void test_list_iterate(void) list = NULL; counter = 0; - iter = list_iterate(&list); + iter = list_iterate(&list); - while (list_iter_has_more(iter)) { - data = (int *) list_iter_next(iter); - ++counter; - } + while (list_iter_has_more(iter)) { + data = (int *) list_iter_next(iter); + ++counter; + } assert(counter == 0); } diff --git a/test/test-set.c b/test/test-set.c index 9432990..d96dc39 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -146,46 +146,46 @@ void test_set_remove(void) { Set *set; int i; - int num_entries; + int num_entries; set = generate_set(); - num_entries = set_num_entries(set); - assert(num_entries == 10000); + num_entries = set_num_entries(set); + assert(num_entries == 10000); /* Remove some entries */ - for (i=4000; i<6000; ++i) { - /* Check this is in the set */ + for (i=4000; i<6000; ++i) { + /* Check this is in the set */ - assert(set_query(set, &i) != 0); + assert(set_query(set, &i) != 0); - /* Remove it */ + /* Remove it */ - assert(set_remove(set, &i) != 0); + assert(set_remove(set, &i) != 0); - /* Check the number of entries decreases */ + /* Check the number of entries decreases */ - assert(set_num_entries(set) == num_entries - 1); + assert(set_num_entries(set) == num_entries - 1); - /* Check it is no longer in the set */ + /* Check it is no longer in the set */ - assert(set_query(set, &i) == 0); + assert(set_query(set, &i) == 0); - --num_entries; - } + --num_entries; + } /* Try to remove some invalid entries */ - for (i=-1000; i<-500; ++i) { - assert(set_remove(set, &i) == 0); - assert(set_num_entries(set) == num_entries); - } + for (i=-1000; i<-500; ++i) { + assert(set_remove(set, &i) == 0); + assert(set_num_entries(set) == num_entries); + } - for (i=50000; i<51000; ++i) { - assert(set_remove(set, &i) == 0); - assert(set_num_entries(set) == num_entries); - } + for (i=50000; i<51000; ++i) { + assert(set_remove(set, &i) == 0); + assert(set_num_entries(set) == num_entries); + } } void test_set_union(void) From bff5c4133a0d304c14420b449f49bb69ac9633b3 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 28 Oct 2006 12:10:43 +0000 Subject: [PATCH 018/250] Convert slist_foreach to iterators. --- src/slist.c | 147 +++++++++++++++++++++++++++++++++++++++------- src/slist.h | 67 ++++++++++++++++----- test/test-slist.c | 91 ++++++++++++++++++++-------- 3 files changed, 243 insertions(+), 62 deletions(-) diff --git a/src/slist.c b/src/slist.c index fa53c59..cc8438c 100644 --- a/src/slist.c +++ b/src/slist.c @@ -44,6 +44,14 @@ struct _SListEntry { SListEntry *next; }; +/* Iterator for iterating over a singly-linked list. */ + +struct _SListIterator { + SListEntry **list; + SListEntry **prev_next; + SListEntry *current; +}; + void slist_free(SListEntry *list) { SListEntry *entry; @@ -233,27 +241,6 @@ void **slist_to_array(SListEntry *list) return array; } - -void slist_foreach(SListEntry *list, SListIterator callback, void *user_data) -{ - SListEntry *entry; - - /* Iterate over each entry in the list */ - - entry = list; - - while (entry != NULL) { - - /* Invoke the callback function */ - - callback(entry->data, user_data); - - /* Advance to the next entry */ - - entry = entry->next; - } -} - int slist_remove_entry(SListEntry **list, SListEntry *entry) { SListEntry *rover; @@ -455,5 +442,121 @@ SListEntry *slist_find_data(SListEntry *list, return NULL; } - +SListIterator *slist_iterate(SListEntry **list) +{ + SListIterator *iter; + + /* Allocate the new structure */ + + iter = malloc(sizeof(SListIterator)); + + if (iter == NULL) { + return NULL; + } + + /* Save the list location */ + + iter->list = list; + + /* These are NULL as we have not read the first item yet */ + + iter->prev_next = NULL; + iter->current = NULL; + + return iter; +} + +int slist_iter_has_more(SListIterator *iter) +{ + if (iter->prev_next == NULL) { + + /* The iterator has just been created. slist_iter_next + * has not been called yet. There are more entries if + * the list itself is not empty. */ + + return *iter->list != NULL; + + } else if (*iter->prev_next != iter->current) { + + /* The entry last returned from slist_iter_next has been + * deleted. The next entry is indicated by prev_next. */ + + return *iter->prev_next != NULL; + + } else { + + /* The current entry has not been deleted. There + * is a next entry if current->next is not NULL. */ + + return iter->current->next != NULL; + + } +} + +void *slist_iter_next(SListIterator *iter) +{ + if (iter->prev_next == NULL) { + + /* This is the first call to slist_iter_next. */ + + /* Initial prev_next is the list start variable */ + + iter->prev_next = iter->list; + + /* Start at the first element */ + + iter->current = *iter->list; + + } else if (*iter->prev_next != iter->current) { + + /* The value last returned by slist_iter_next was + * deleted. Use prev_next to find the next + * entry. */ + + iter->current = *iter->prev_next; + + } else { + + /* Last value returned from slist_iter_next was not + * deleted. Advance to the next entry. */ + + if (iter->current != NULL) { + iter->prev_next = &iter->current->next; + iter->current = iter->current->next; + } + } + + if (iter->current == NULL) { + return NULL; + } else { + return iter->current->data; + } + +} + +void slist_iter_remove(SListIterator *iter) +{ + if (iter->prev_next == NULL) { + + /* slist_iter_next has not been called yet. */ + + } else if (*iter->prev_next != iter->current) { + + /* Current entry was already deleted */ + + } else { + + /* Remove the current entry */ + + if (iter->current != NULL) { + *iter->prev_next = iter->current->next; + free(iter->current); + } + } +} + +void slist_iter_free(SListIterator *iter) +{ + free(iter); +} diff --git a/src/slist.h b/src/slist.h index 1ace58a..d5b9167 100644 --- a/src/slist.h +++ b/src/slist.h @@ -61,8 +61,6 @@ POSSIBILITY OF SUCH DAMAGE. * * To sort a list into an order, use @ref slist_sort. * - * To iterate over a list, use @ref slist_foreach. - * * To find a particular entry in a list by its index, use * @ref slist_nth_entry. * @@ -87,10 +85,10 @@ POSSIBILITY OF SUCH DAMAGE. typedef struct _SListEntry SListEntry; /** - * Callback function used for iterating over a list + * Structure used to iterate over a list. */ -typedef void (*SListIterator)(void *data, void *user_data); +typedef struct _SListIterator SListIterator; /** * Callback function used to compare values in a list when sorting. @@ -202,16 +200,6 @@ int slist_length(SListEntry *list); void **slist_to_array(SListEntry *list); -/** - * Iterate over all entries in a list. - * - * @param list The list. - * @param callback Callback function to invoke for each entry in the list. - * @param user_data Extra data to pass to the callback function. - */ - -void slist_foreach(SListEntry *list, SListIterator callback, void *user_data); - /** * Remove an entry from a list. * @@ -259,5 +247,56 @@ SListEntry *slist_find_data(SListEntry *list, SListEqualFunc callback, void *data); +/** + * Create a new @reg SListIterator structure to iterate over a list. + * The iterator should be freed once iterating has completed, using + * the function @ref list_iter_free. + * + * @param list Pointer to the list to iterate over. + * @return A new @ref SListIterator. + */ + +SListIterator *slist_iterate(SListEntry **list); + +/** + * Determine if there are more values in the list to iterate over. When + * iteration is finished, the iterator should be freed using + * @ref slist_iter_free. + * + * @param iterator The list iterator. + * @return Zero if there are no more values in the list to + * iterate over, non-zero if there are more values to + * read. + */ + +int slist_iter_has_more(SListIterator *iter); + +/** + * Using a list iterator, retrieve the next value from the list. + * + * @param iterator The list iterator. + * @return The next value from the list, or NULL if there are + * no more values in the list. + */ + +void *slist_iter_next(SListIterator *iter); + +/** + * Delete the current entry in the list (the value last returned from + * @ref slist_iter_next) + * + * @param iterator The list iterator. + */ + +void slist_iter_remove(SListIterator *iter); + +/** + * Free back a list iterator. + * + * @param iterator The list iterator. + */ + +void slist_iter_free(SListIterator *iter); + #endif /* #ifndef ALGORITHM_SLIST_H */ diff --git a/test/test-slist.c b/test/test-slist.c index cfa54bd..b80907f 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -348,34 +348,27 @@ void test_slist_find_data(void) void test_slist_to_array(void) { - SListEntry *list; - void **array; - - list = generate_list(); - - array = slist_to_array(list); - - assert(array[0] == &variable1); - assert(array[1] == &variable2); - assert(array[2] == &variable3); - assert(array[3] == &variable4); + SListEntry *list; + void **array; + + list = generate_list(); + + array = slist_to_array(list); + + assert(array[0] == &variable1); + assert(array[1] == &variable2); + assert(array[2] == &variable3); + assert(array[3] == &variable4); } -static void test_slist_foreach_foreach(void *data, void *vcounter) -{ - int *counter; - - counter = (int *) vcounter; - - ++*counter; -} - -void test_slist_foreach(void) +void test_slist_iterate(void) { + SListEntry *list; + SListIterator *iter; + int *data; int a; int i; int counter; - SListEntry *list; /* Create a list with 50 entries */ @@ -389,19 +382,65 @@ void test_slist_foreach(void) counter = 0; - slist_foreach(list, test_slist_foreach_foreach, &counter); + iter = slist_iterate(&list); + + /* Test remove before slist_iter_next has been called */ + + slist_iter_remove(iter); + + /* Iterate over the list */ + + while (slist_iter_has_more(iter)) { + + data = (int *) slist_iter_next(iter); + + ++counter; + + /* Remove half the entries from the list */ + + if ((counter % 2) == 0) { + slist_iter_remove(iter); + + /* Test double remove */ + + slist_iter_remove(iter); + } + } + + /* Test remove at the end of a list */ + + slist_iter_remove(iter); + + /* Destroy the iterator */ + + slist_iter_free(iter); assert(counter == 50); + assert(slist_length(list) == 25); /* Test iterating over an empty list */ list = NULL; counter = 0; - slist_foreach(list, test_slist_foreach_foreach, &counter); + iter = slist_iterate(&list); - assert(counter == 0); + while (slist_iter_has_more(iter)) { + + data = (int *) slist_iter_next(iter); + + ++counter; + /* Remove half the entries from the list */ + + if ((counter % 2) == 0) { + slist_iter_remove(iter); + } + } + + slist_iter_free(iter); + + assert(counter == 0); } @@ -419,7 +458,7 @@ int main(int argc, char *argv[]) test_slist_sort(); test_slist_find_data(); test_slist_to_array(); - test_slist_foreach(); + test_slist_iterate(); return 0; } From e005519bc731eb4eb6859b203f5b41909f7fe396 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 28 Oct 2006 12:17:45 +0000 Subject: [PATCH 019/250] Improve list iterate test case. --- test/test-list.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/test-list.c b/test/test-list.c index 9a30ead..46f7bed 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -409,6 +409,12 @@ void test_list_iterate(void) iter = list_iterate(&list); + /* Test remove before list_iter_next has been called */ + + list_iter_remove(iter); + + /* Iterate over the list */ + while (list_iter_has_more(iter)) { data = (int *) list_iter_next(iter); ++counter; @@ -417,12 +423,23 @@ void test_list_iterate(void) /* Delete half the entries in the list. */ list_iter_remove(iter); + + /* Test double remove */ + + list_iter_remove(iter); } } + /* Test remove at the end of a list */ + + list_iter_remove(iter); + + /* Destroy the iterator */ + list_iter_free(iter); assert(counter == 50); + assert(list_length(list) == 25); /* Test iterating over an empty list */ From b0abae214e49bf8a0a16e96f81d310a532f81ec8 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 28 Oct 2006 12:18:05 +0000 Subject: [PATCH 020/250] Reword comments. --- src/list.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/list.c b/src/list.c index 4a31320..dac1191 100644 --- a/src/list.c +++ b/src/list.c @@ -511,9 +511,8 @@ int list_iter_has_more(ListIterator *iter) } else if (*iter->prev_next != iter->current) { - /* Current entry has been deleted since the last call - * to list_iter_next. Use prev_next as an indicator - * of the next entry. */ + /* The entry last returned by list_iter_next has been + * deleted. The next entry is indincated by prev_next. */ return *iter->prev_next != NULL; @@ -542,33 +541,49 @@ void *list_iter_next(ListIterator *iter) } else if (*iter->prev_next != iter->current) { - /* The current value has been deleted since the last call - * to list_iter_next. Use what prev_next is pointing to - * now as the next entry. */ + /* The value last returned by list_iter_next was deleted. + * Use prev_next to find the next entry. */ iter->current = *iter->prev_next; } else { - /* Current entry has not been deleted since the last call - * to list_iter_next. Simply advance to the next entry - * in the list. */ + /* Last value returned from list_iter_next was not deleted. + * Advance to the next entry. */ if (iter->current != NULL) { iter->prev_next = &iter->current->next; iter->current = iter->current->next; } - } /* Return data from the current entry */ - return iter->current->data; + if (iter->current == NULL) { + return NULL; + } else { + return iter->current->data; + } } void list_iter_remove(ListIterator *iter) { - list_remove_entry(iter->list, iter->current); + if (iter->prev_next == NULL) { + + /* list_iter_next has not been called yet. */ + + } else if (*iter->prev_next != iter->current) { + + /* Current entry was already deleted. */ + + } else { + + /* Remove the current entry */ + + if (iter->current != NULL) { + list_remove_entry(iter->list, iter->current); + } + } } void list_iter_free(ListIterator *iter) From 56bdb4a037496f144afc21a55c61b4b74b1afa07 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 28 Oct 2006 12:21:26 +0000 Subject: [PATCH 021/250] Fix up indentation. --- src/list.c | 42 +++++++------- src/slist.c | 140 +++++++++++++++++++++++----------------------- test/test-list.c | 20 +++---- test/test-slist.c | 68 +++++++++++----------- 4 files changed, 135 insertions(+), 135 deletions(-) diff --git a/src/list.c b/src/list.c index dac1191..25237e2 100644 --- a/src/list.c +++ b/src/list.c @@ -511,8 +511,8 @@ int list_iter_has_more(ListIterator *iter) } else if (*iter->prev_next != iter->current) { - /* The entry last returned by list_iter_next has been - * deleted. The next entry is indincated by prev_next. */ + /* The entry last returned by list_iter_next has been + * deleted. The next entry is indincated by prev_next. */ return *iter->prev_next != NULL; @@ -542,14 +542,14 @@ void *list_iter_next(ListIterator *iter) } else if (*iter->prev_next != iter->current) { /* The value last returned by list_iter_next was deleted. - * Use prev_next to find the next entry. */ + * Use prev_next to find the next entry. */ iter->current = *iter->prev_next; } else { - /* Last value returned from list_iter_next was not deleted. - * Advance to the next entry. */ + /* Last value returned from list_iter_next was not deleted. + * Advance to the next entry. */ if (iter->current != NULL) { iter->prev_next = &iter->current->next; @@ -559,31 +559,31 @@ void *list_iter_next(ListIterator *iter) /* Return data from the current entry */ - if (iter->current == NULL) { - return NULL; - } else { - return iter->current->data; - } + if (iter->current == NULL) { + return NULL; + } else { + return iter->current->data; + } } void list_iter_remove(ListIterator *iter) { - if (iter->prev_next == NULL) { + if (iter->prev_next == NULL) { - /* list_iter_next has not been called yet. */ + /* list_iter_next has not been called yet. */ - } else if (*iter->prev_next != iter->current) { + } else if (*iter->prev_next != iter->current) { - /* Current entry was already deleted. */ + /* Current entry was already deleted. */ - } else { - - /* Remove the current entry */ + } else { + + /* Remove the current entry */ - if (iter->current != NULL) { - list_remove_entry(iter->list, iter->current); - } - } + if (iter->current != NULL) { + list_remove_entry(iter->list, iter->current); + } + } } void list_iter_free(ListIterator *iter) diff --git a/src/slist.c b/src/slist.c index cc8438c..5663b9b 100644 --- a/src/slist.c +++ b/src/slist.c @@ -47,9 +47,9 @@ struct _SListEntry { /* Iterator for iterating over a singly-linked list. */ struct _SListIterator { - SListEntry **list; - SListEntry **prev_next; - SListEntry *current; + SListEntry **list; + SListEntry **prev_next; + SListEntry *current; }; void slist_free(SListEntry *list) @@ -444,119 +444,119 @@ SListEntry *slist_find_data(SListEntry *list, SListIterator *slist_iterate(SListEntry **list) { - SListIterator *iter; + SListIterator *iter; - /* Allocate the new structure */ + /* Allocate the new structure */ - iter = malloc(sizeof(SListIterator)); + iter = malloc(sizeof(SListIterator)); - if (iter == NULL) { - return NULL; - } + if (iter == NULL) { + return NULL; + } - /* Save the list location */ + /* Save the list location */ - iter->list = list; + iter->list = list; - /* These are NULL as we have not read the first item yet */ + /* These are NULL as we have not read the first item yet */ - iter->prev_next = NULL; - iter->current = NULL; + iter->prev_next = NULL; + iter->current = NULL; - return iter; + return iter; } int slist_iter_has_more(SListIterator *iter) { - if (iter->prev_next == NULL) { - - /* The iterator has just been created. slist_iter_next - * has not been called yet. There are more entries if - * the list itself is not empty. */ + if (iter->prev_next == NULL) { + + /* The iterator has just been created. slist_iter_next + * has not been called yet. There are more entries if + * the list itself is not empty. */ - return *iter->list != NULL; - - } else if (*iter->prev_next != iter->current) { + return *iter->list != NULL; + + } else if (*iter->prev_next != iter->current) { - /* The entry last returned from slist_iter_next has been - * deleted. The next entry is indicated by prev_next. */ + /* The entry last returned from slist_iter_next has been + * deleted. The next entry is indicated by prev_next. */ - return *iter->prev_next != NULL; + return *iter->prev_next != NULL; - } else { - - /* The current entry has not been deleted. There - * is a next entry if current->next is not NULL. */ + } else { + + /* The current entry has not been deleted. There + * is a next entry if current->next is not NULL. */ - return iter->current->next != NULL; + return iter->current->next != NULL; - } + } } void *slist_iter_next(SListIterator *iter) { - if (iter->prev_next == NULL) { + if (iter->prev_next == NULL) { - /* This is the first call to slist_iter_next. */ + /* This is the first call to slist_iter_next. */ - /* Initial prev_next is the list start variable */ + /* Initial prev_next is the list start variable */ - iter->prev_next = iter->list; + iter->prev_next = iter->list; - /* Start at the first element */ + /* Start at the first element */ - iter->current = *iter->list; + iter->current = *iter->list; - } else if (*iter->prev_next != iter->current) { + } else if (*iter->prev_next != iter->current) { - /* The value last returned by slist_iter_next was - * deleted. Use prev_next to find the next - * entry. */ + /* The value last returned by slist_iter_next was + * deleted. Use prev_next to find the next + * entry. */ - iter->current = *iter->prev_next; + iter->current = *iter->prev_next; - } else { + } else { - /* Last value returned from slist_iter_next was not - * deleted. Advance to the next entry. */ + /* Last value returned from slist_iter_next was not + * deleted. Advance to the next entry. */ - if (iter->current != NULL) { - iter->prev_next = &iter->current->next; - iter->current = iter->current->next; - } - } + if (iter->current != NULL) { + iter->prev_next = &iter->current->next; + iter->current = iter->current->next; + } + } - if (iter->current == NULL) { - return NULL; - } else { - return iter->current->data; - } + if (iter->current == NULL) { + return NULL; + } else { + return iter->current->data; + } } void slist_iter_remove(SListIterator *iter) { - if (iter->prev_next == NULL) { + if (iter->prev_next == NULL) { - /* slist_iter_next has not been called yet. */ + /* slist_iter_next has not been called yet. */ - } else if (*iter->prev_next != iter->current) { - - /* Current entry was already deleted */ + } else if (*iter->prev_next != iter->current) { + + /* Current entry was already deleted */ - } else { - - /* Remove the current entry */ + } else { + + /* Remove the current entry */ - if (iter->current != NULL) { - *iter->prev_next = iter->current->next; - free(iter->current); - } - } + if (iter->current != NULL) { + *iter->prev_next = iter->current->next; + free(iter->current); + } + } } void slist_iter_free(SListIterator *iter) { - free(iter); + free(iter); } diff --git a/test/test-list.c b/test/test-list.c index 46f7bed..c25bbc8 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -409,11 +409,11 @@ void test_list_iterate(void) iter = list_iterate(&list); - /* Test remove before list_iter_next has been called */ + /* Test remove before list_iter_next has been called */ - list_iter_remove(iter); + list_iter_remove(iter); - /* Iterate over the list */ + /* Iterate over the list */ while (list_iter_has_more(iter)) { data = (int *) list_iter_next(iter); @@ -424,22 +424,22 @@ void test_list_iterate(void) list_iter_remove(iter); - /* Test double remove */ + /* Test double remove */ - list_iter_remove(iter); + list_iter_remove(iter); } } - /* Test remove at the end of a list */ + /* Test remove at the end of a list */ - list_iter_remove(iter); + list_iter_remove(iter); - /* Destroy the iterator */ - + /* Destroy the iterator */ + list_iter_free(iter); assert(counter == 50); - assert(list_length(list) == 25); + assert(list_length(list) == 25); /* Test iterating over an empty list */ diff --git a/test/test-slist.c b/test/test-slist.c index b80907f..61cc0cb 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -364,8 +364,8 @@ void test_slist_to_array(void) void test_slist_iterate(void) { SListEntry *list; - SListIterator *iter; - int *data; + SListIterator *iter; + int *data; int a; int i; int counter; @@ -382,63 +382,63 @@ void test_slist_iterate(void) counter = 0; - iter = slist_iterate(&list); + iter = slist_iterate(&list); - /* Test remove before slist_iter_next has been called */ + /* Test remove before slist_iter_next has been called */ - slist_iter_remove(iter); + slist_iter_remove(iter); - /* Iterate over the list */ + /* Iterate over the list */ - while (slist_iter_has_more(iter)) { + while (slist_iter_has_more(iter)) { - data = (int *) slist_iter_next(iter); + data = (int *) slist_iter_next(iter); - ++counter; + ++counter; - /* Remove half the entries from the list */ + /* Remove half the entries from the list */ - if ((counter % 2) == 0) { - slist_iter_remove(iter); + if ((counter % 2) == 0) { + slist_iter_remove(iter); - /* Test double remove */ + /* Test double remove */ - slist_iter_remove(iter); - } - } - - /* Test remove at the end of a list */ + slist_iter_remove(iter); + } + } + + /* Test remove at the end of a list */ - slist_iter_remove(iter); + slist_iter_remove(iter); - /* Destroy the iterator */ - - slist_iter_free(iter); + /* Destroy the iterator */ + + slist_iter_free(iter); assert(counter == 50); - assert(slist_length(list) == 25); + assert(slist_length(list) == 25); /* Test iterating over an empty list */ list = NULL; counter = 0; - iter = slist_iterate(&list); + iter = slist_iterate(&list); - while (slist_iter_has_more(iter)) { + while (slist_iter_has_more(iter)) { - data = (int *) slist_iter_next(iter); + data = (int *) slist_iter_next(iter); - ++counter; + ++counter; - /* Remove half the entries from the list */ + /* Remove half the entries from the list */ - if ((counter % 2) == 0) { - slist_iter_remove(iter); - } - } - - slist_iter_free(iter); + if ((counter % 2) == 0) { + slist_iter_remove(iter); + } + } + + slist_iter_free(iter); assert(counter == 0); } From 1536c59f1641f0b8982fc92c6919204eed219456 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 30 Oct 2006 20:09:29 +0000 Subject: [PATCH 022/250] Fix allocation size on reallocs. --- src/arraylist.c | 7 ++++--- src/binary-heap.c | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/arraylist.c b/src/arraylist.c index bef16ef..ee54a8e 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -87,20 +87,21 @@ void arraylist_free(ArrayList *arraylist) static int arraylist_enlarge(ArrayList *arraylist) { void **data; + int newsize; /* Double the allocated size */ - arraylist->_alloced *= 2; + newsize = arraylist->_alloced * 2; /* Reallocate the array to the new size */ - data = realloc(arraylist->data, - sizeof(void *) * arraylist->_alloced); + data = realloc(arraylist->data, sizeof(void *) * newsize); if (data == NULL) { return 0; } else { arraylist->data = data; + arraylist->_alloced = newsize; return 1; } diff --git a/src/binary-heap.c b/src/binary-heap.c index 04f4606..750691f 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -92,6 +92,7 @@ int binary_heap_insert(BinaryHeap *heap, void *value) { void **new_values; int index; + int newsize; int parent; /* Possibly realloc the heap to a larger size */ @@ -100,14 +101,14 @@ int binary_heap_insert(BinaryHeap *heap, void *value) /* Double the table size */ - heap->alloced_size *= 2; - new_values = realloc(heap->values, - sizeof(void *) * heap->alloced_size); + newsize = heap->alloced_size * 2; + new_values = realloc(heap->values, sizeof(void *) * newsize); if (new_values == NULL) { return 0; } + heap->alloced_size = newsize; heap->values = new_values; } From bcdc17567609807c1a788f7001c66bba44ef2dab Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 30 Oct 2006 20:11:34 +0000 Subject: [PATCH 023/250] Trie fixes: recover properly from failed mallocs. Fix insert that replaces an existing value. --- src/trie.c | 149 +++++++++++++++++++++++++++++++++++++---------------- src/trie.h | 4 +- 2 files changed, 107 insertions(+), 46 deletions(-) diff --git a/src/trie.c b/src/trie.c index d4886eb..d86f837 100644 --- a/src/trie.c +++ b/src/trie.c @@ -96,6 +96,73 @@ void trie_free(Trie *trie) free(trie); } +static TrieNode *trie_find_end(Trie *trie, char *key) +{ + TrieNode *node; + char *p; + int c; + + /* Search down the trie until the end of string is reached */ + + node = trie->root_node; + + for (p=key; *p != '\0'; ++p) { + + if (node == NULL) { + /* Not found in the tree. Return. */ + + return NULL; + } + + /* Jump to the next node */ + + c = *p; + node = node->next[c]; + } + + /* This key is present if the value at the last node is not NULL */ + + return node; +} + +/* Roll back an insert operation after a failed malloc() call. */ + +static void trie_insert_rollback(Trie *trie, char *key) +{ + TrieNode **rover; + TrieNode *node; + char *p; + + /* Follow the chain along. We know that we will never reach the + * end of the string because trie_insert never got that far. As a + * result, it is not necessary to check for the end of string + * delimiter (NUL) */ + + rover = &trie->root_node; + p = key; + + while (*rover != NULL) { + + /* Advance to the next node in the chain. Do this now, + * before we potentially free this node. */ + + node = *rover; + rover = &node->next[(int) *p]; + ++p; + + /* Decrement the use count at this node back to what it + * previously was. */ + + --node->use_count; + + if (node->use_count <= 0) { + /* This has just been allocated. Free it back. */ + + free(node); + } + } +} + int trie_insert(Trie *trie, char *key, void *value) { TrieNode **rover; @@ -108,6 +175,18 @@ int trie_insert(Trie *trie, char *key, void *value) if (value == NULL) { return 0; } + + /* Search to see if this is already in the tree */ + + node = trie_find_end(trie, key); + + /* Already in the tree? If so, replace the existing value and + * return success. */ + + if (node != NULL && node->data != NULL) { + node->data = value; + return 1; + } /* Search down the trie until we reach the end of string, * creating nodes as necessary */ @@ -120,12 +199,18 @@ int trie_insert(Trie *trie, char *key, void *value) node = *rover; if (node == NULL) { - + /* Node does not exist, so create it */ node = (TrieNode *) calloc(1, sizeof(TrieNode)); if (node == NULL) { + + /* Allocation failed. Go back and undo + * what we have done so far. */ + + trie_insert_rollback(trie, key); + return 0; } @@ -134,7 +219,7 @@ int trie_insert(Trie *trie, char *key, void *value) *rover = node; } - /* One more use of this node */ + /* Increase the node use count */ ++node->use_count; @@ -162,7 +247,7 @@ int trie_insert(Trie *trie, char *key, void *value) return 1; } -void trie_remove(Trie *trie, char *key) +int trie_remove(Trie *trie, char *key) { TrieNode *node; TrieNode *next; @@ -170,31 +255,16 @@ void trie_remove(Trie *trie, char *key) char *p; int c; - /* First, search down to the ending node so that the data can - * be removed. */ - - /* Search down the trie until the end of string is reached */ + /* Find the end node and remove the value */ - node = trie->root_node; - - for (p=key; *p != '\0'; ++p) { - - if (node == NULL) { - /* Not found in the tree. Return. */ + node = trie_find_end(trie, key); - return; - } - - /* Jump to the next node */ - - c = *p; - node = node->next[c]; + if (node != NULL && node->data != NULL) { + node->data = NULL; + } else { + return 0; } - /* Remove the data at this node */ - - node->data = NULL; - /* Now traverse the tree again as before, decrementing the use * count of each node. Free back nodes as necessary. */ @@ -217,7 +287,7 @@ void trie_remove(Trie *trie, char *key) free(node); /* Set the "next" pointer on the previous node to NULL, - * to unlink the free'd node from the tree. This only + * to unlink the freed node from the tree. This only * needs to be done once in a remove. After the first * unlink, all further nodes are also going to be * free'd. */ @@ -248,34 +318,23 @@ void trie_remove(Trie *trie, char *key) node = next; } + + /* Removed successfully */ + + return 1; } void *trie_lookup(Trie *trie, char *key) { TrieNode *node; - char *p; - int c; - - /* Search down the trie until the end of string is found */ - - node = trie->root_node; - p = key; - - while (*p != '\0') { - if (node == NULL) { - /* Not found - reached end of branch */ - - return NULL; - } - /* Advance to the next node in the chain, next character */ + node = trie_find_end(trie, key); - c = *p; - node = node->next[c]; - ++p; + if (node != NULL) { + return node->data; + } else { + return NULL; } - - return node->data; } int trie_num_entries(Trie *trie) diff --git a/src/trie.h b/src/trie.h index 5b3d878..41fd6c1 100644 --- a/src/trie.h +++ b/src/trie.h @@ -108,9 +108,11 @@ void *trie_lookup(Trie *trie, char *key); * * @param trie The trie. * @param key The key of the entry to remove. + * @return Non-zero if the key was removed successfully, + * or zero if it is not present in the trie. */ -void trie_remove(Trie *trie, char *key); +int trie_remove(Trie *trie, char *key); /** * Find the number of entries in a trie. From c2a7c499d464e7eec9a253a61737bca5ae044bc0 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 30 Oct 2006 20:12:29 +0000 Subject: [PATCH 024/250] Indentation fixes. --- test/test-hashtable.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-hashtable.c b/test/test-hashtable.c index 19a76c1..4ff8bb4 100644 --- a/test/test-hashtable.c +++ b/test/test-hashtable.c @@ -180,9 +180,9 @@ void test_hash_table_iterating(void) iterator = hash_table_iterate(hashtable); while (hash_table_iter_has_more(iterator)) { - hash_table_iter_next(iterator); + hash_table_iter_next(iterator); - ++count; + ++count; } hash_table_iter_free(iterator); From 0b1e66e25335ed2d88bd22570dbf2ef4ea45ae0c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 30 Oct 2006 20:13:10 +0000 Subject: [PATCH 025/250] Improved trie test cases. --- test/test-trie.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/test/test-trie.c b/test/test-trie.c index 6d96c15..4219181 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -75,7 +75,7 @@ void test_trie_free() trie = trie_new(); trie_insert(trie, "hello", "there"); - trie_remove(trie, "hello"); + assert(trie_remove(trie, "hello") == 1); trie_free(trie); } @@ -109,6 +109,20 @@ void test_trie_insert_lookup_remove() assert(trie_num_entries(trie) == entries); } + /* Test remove on non-existent values. */ + + assert(trie_remove(trie, "000000000000000") == 0); + assert(trie_remove(trie, "") == 0); + assert(trie_num_entries(trie) == entries); + + /* Test replacing values */ + + val = malloc(sizeof(int)); + *val = 999; + trie_insert(trie, "999", val); + assert(trie_num_entries(trie) == entries); + assert(trie_lookup(trie, "999") == val); + /* Look up all values */ for (i=0; i<100000; ++i) { @@ -121,7 +135,7 @@ void test_trie_insert_lookup_remove() /* Remove value and check counter */ - trie_remove(trie, buf); + assert(trie_remove(trie, buf) != 0); --entries; assert(trie_num_entries(trie) == entries); } @@ -131,7 +145,7 @@ void test_trie_insert_lookup_remove() trie_insert(trie, "", buf); assert(trie_num_entries(trie) == 1); assert(trie_lookup(trie, "") == buf); - trie_remove(trie, ""); + assert(trie_remove(trie, "") != 0); assert(trie_num_entries(trie) == 0); } From f6d88ee092740c604351dd54019deff3ab719c04 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 30 Oct 2006 20:15:18 +0000 Subject: [PATCH 026/250] Fix indentation. --- test/test-slist.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/test-slist.c b/test/test-slist.c index 61cc0cb..839de91 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -348,17 +348,17 @@ void test_slist_find_data(void) void test_slist_to_array(void) { - SListEntry *list; - void **array; - - list = generate_list(); - - array = slist_to_array(list); - - assert(array[0] == &variable1); - assert(array[1] == &variable2); - assert(array[2] == &variable3); - assert(array[3] == &variable4); + SListEntry *list; + void **array; + + list = generate_list(); + + array = slist_to_array(list); + + assert(array[0] == &variable1); + assert(array[1] == &variable2); + assert(array[2] == &variable3); + assert(array[3] == &variable4); } void test_slist_iterate(void) From a5abac3601d60a114970deeb9e653a9ff612abf1 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 15 Nov 2006 19:32:01 +0000 Subject: [PATCH 027/250] Add bloom filter. --- src/Makefile.am | 6 +- src/bloom-filter.c | 192 +++++++++++++++++++++++++++++++++++++++++++++ src/bloom-filter.h | 135 +++++++++++++++++++++++++++++++ 3 files changed, 331 insertions(+), 2 deletions(-) create mode 100644 src/bloom-filter.c create mode 100644 src/bloom-filter.h diff --git a/src/Makefile.am b/src/Makefile.am index dfcaab8..9f83dc7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,12 +8,14 @@ MAIN_HEADERFILES = libcalg.h CALG_HEADERFILES=\ arraylist.h compare-int.h hash-int.h hashtable.h set.h \ avltree.h compare-pointer.h hash-pointer.h list.h slist.h \ -queue.h compare-string.h hash-string.h trie.h binary-heap.h +queue.h compare-string.h hash-string.h trie.h binary-heap.h \ +bloom-filter.h SRC=\ arraylist.c compare-pointer.c hash-pointer.c list.c slist.c \ avltree.c compare-string.c hash-string.c queue.c trie.c \ -compare-int.c hash-int.c hashtable.c set.c binary-heap.c +compare-int.c hash-int.c hashtable.c set.c binary-heap.c \ +bloom-filter.c libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) diff --git a/src/bloom-filter.c b/src/bloom-filter.c new file mode 100644 index 0000000..472bc03 --- /dev/null +++ b/src/bloom-filter.c @@ -0,0 +1,192 @@ + +/* + +Copyright (c) 2005, Simon Howard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include + +#include "bloom-filter.h" + +struct _BloomFilter { + BloomFilterHashFunc hash_func; + unsigned char *table; + unsigned int table_size; + unsigned int num_functions; +}; + +/* Salt values. These salts are XORed with the output of the hash + * function to give multiple unique hashes. */ + +static const int salts[] = { + 0x5cee4612, 0xb5587b1c, 0xa250f2b0, 0xa3bf6d2a, + 0x7a81bd1a, 0x92888d7f, 0x1dc977c7, 0xedc96624, + 0x920c85d9, 0xf16066b3, 0xc6f0d4b3, 0x2b76eb86, + 0xcacb3893, 0x493d81c5, 0xf5a133ac, 0x039740bf, + 0x162b8224, 0xf841de90, 0xc3e5090d, 0x3bce93a7, + 0xf1860334, 0xe832b5f1, 0xf5b6535b, 0xe4cf4fa6, + 0x8357b769, 0x1442b07a, 0x21c5863d, 0xabc0d846, + 0x6dc0d77a, 0x23a3992c, 0xe12179ba, 0xd81d1e23, + 0xcff4727b, 0xe957ecfb, 0xee8f391a, 0x426efa23, + 0x3a34ff2c, 0x8b875d94, 0x34fd0f63, 0xf159daae, + 0xaabab8b3, 0xa83a07ba, 0x4e54fb33, 0xfb82fab8, + 0x2ae2888f, 0xd1a307a8, 0xbe33322d, 0x87c73f86, + 0x7270fa7e, 0x68673c55, 0x2c8026d0, 0xead8e422, + 0xa3ee5132, 0xecb67767, 0x1c3b1ae5, 0x47adf5b6, + 0xf4518d30, 0x46e62797, 0x9889aa76, 0x1405aadf, + 0xf62f9124, 0x5c435ac5, 0x35b8dfe3, 0x651c08c5, +}; + + +BloomFilter *bloom_filter_new(unsigned int table_size, + BloomFilterHashFunc hash_func, + unsigned int num_functions) +{ + BloomFilter *filter; + + /* There is a limit on the number of functions which can be + * applied, due to the table size */ + + if (num_functions > sizeof(salts) / sizeof(*salts)) { + return NULL; + } + + /* Allocate bloom filter structure */ + + filter = malloc(sizeof(BloomFilter)); + + if (filter == NULL) { + return NULL; + } + + /* Allocate table, each entry is one bit; these are packed into + * bytes. When allocating we must round the length up to the nearest + * byte. */ + + filter->table = calloc((table_size + 7) / 8, 1); + + if (filter->table == NULL) { + free(filter); + return NULL; + } + + filter->num_functions = num_functions; + filter->table_size = table_size; + + return filter; +} + +void bloom_filter_free(BloomFilter *bloomfilter) +{ + free(bloomfilter->table); + free(bloomfilter); +} + +void bloom_filter_insert(BloomFilter *bloomfilter, void *value) +{ + unsigned long hash; + unsigned long subhash; + unsigned int index; + unsigned int i; + + /* Generate hash of the value to insert */ + + hash = bloomfilter->hash_func(value); + + /* Generate multiple unique hashes by XORing with values in the + * salt table. */ + + for (i=0; inum_functions; ++i) { + + /* Generate a unique hash */ + + subhash = hash ^ salts[i]; + + /* Find the index into the table */ + + index = subhash % bloomfilter->table_size; + + /* Insert into the table. + * index / 8 finds the byte index of the table, + * index % 8 gives the bit index within that byte to set. */ + + bloomfilter->table[index / 8] |= 1 << (index % 8); + } +} + +int bloom_filter_lookup(BloomFilter *bloomfilter, void *value) +{ + unsigned long hash; + unsigned long subhash; + unsigned int index; + unsigned int i; + unsigned char b; + int bit; + + /* Generate hash of the value to lookup */ + + hash = bloomfilter->hash_func(value); + + /* Generate multiple unique hashes by XORing with values in the + * salt table. */ + + for (i=0; inum_functions; ++i) { + + /* Generate a unique hash */ + + subhash = hash ^ salts[i]; + + /* Find the index into the table to test */ + + index = subhash % bloomfilter->table_size; + + /* The byte at index / 8 holds the value to test */ + + b = bloomfilter->table[index / 8]; + bit = 1 << (index % 8); + + /* Test if the particular bit is set; if it is not set, + * this value can not have been inserted. */ + + if ((b & bit) == 0) { + return 0; + } + } + + /* All necessary bits were set. This may indicate that the value + * was inserted, or the values could have been set through other + * insertions. */ + + return 1; +} + + diff --git a/src/bloom-filter.h b/src/bloom-filter.h new file mode 100644 index 0000000..01502fc --- /dev/null +++ b/src/bloom-filter.h @@ -0,0 +1,135 @@ + +/* + +Copyright (c) 2005, Simon Howard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +/** + * @file bloom-filter.h + * + * @brief Bloom filter + * + * A bloom filter is a space efficient data structure that can be + * used to test whether a given element is part of a set. Lookups + * will occasionally generate false positives, but never false + * negatives. + * + * To create a bloom filter, use @ref bloom_filter_new. To destroy a + * bloom filter, use @ref bloom_filter_free. + * + * To insert a value into a bloom filter, use @ref bloom_filter_insert. + * + * To query whether a value is part of the set, use + * @ref bloom_filter_lookup. + */ + +#ifndef ALGORITHM_BLOOM_FILTER_H +#define ALGORITHM_BLOOM_FILTER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A bloom filter structure. + */ + +typedef struct _BloomFilter BloomFilter; + +/** + * Hash function used to generate hash values for values inserted into a + * bloom filter. + * + * @param data The value to generate a hash value for. + * @return The hash value. + */ + +typedef unsigned long (*BloomFilterHashFunc)(void *data); + +/** + * Create a new bloom filter. + * + * @param table_size The size of the bloom filter. The greater + * the table size, the more elements can be + * stored, and the lesser the chance of false + * positives. + * @param num_functions Number of hash functions to apply to each + * element on insertion. This running time for + * insertion and lookups is proportional to this + * value. The more functions applied, the lesser + * the chance of false positives. The maximum + * number of functions is 64. + * @return A new hash table structure, or NULL if it + * was not possible to allocate the new bloom + * filter. + */ + +BloomFilter *bloom_filter_new(unsigned int table_size, + BloomFilterHashFunc hash_func, + unsigned int num_functions); + +/** + * Destroy a bloom filter. + * + * @param bloomfilter The bloom filter to destroy. + */ + +void bloom_filter_free(BloomFilter *bloomfilter); + +/** + * Insert a value into a bloom filter. + * + * @param bloomfilter The bloom filter. + * @param value The value to insert. + */ + +void bloom_filter_insert(BloomFilter *bloomfilter, void *value); + +/** + * Query a bloom filter for a particular value. + * + * @param bloomfilter The bloom filter. + * @param value The value to look up. + * @return Zero if the value was definitely not + * inserted into the filter. Non-zero + * indicates that it either may or may not + * have been inserted. + */ + +int bloom_filter_lookup(BloomFilter *bloomfilter, void *value); + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef ALGORITHM_BLOOM_FILTER_H */ + From 2b38dc6a52a913b28ac039217a224efd4245f712 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 15 Nov 2006 19:32:53 +0000 Subject: [PATCH 028/250] Make salts unsigned. --- src/bloom-filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bloom-filter.c b/src/bloom-filter.c index 472bc03..fd255c7 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -47,7 +47,7 @@ struct _BloomFilter { /* Salt values. These salts are XORed with the output of the hash * function to give multiple unique hashes. */ -static const int salts[] = { +static const unsigned int salts[] = { 0x5cee4612, 0xb5587b1c, 0xa250f2b0, 0xa3bf6d2a, 0x7a81bd1a, 0x92888d7f, 0x1dc977c7, 0xedc96624, 0x920c85d9, 0xf16066b3, 0xc6f0d4b3, 0x2b76eb86, From 8b12e057ddd1b366d1a326ec5c08e2208eeddbb6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 15 Nov 2006 19:43:25 +0000 Subject: [PATCH 029/250] Add bloom filter read/load functions. --- src/bloom-filter.c | 30 +++++++++++++++++++++++++++++- src/bloom-filter.h | 25 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/bloom-filter.c b/src/bloom-filter.c index fd255c7..59d4c2b 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include "bloom-filter.h" @@ -66,7 +67,6 @@ static const unsigned int salts[] = { 0xf62f9124, 0x5c435ac5, 0x35b8dfe3, 0x651c08c5, }; - BloomFilter *bloom_filter_new(unsigned int table_size, BloomFilterHashFunc hash_func, unsigned int num_functions) @@ -189,4 +189,32 @@ int bloom_filter_lookup(BloomFilter *bloomfilter, void *value) return 1; } +void bloom_filter_read(BloomFilter *bloomfilter, unsigned char *array) +{ + unsigned int array_size; + + /* The table is an array of bits, packed into bytes. Round up + * to the nearest byte. */ + + array_size = (bloomfilter->table_size + 7) / 8; + + /* Copy into the buffer of the calling routine. */ + + memcpy(array, bloomfilter->table, array_size); +} + +void bloom_filter_load(BloomFilter *bloomfilter, unsigned char *array) +{ + unsigned int array_size; + + /* The table is an array of bits, packed into bytes. Round up + * to the nearest byte. */ + + array_size = (bloomfilter->table_size + 7) / 8; + + /* Copy from the buffer of the calling routine. */ + + memcpy(bloomfilter->table, array, array_size); +} + diff --git a/src/bloom-filter.h b/src/bloom-filter.h index 01502fc..1786748 100644 --- a/src/bloom-filter.h +++ b/src/bloom-filter.h @@ -127,6 +127,31 @@ void bloom_filter_insert(BloomFilter *bloomfilter, void *value); int bloom_filter_lookup(BloomFilter *bloomfilter, void *value); +/** + * Read the contents of a bloom filter into an array. + * + * @param bloomfilter The bloom filter. + * @param array Pointer to the array to read into. This + * should be (table_size + 7) / 8 bytes in + * length. + */ + +void bloom_filter_read(BloomFilter *bloomfilter, unsigned char *array); + +/** + * Load the contents of a bloom filter from an array. + * The data loaded should be the output read from @ref bloom_filter_read, + * from a bloom filter created using the same arguments used to create + * the original filter. + * + * @param bloomfilter The bloom filter. + * @param array Pointer to the array to load from. This + * should be (table_size + 7) / 8 bytes in + * length. + */ + +void bloom_filter_load(BloomFilter *bloomfilter, unsigned char *array); + #ifdef __cplusplus } #endif From 11e3e6969edb4ba6c35cc48a52648bfba6526aa6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 15 Nov 2006 19:56:21 +0000 Subject: [PATCH 030/250] Add bloom filter union/intersection functions. --- src/bloom-filter.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++ src/bloom-filter.h | 40 ++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/src/bloom-filter.c b/src/bloom-filter.c index 59d4c2b..b38f14b 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -217,4 +217,82 @@ void bloom_filter_load(BloomFilter *bloomfilter, unsigned char *array) memcpy(bloomfilter->table, array, array_size); } +BloomFilter *bloom_filter_union(BloomFilter *filter1, BloomFilter *filter2) +{ + BloomFilter *result; + unsigned int i; + unsigned int array_size; + + /* To perform this operation, both filters must be created with + * the same values. */ + + if (filter1->table_size != filter2->table_size + || filter1->num_functions != filter2->num_functions + || filter1->hash_func != filter2->hash_func) { + return NULL; + } + + /* Create a new bloom filter for the result */ + + result = bloom_filter_new(filter1->table_size, + filter1->hash_func, + filter1->num_functions); + + if (result == NULL) { + return NULL; + } + + /* The table is an array of bits, packed into bytes. Round up + * to the nearest byte. */ + + array_size = (filter1->table_size + 7) / 8; + + /* Populate the table of the new filter */ + + for (i=0; itable[i] = filter1->table[i] | filter2->table[i]; + } + + return result; +} + +BloomFilter *bloom_filter_intersection(BloomFilter *filter1, + BloomFilter *filter2) +{ + BloomFilter *result; + unsigned int i; + unsigned int array_size; + + /* To perform this operation, both filters must be created with + * the same values. */ + + if (filter1->table_size != filter2->table_size + || filter1->num_functions != filter2->num_functions + || filter1->hash_func != filter2->hash_func) { + return NULL; + } + + /* Create a new bloom filter for the result */ + + result = bloom_filter_new(filter1->table_size, + filter1->hash_func, + filter1->num_functions); + + if (result == NULL) { + return NULL; + } + + /* The table is an array of bits, packed into bytes. Round up + * to the nearest byte. */ + + array_size = (filter1->table_size + 7) / 8; + + /* Populate the table of the new filter */ + + for (i=0; itable[i] = filter1->table[i] & filter2->table[i]; + } + + return result; +} diff --git a/src/bloom-filter.h b/src/bloom-filter.h index 1786748..8e27d48 100644 --- a/src/bloom-filter.h +++ b/src/bloom-filter.h @@ -152,6 +152,46 @@ void bloom_filter_read(BloomFilter *bloomfilter, unsigned char *array); void bloom_filter_load(BloomFilter *bloomfilter, unsigned char *array); +/** + * Find the union of two bloom filters. Values are present in the + * resulting filter if they are present in either of the original + * filters. + * + * Both of the original filters must have been created using the + * same parameters to @ref bloom_filter_new. + * + * @param filter1 The first filter. + * @param filter2 The second filter. + * @return A new filter which is an intersection of the + * two filters, or NULL if it was not possible + * to allocate memory for the new filter, or + * if the two filters specified were created + * with different parameters. + */ + +BloomFilter *bloom_filter_union(BloomFilter *filter1, + BloomFilter *filter2); + +/** + * Find the intersection of two bloom filters. Values are only ever + * present in the resulting filter if they are present in both of the + * original filters. + * + * Both of the original filters must have been created using the + * same parameters to @ref bloom_filter_new. + * + * @param filter1 The first filter. + * @param filter2 The second filter. + * @return A new filter which is an intersection of the + * two filters, or NULL if it was not possible + * to allocate memory for the new filter, or + * if the two filters specified were created + * with different parameters. + */ + +BloomFilter *bloom_filter_intersection(BloomFilter *filter1, + BloomFilter *filter2); + #ifdef __cplusplus } #endif From 3ec9a9f83746f10ad4fa09e5b8a896999efad3aa Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 15 Nov 2006 23:34:14 +0000 Subject: [PATCH 031/250] Rename bloom_filter_lookup to bloom_filter_query to be consistent with the set data structure. --- src/bloom-filter.c | 2 +- src/bloom-filter.h | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/bloom-filter.c b/src/bloom-filter.c index b38f14b..770d4d6 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -143,7 +143,7 @@ void bloom_filter_insert(BloomFilter *bloomfilter, void *value) } } -int bloom_filter_lookup(BloomFilter *bloomfilter, void *value) +int bloom_filter_query(BloomFilter *bloomfilter, void *value) { unsigned long hash; unsigned long subhash; diff --git a/src/bloom-filter.h b/src/bloom-filter.h index 8e27d48..b16b97c 100644 --- a/src/bloom-filter.h +++ b/src/bloom-filter.h @@ -49,7 +49,7 @@ POSSIBILITY OF SUCH DAMAGE. * To insert a value into a bloom filter, use @ref bloom_filter_insert. * * To query whether a value is part of the set, use - * @ref bloom_filter_lookup. + * @ref bloom_filter_query. */ #ifndef ALGORITHM_BLOOM_FILTER_H @@ -82,9 +82,11 @@ typedef unsigned long (*BloomFilterHashFunc)(void *data); * the table size, the more elements can be * stored, and the lesser the chance of false * positives. + * @param hash_func Hash function to use on values stored in the + * filter. * @param num_functions Number of hash functions to apply to each * element on insertion. This running time for - * insertion and lookups is proportional to this + * insertion and queries is proportional to this * value. The more functions applied, the lesser * the chance of false positives. The maximum * number of functions is 64. @@ -125,7 +127,7 @@ void bloom_filter_insert(BloomFilter *bloomfilter, void *value); * have been inserted. */ -int bloom_filter_lookup(BloomFilter *bloomfilter, void *value); +int bloom_filter_query(BloomFilter *bloomfilter, void *value); /** * Read the contents of a bloom filter into an array. From 2f7659cb4098c23b707b39a00e78ab7215779603 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 15 Nov 2006 23:35:18 +0000 Subject: [PATCH 032/250] Add bloom filter to front page in documentation. Fix documentation warnings. --- doc/intro.h | 1 + src/list.h | 8 ++++---- src/set.h | 2 +- src/slist.h | 10 +++++----- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/intro.h b/doc/intro.h index 9b897ae..0964c5e 100644 --- a/doc/intro.h +++ b/doc/intro.h @@ -60,6 +60,7 @@ POSSIBILITY OF SUCH DAMAGE. * @li @link queue.h Queue @endlink: Double ended queue which can be used * as a FIFO or a stack. * @li @link set.h Set @endlink: Unordered set of values. + * @li @link bloom-filter.h Bloom Filter @endlink: Space-efficient set. * * @subsection Mappings * diff --git a/src/list.h b/src/list.h index e716e65..6547e34 100644 --- a/src/list.h +++ b/src/list.h @@ -276,7 +276,7 @@ ListIterator *list_iterate(ListEntry **list); * read. */ -int list_iter_has_more(ListIterator *iter); +int list_iter_has_more(ListIterator *iterator); /** * Using a list iterator, retrieve the next value from the list. @@ -286,7 +286,7 @@ int list_iter_has_more(ListIterator *iter); * no more values in the list. */ -void *list_iter_next(ListIterator *iter); +void *list_iter_next(ListIterator *iterator); /** * Delete the current entry in the list (the value last returned from @@ -295,7 +295,7 @@ void *list_iter_next(ListIterator *iter); * @param iterator The list iterator. */ -void list_iter_remove(ListIterator *iter); +void list_iter_remove(ListIterator *iterator); /** * Free back a list iterator. @@ -303,7 +303,7 @@ void list_iter_remove(ListIterator *iter); * @param iterator The list iterator. */ -void list_iter_free(ListIterator *iter); +void list_iter_free(ListIterator *iterator); #endif /* #ifndef ALGORITHM_LIST_H */ diff --git a/src/set.h b/src/set.h index e19f561..f45e9c4 100644 --- a/src/set.h +++ b/src/set.h @@ -51,7 +51,7 @@ POSSIBILITY OF SUCH DAMAGE. * * To query if a particular value is in a set, use @ref set_query. * - * To iterate over all values in a set, use @ref set_foreach. + * To iterate over all values in a set, use @ref set_iterate. */ #ifndef ALGORITHM_SET_H diff --git a/src/slist.h b/src/slist.h index d5b9167..553a55a 100644 --- a/src/slist.h +++ b/src/slist.h @@ -248,7 +248,7 @@ SListEntry *slist_find_data(SListEntry *list, void *data); /** - * Create a new @reg SListIterator structure to iterate over a list. + * Create a new @ref SListIterator structure to iterate over a list. * The iterator should be freed once iterating has completed, using * the function @ref list_iter_free. * @@ -269,7 +269,7 @@ SListIterator *slist_iterate(SListEntry **list); * read. */ -int slist_iter_has_more(SListIterator *iter); +int slist_iter_has_more(SListIterator *iterator); /** * Using a list iterator, retrieve the next value from the list. @@ -279,7 +279,7 @@ int slist_iter_has_more(SListIterator *iter); * no more values in the list. */ -void *slist_iter_next(SListIterator *iter); +void *slist_iter_next(SListIterator *iterator); /** * Delete the current entry in the list (the value last returned from @@ -288,7 +288,7 @@ void *slist_iter_next(SListIterator *iter); * @param iterator The list iterator. */ -void slist_iter_remove(SListIterator *iter); +void slist_iter_remove(SListIterator *iterator); /** * Free back a list iterator. @@ -296,7 +296,7 @@ void slist_iter_remove(SListIterator *iter); * @param iterator The list iterator. */ -void slist_iter_free(SListIterator *iter); +void slist_iter_free(SListIterator *iterator); #endif /* #ifndef ALGORITHM_SLIST_H */ From 2fca133b1faf9a0a1f18df70033f86c9f92df9f0 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 20 Nov 2006 17:54:07 +0000 Subject: [PATCH 033/250] Add bloom filter test case. --- test/Makefile.am | 1 + test/test-bloom-filter.c | 149 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 test/test-bloom-filter.c diff --git a/test/Makefile.am b/test/Makefile.am index 45bec85..22778dc 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -3,6 +3,7 @@ TESTS = \ test-arraylist \ test-avltree \ test-binary-heap \ + test-bloom-filter \ test-list \ test-slist \ test-queue \ diff --git a/test/test-bloom-filter.c b/test/test-bloom-filter.c new file mode 100644 index 0000000..31d4f38 --- /dev/null +++ b/test/test-bloom-filter.c @@ -0,0 +1,149 @@ + +#include +#include +#include + +#include "bloom-filter.h" +#include "hash-string.h" + +void test_bloom_filter_new_free(void) +{ + BloomFilter *filter; + + filter = bloom_filter_new(128, string_hash, 1); + + assert(filter != NULL); + + filter = bloom_filter_new(128, string_hash, 64); + + assert(filter != NULL); +} + +void test_bloom_filter_insert_query(void) +{ + BloomFilter *filter; + + /* Create a filter */ + + filter = bloom_filter_new(128, string_hash, 4); + + /* Check values are not present at the start */ + + assert(bloom_filter_query(filter, "test 1") == 0); + assert(bloom_filter_query(filter, "test 2") == 0); + + /* Insert some values */ + + bloom_filter_insert(filter, "test 1"); + bloom_filter_insert(filter, "test 2"); + + /* Check they are set */ + + assert(bloom_filter_query(filter, "test 1") != 0); + assert(bloom_filter_query(filter, "test 2") != 0); +} + +void test_bloom_filter_read_load(void) +{ + BloomFilter *filter1; + BloomFilter *filter2; + unsigned char state[16]; + + /* Create a filter with some values set */ + + filter1 = bloom_filter_new(128, string_hash, 4); + + bloom_filter_insert(filter1, "test 1"); + bloom_filter_insert(filter1, "test 2"); + + /* Read the current state into an array */ + + bloom_filter_read(filter1, state); + + /* Create a new filter and load the state */ + + filter2 = bloom_filter_new(128, string_hash, 4); + + bloom_filter_load(filter2, state); + + /* Check the values are set in the new filter */ + + assert(bloom_filter_query(filter1, "test 1") != 0); + assert(bloom_filter_query(filter1, "test 2") != 0); +} + +void test_bloom_filter_intersection(void) +{ + BloomFilter *filter1; + BloomFilter *filter2; + BloomFilter *result; + + /* Create one filter with both values set */ + + filter1 = bloom_filter_new(128, string_hash, 4); + + bloom_filter_insert(filter1, "test 1"); + bloom_filter_insert(filter1, "test 2"); + + /* Create second filter with only one value set */ + + filter2 = bloom_filter_new(128, string_hash, 4); + + bloom_filter_insert(filter2, "test 1"); + + /* For this test, we need this to be definitely not present. + * Note that this could theoretically return non-zero here, + * depending on the hash function. */ + + assert(bloom_filter_query(filter2, "test 2") == 0); + + /* Intersection */ + + result = bloom_filter_intersection(filter1, filter2); + + /* test 1 should be set, as it is in both + * test 2 should not be set, as it is not present in both */ + + assert(bloom_filter_query(result, "test 1") != 0); + assert(bloom_filter_query(result, "test 2") == 0); +} + +void test_bloom_filter_union(void) +{ + BloomFilter *filter1; + BloomFilter *filter2; + BloomFilter *result; + + /* Create one filter with both values set */ + + filter1 = bloom_filter_new(128, string_hash, 4); + + bloom_filter_insert(filter1, "test 1"); + + /* Create second filter with only one value set */ + + filter2 = bloom_filter_new(128, string_hash, 4); + + bloom_filter_insert(filter2, "test 2"); + + /* Union */ + + result = bloom_filter_union(filter1, filter2); + + /* Both should be present */ + + assert(bloom_filter_query(result, "test 1") != 0); + assert(bloom_filter_query(result, "test 2") != 0); +} + +int main(int argc, char *argv[]) +{ + test_bloom_filter_new_free(); + test_bloom_filter_insert_query(); + test_bloom_filter_read_load(); + test_bloom_filter_intersection(); + test_bloom_filter_union(); + + return 0; +} + From 102d4512090e58bca3b7ee3aad38b4b6549e6ee6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 20 Nov 2006 17:54:29 +0000 Subject: [PATCH 034/250] Fix bloom filter. --- src/bloom-filter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bloom-filter.c b/src/bloom-filter.c index 770d4d6..7db7876 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -99,6 +99,7 @@ BloomFilter *bloom_filter_new(unsigned int table_size, return NULL; } + filter->hash_func = hash_func; filter->num_functions = num_functions; filter->table_size = table_size; From 2947e94dccfcadbaf5b916dfa27262d6b27f1d55 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 20 Nov 2006 17:55:53 +0000 Subject: [PATCH 035/250] Add binomial heap. --- src/Makefile.am | 4 +- src/binomial-heap.c | 475 ++++++++++++++++++++++++++++++++++++++ src/binomial-heap.h | 142 ++++++++++++ test/Makefile.am | 1 + test/test-binomial-heap.c | 138 +++++++++++ 5 files changed, 758 insertions(+), 2 deletions(-) create mode 100644 src/binomial-heap.c create mode 100644 src/binomial-heap.h create mode 100644 test/test-binomial-heap.c diff --git a/src/Makefile.am b/src/Makefile.am index 9f83dc7..63a6ea8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,13 +9,13 @@ CALG_HEADERFILES=\ arraylist.h compare-int.h hash-int.h hashtable.h set.h \ avltree.h compare-pointer.h hash-pointer.h list.h slist.h \ queue.h compare-string.h hash-string.h trie.h binary-heap.h \ -bloom-filter.h +bloom-filter.h binomial-heap.h SRC=\ arraylist.c compare-pointer.c hash-pointer.c list.c slist.c \ avltree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hashtable.c set.c binary-heap.c \ -bloom-filter.c +bloom-filter.c binomial-heap.c libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) diff --git a/src/binomial-heap.c b/src/binomial-heap.c new file mode 100644 index 0000000..0bcd708 --- /dev/null +++ b/src/binomial-heap.c @@ -0,0 +1,475 @@ + +/* + +Copyright (c) 2005, Simon Howard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include + +#include "binomial-heap.h" + +typedef struct _BinomialTree BinomialTree; + +struct _BinomialTree +{ + void *value; + unsigned short order; + unsigned short refcount; + BinomialTree **subtrees; +}; + +struct _BinomialHeap +{ + BinomialHeapType heap_type; + BinomialHeapCompareFunc compare_func; + int num_values; + BinomialTree **roots; + int roots_length; +}; + +static int binomial_heap_cmp(BinomialHeap *heap, void *data1, void *data2) +{ + if (heap->heap_type == BINOMIAL_HEAP_TYPE_MIN) { + return heap->compare_func(data1, data2); + } else { + return -(heap->compare_func(data1, data2)); + } +} + +static void binomial_tree_ref(BinomialTree *tree) +{ + if (tree != NULL) { + ++tree->refcount; + } +} + +static void binomial_tree_unref(BinomialTree *tree) +{ + int i; + + if (tree == NULL) { + return; + } + + /* Subtract a reference */ + + --tree->refcount; + + /* If this removed the last reference, unreference all subtrees + * and free. */ + + if (tree->refcount == 0) { + + for (i=0; iorder; ++i) { + binomial_tree_unref(tree->subtrees[i]); + } + + free(tree->subtrees); + free(tree); + } +} + +static BinomialTree *binomial_tree_merge(BinomialHeap *heap, + BinomialTree *tree1, + BinomialTree *tree2) +{ + BinomialTree *new_tree; + BinomialTree *tmp; + int i; + + /* Order tree1 and tree2 so that tree1 is the tree with the + * smallest root */ + + if (binomial_heap_cmp(heap, tree1->value, tree2->value) > 0) { + + /* Swap tree1 and tree2 */ + + tmp = tree1; + tree1 = tree2; + tree2 = tmp; + } + + /* Allocate a new tree */ + + new_tree = malloc(sizeof(BinomialTree)); + + if (new_tree == NULL) { + return NULL; + } + + new_tree->order = tree1->order + 1; + + /* Take the smallest value of the two trees */ + + new_tree->value = tree1->value; + + /* Copy subtrees of the smallest tree. The last entry in the + * array is the larger tree */ + + new_tree->subtrees = malloc(sizeof(BinomialTree *) * new_tree->order); + memcpy(new_tree->subtrees, tree1->subtrees, + sizeof(BinomialTree *) * tree1->order); + new_tree->subtrees[new_tree->order - 1] = tree2; + + /* Add a reference to each of the subtrees we have referenced */ + + for (i=0; iorder; ++i) { + binomial_tree_ref(new_tree->subtrees[i]); + } + + return new_tree; +} + +/* Used to perform an "undo" when an error occurs during + * binomial_heap_merge. Go through the list of roots so far and remove + * references that have been added. */ + +static void binomial_heap_merge_undo(BinomialTree **new_roots, int count) +{ + int i; + + for (i=0; i<=count; ++i) { + binomial_tree_unref(new_roots[i]); + } + + free(new_roots); +} + +/* Merge the data in the 'other' heap into the 'heap' heap. + * Returns non-zero if successful. */ + +static int binomial_heap_merge(BinomialHeap *heap, BinomialHeap *other) +{ + BinomialTree **new_roots; + int new_roots_length; + BinomialTree *vals[3]; + int num_vals; + BinomialTree *carry; + BinomialTree *new_carry; + int i; + int max; + + /* Find the maximum length of the two heaps. Add one because + * after merging we may have one more value to carry over. */ + + if (heap->roots_length > other->roots_length) { + max = heap->roots_length + 1; + } else { + max = other->roots_length + 1; + } + + /* Allocate an array for the new roots */ + + new_roots = malloc(sizeof(BinomialTree *) * max); + + if (new_roots == NULL) { + return 0; + } + + /* Go through one entry at a time. This works kind of like a + * ripple-carry adder. */ + + new_roots_length = 0; + carry = NULL; + + for (i=0; iroots_length && heap->roots[i] != NULL) { + vals[num_vals] = heap->roots[i]; + ++num_vals; + } + + /* If there is a value in 'other', add it */ + + if (i < other->roots_length && other->roots[i] != NULL) { + vals[num_vals] = other->roots[i]; + ++num_vals; + } + + /* If there is a carried value from the previous iteration, + * add it */ + + if (carry != NULL) { + vals[num_vals] = carry; + ++num_vals; + } + + /* When num_vals == 1 or 3, we store a value. */ + + if ((num_vals & 1) != 0) { + + /* Save the last value into new_roots. */ + + new_roots[i] = vals[num_vals - 1]; + binomial_tree_ref(new_roots[i]); + new_roots_length = i + 1; + + } else { + + /* No value to store at this iteration */ + + new_roots[i] = NULL; + } + + /* When num_vals == 2 or 3, we must carry over to the + * next iteration */ + + if ((num_vals & 2) != 0) { + + /* Merge the first two values and carry to the + * next iteration */ + + new_carry = binomial_tree_merge(heap, + vals[0], + vals[1]); + + if (new_carry == NULL) { + + /* Remove references that we have added + * (freeing any BinomialTree structures + * that were created in the process) */ + + binomial_heap_merge_undo(new_roots, i); + + /* Unreference the carry variable */ + + binomial_tree_unref(carry); + + return 0; + } + + } else { + + /* Nothing to carry */ + + new_carry = NULL; + } + + /* Unreference previous carried value */ + + binomial_tree_unref(carry); + + /* Assign the new value of carry, and add a reference */ + + carry = new_carry; + + binomial_tree_ref(carry); + } + + /* Unreference all values in the old 'roots' array, freeing unused + * BinomialTree structures as necessary. */ + + for (i=0; iroots_length; ++i) { + if (heap->roots[i] != NULL) { + binomial_tree_unref(heap->roots[i]); + } + } + + /* Free the old roots array and use the new one */ + + free(heap->roots); + heap->roots = new_roots; + heap->roots_length = new_roots_length; + + /* Merged successfully */ + + return 1; +} + +BinomialHeap *binomial_heap_new(BinomialHeapType heap_type, + BinomialHeapCompareFunc compare_func) +{ + BinomialHeap *new_heap; + + /* Allocate a new heap */ + + new_heap = calloc(1, sizeof(BinomialHeap)); + + if (new_heap == NULL) { + return NULL; + } + + /* Initialise and return */ + + new_heap->heap_type = heap_type; + new_heap->compare_func = compare_func; + + return new_heap; +} + +void binomial_heap_free(BinomialHeap *heap) +{ + int i; + + /* Unreference all trees in the heap. This should free + * back all subtrees. */ + + for (i=0; iroots_length; ++i) { + binomial_tree_unref(heap->roots[i]); + } + + /* Free the heap itself */ + + free(heap->roots); + free(heap); +} + +int binomial_heap_insert(BinomialHeap *heap, void *value) +{ + BinomialHeap fake_heap; + BinomialTree *new_tree; + int result; + + /* Allocate an order 0 tree for storing the new value */ + + new_tree = malloc(sizeof(BinomialTree)); + + if (new_tree == NULL) { + return 0; + } + + /* Fill in values. This has an initial reference count of 1 that + * the "fake" heap holds; this will be removed at the end of + * this function. */ + + new_tree->value = value; + new_tree->order = 0; + new_tree->refcount = 1; + new_tree->subtrees = NULL; + + /* Build a fake heap structure for merging */ + + fake_heap.heap_type = heap->heap_type; + fake_heap.compare_func = heap->compare_func; + fake_heap.num_values = 1; + fake_heap.roots = &new_tree; + fake_heap.roots_length = 1; + + /* Perform the merge */ + + result = binomial_heap_merge(heap, &fake_heap); + + if (result != 0) { + ++heap->num_values; + } + + /* Remove reference to the new tree. */ + + binomial_tree_unref(new_tree); + + return result; +} + +void *binomial_heap_pop(BinomialHeap *heap) +{ + BinomialTree *least_tree; + BinomialHeap fake_heap; + void *result; + int least; + int i; + + if (heap->num_values == 0) { + return NULL; + } + + /* Find the tree with the lowest root value */ + + least = -1; + + for (i=0; iroots_length; ++i) { + + if (heap->roots[i] == NULL) { + continue; + } + + if (least < 0 + || binomial_heap_cmp(heap, + heap->roots[i]->value, + heap->roots[least]->value) < 0) { + least = i; + } + } + + /* Remove the least_tree from the heap. */ + + least_tree = heap->roots[least]; + heap->roots[least] = NULL; + + /* Construct a fake heap containing the data in the least tree */ + + fake_heap.heap_type = heap->heap_type; + fake_heap.compare_func = heap->compare_func; + fake_heap.roots = least_tree->subtrees; + fake_heap.roots_length = least_tree->order; + + /* Merge subtrees of least tree back into the heap */ + + if (binomial_heap_merge(heap, &fake_heap)) { + + /* Merge successful */ + + /* Remove reference to least tree */ + + result = least_tree->value; + binomial_tree_unref(least_tree); + + /* Update the number of values */ + + --heap->num_values; + + return result; + + } else { + + /* Add the least tree back */ + + heap->roots[least] = least_tree; + + /* Pop failed */ + + return NULL; + } +} + +int binomial_heap_num_entries(BinomialHeap *heap) +{ + return heap->num_values; +} + diff --git a/src/binomial-heap.h b/src/binomial-heap.h new file mode 100644 index 0000000..cd78335 --- /dev/null +++ b/src/binomial-heap.h @@ -0,0 +1,142 @@ + +/* + +Copyright (c) 2005, Simon Howard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +/** + * @file binomial-heap.h + * + * @brief Binomial heap. + * + * A binomial heap is a heap data structure implemented using a + * binomial tree. In a heap, values are ordered by priority. + * + * To create a binomial heap, use @ref binomial_heap_new. To destroy a + * binomial heap, use @ref binomial_heap_free. + * + * To insert a value into a binomial heap, use @ref binomial_heap_insert. + * + * To remove the first value from a binomial heap, use @ref binomial_heap_pop. + * + */ + +#ifndef ALGORITHM_BINOMIAL_HEAP_H +#define ALGORITHM_BINOMIAL_HEAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Heap type. If a heap is a min heap, the values with the lowest + * priority are stored at the top of the heap and will be the first + * returned. If a heap is a max heap, the values with the + * greatest priority are stored at the top of the heap. + */ + +typedef enum { + BINOMIAL_HEAP_TYPE_MIN, + BINOMIAL_HEAP_TYPE_MAX, +} BinomialHeapType; + +/** + * Type of function used to compare values in a binomial heap. + * + * @param data1 The first value. + * @param data2 The second value. + * @return A negative number if data1 is less than data2, + * a positive number if data1 is greater than data2, + * zero if the two are equal. + */ + +typedef int (*BinomialHeapCompareFunc)(void *data1, void *data2); + +/** + * A binomial heap data structure. + */ + +typedef struct _BinomialHeap BinomialHeap; + +/** + * Create a new @ref BinomialHeap. + * + * @param heap_type The type of heap: min heap or max heap. + * @param compare_func Pointer to a function used to compare the priority + * of values in the heap. + * @return A new binomial heap, or NULL if it was not possible + * to allocate the memory. + */ + +BinomialHeap *binomial_heap_new(BinomialHeapType heap_type, + BinomialHeapCompareFunc compare_func); + +/** + * Destroy a binomial heap. + * + * @param heap The heap to destroy. + */ + +void binomial_heap_free(BinomialHeap *heap); + +/** + * Insert a value into a binomial heap. + * + * @param heap The heap to insert into. + * @param value The value to insert. + * @return Non-zero if the entry was added, or zero if it + * was not possible to allocate memory for the new + * entry. + */ + +int binomial_heap_insert(BinomialHeap *heap, void *value); + +/** + * Remove the first value from a binomial heap. + * + * @param heap The heap. + * @return The first value in the heap. + */ + +void *binomial_heap_pop(BinomialHeap *heap); + +/** + * Find the number of values stored in a binomial heap. + * + * @param heap The heap. + * @return The number of values in the heap. + */ + +int binomial_heap_num_entries(BinomialHeap *heap); + +#endif /* #ifndef ALGORITHM_BINOMIAL_HEAP_H */ + diff --git a/test/Makefile.am b/test/Makefile.am index 22778dc..a3024a8 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -3,6 +3,7 @@ TESTS = \ test-arraylist \ test-avltree \ test-binary-heap \ + test-binomial-heap \ test-bloom-filter \ test-list \ test-slist \ diff --git a/test/test-binomial-heap.c b/test/test-binomial-heap.c new file mode 100644 index 0000000..03bf5ae --- /dev/null +++ b/test/test-binomial-heap.c @@ -0,0 +1,138 @@ + +/* + +Copyright (c) 2005, Simon Howard +All rights reserved. + +Redistribution and use in source and binomial forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binomial form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include + +#include "binomial-heap.h" +#include "compare-int.h" + +void test_binomial_heap_new_free(void) +{ + BinomialHeap *heap; + int i; + + for (i=0; i<1000; ++i) { + heap = binomial_heap_new(BINOMIAL_HEAP_TYPE_MIN, int_compare); + binomial_heap_free(heap); + } +} + +void test_binomial_heap_insert(void) +{ + BinomialHeap *heap; + int *val; + int i; + + heap = binomial_heap_new(BINOMIAL_HEAP_TYPE_MIN, int_compare); + + for (i=0; i<1000; ++i) { + val = malloc(sizeof(int)); + *val = i; + binomial_heap_insert(heap, val); + } + assert(binomial_heap_num_entries(heap) == 1000); + + binomial_heap_free(heap); +} + +void test_min_heap(void) +{ + BinomialHeap *heap; + int *val; + int i; + + heap = binomial_heap_new(BINOMIAL_HEAP_TYPE_MIN, int_compare); + + /* Push a load of values onto the heap */ + + for (i=0; i<1000; ++i) { + val = malloc(sizeof(int)); + *val = i; + binomial_heap_insert(heap, val); + } + + /* Pop values off the heap and check they are in order */ + + i = -1; + while (binomial_heap_num_entries(heap) > 0) { + val = (int *) binomial_heap_pop(heap); + + assert(*val == i + 1); + i = *val; + } + + binomial_heap_free(heap); +} + +void test_max_heap(void) +{ + BinomialHeap *heap; + int *val; + int i; + + heap = binomial_heap_new(BINOMIAL_HEAP_TYPE_MAX, int_compare); + + /* Push a load of values onto the heap */ + + for (i=0; i<1000; ++i) { + val = malloc(sizeof(int)); + *val = i; + binomial_heap_insert(heap, val); + } + + /* Pop values off the heap and check they are in order */ + + i = 1000; + while (binomial_heap_num_entries(heap) > 0) { + val = (int *) binomial_heap_pop(heap); + + assert(*val == i - 1); + i = *val; + } + + binomial_heap_free(heap); +} + +int main(int argc, char *argv[]) +{ + test_binomial_heap_new_free(); + test_binomial_heap_insert(); + test_min_heap(); + test_max_heap(); + + return 0; +} + From a0e8025eac4aa712a75bda4d53743939ab43f6d0 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 20 Nov 2006 17:58:58 +0000 Subject: [PATCH 036/250] Test formatting cleanups. --- test/test-binary-heap.c | 1 + test/test-set.c | 1 + test/test-trie.c | 6 +++--- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/test-binary-heap.c b/test/test-binary-heap.c index 5f87715..3bf08ef 100644 --- a/test/test-binary-heap.c +++ b/test/test-binary-heap.c @@ -129,6 +129,7 @@ void test_max_heap(void) int main(int argc, char *argv[]) { test_binary_heap_new_free(); + test_binary_heap_insert(); test_min_heap(); test_max_heap(); diff --git a/test/test-set.c b/test/test-set.c index d96dc39..2f9fdab 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -388,6 +388,7 @@ int main(int argc, char *argv[]) test_set_union(); test_set_iterating(); test_set_iterating_remove(); + test_set_to_array(); return 0; } diff --git a/test/test-trie.c b/test/test-trie.c index 4219181..c6c7914 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -40,7 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "trie.h" -void test_trie_new() +void test_trie_new(void) { Trie *trie; @@ -49,7 +49,7 @@ void test_trie_new() assert(trie != NULL); } -void test_trie_free() +void test_trie_free(void) { Trie *trie; @@ -80,7 +80,7 @@ void test_trie_free() trie_free(trie); } -void test_trie_insert_lookup_remove() +void test_trie_insert_lookup_remove(void) { Trie *trie; char buf[10]; From c92cfe476593d65d75c96c2bd75cdf9e7fdf0133 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 22 Nov 2006 00:04:55 +0000 Subject: [PATCH 037/250] Abstract key/values into separate types, so that these can be changed from "void *" if desired. --- src/arraylist.c | 24 +++++++++---------- src/arraylist.h | 20 ++++++++++------ src/avltree.c | 27 +++++++++++----------- src/avltree.h | 41 ++++++++++++++++++++++++--------- src/binary-heap.c | 20 ++++++++-------- src/binary-heap.h | 22 ++++++++++++++---- src/binomial-heap.c | 16 +++++++------ src/binomial-heap.h | 23 +++++++++++++++---- src/bloom-filter.c | 4 ++-- src/bloom-filter.h | 12 +++++++--- src/hashtable.c | 26 ++++++++++----------- src/hashtable.h | 56 +++++++++++++++++++++++++++++++++------------ src/list.c | 26 ++++++++++----------- src/list.h | 38 +++++++++++++++++++----------- src/queue.c | 26 ++++++++++----------- src/queue.h | 32 ++++++++++++++++++-------- src/slist.c | 26 ++++++++++----------- src/slist.h | 38 +++++++++++++++++++----------- src/trie.c | 16 ++++++------- src/trie.h | 20 ++++++++++++---- 20 files changed, 322 insertions(+), 191 deletions(-) diff --git a/src/arraylist.c b/src/arraylist.c index ee54a8e..d2f332e 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -64,7 +64,7 @@ ArrayList *arraylist_new(int length) /* Allocate the data array */ - new_arraylist->data = malloc(length * sizeof(void *)); + new_arraylist->data = malloc(length * sizeof(ArrayListValue)); if (new_arraylist->data == NULL) { free(new_arraylist); @@ -86,7 +86,7 @@ void arraylist_free(ArrayList *arraylist) static int arraylist_enlarge(ArrayList *arraylist) { - void **data; + ArrayListValue *data; int newsize; /* Double the allocated size */ @@ -95,7 +95,7 @@ static int arraylist_enlarge(ArrayList *arraylist) /* Reallocate the array to the new size */ - data = realloc(arraylist->data, sizeof(void *) * newsize); + data = realloc(arraylist->data, sizeof(ArrayListValue) * newsize); if (data == NULL) { return 0; @@ -107,7 +107,7 @@ static int arraylist_enlarge(ArrayList *arraylist) } } -int arraylist_insert(ArrayList *arraylist, int index, void *data) +int arraylist_insert(ArrayList *arraylist, int index, ArrayListValue data) { /* Sanity check the index */ @@ -128,7 +128,7 @@ int arraylist_insert(ArrayList *arraylist, int index, void *data) memmove(&arraylist->data[index + 1], &arraylist->data[index], - (arraylist->length - index) * sizeof(void *)); + (arraylist->length - index) * sizeof(ArrayListValue)); /* Insert the new entry at the index */ @@ -138,12 +138,12 @@ int arraylist_insert(ArrayList *arraylist, int index, void *data) return 1; } -int arraylist_append(ArrayList *arraylist, void *data) +int arraylist_append(ArrayList *arraylist, ArrayListValue data) { return arraylist_insert(arraylist, arraylist->length, data); } -int arraylist_prepend(ArrayList *arraylist, void *data) +int arraylist_prepend(ArrayList *arraylist, ArrayListValue data) { return arraylist_insert(arraylist, 0, data); } @@ -160,7 +160,7 @@ void arraylist_remove_range(ArrayList *arraylist, int index, int length) memmove(&arraylist->data[index], &arraylist->data[index + length], - (arraylist->length - (index + length)) * sizeof(void *)); + (arraylist->length - (index + length)) * sizeof(ArrayListValue)); /* Decrease the counter */ @@ -174,7 +174,7 @@ void arraylist_remove(ArrayList *arraylist, int index) int arraylist_index_of(ArrayList *arraylist, ArrayListEqualFunc callback, - void *data) + ArrayListValue data) { int i; @@ -193,11 +193,11 @@ void arraylist_clear(ArrayList *arraylist) arraylist->length = 0; } -static void arraylist_sort_internal(void **list_data, int list_length, +static void arraylist_sort_internal(ArrayListValue *list_data, int list_length, ArrayListCompareFunc compare_func) { - void *pivot; - void *tmp; + ArrayListValue pivot; + ArrayListValue tmp; int i; int list1_length; int list2_length; diff --git a/src/arraylist.h b/src/arraylist.h index fe06c46..f9361d9 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -58,6 +58,12 @@ POSSIBILITY OF SUCH DAMAGE. extern "C" { #endif +/** + * A value to be stored in an @ref ArrayList. + */ + +typedef void *ArrayListValue; + /** * An ArrayList structure. New ArrayLists can be created using the * arraylist_new function. @@ -69,7 +75,7 @@ typedef struct _ArrayList { /** Entries in the array */ - void **data; + ArrayListValue *data; /** Length of the array */ @@ -86,7 +92,7 @@ typedef struct _ArrayList { * @return Non-zero if the values are not equal, zero if they are equal. */ -typedef int (*ArrayListEqualFunc)(void *data1, void *data2); +typedef int (*ArrayListEqualFunc)(ArrayListValue data1, ArrayListValue data2); /** * Compare two values in an arraylist. Used by @ref arraylist_sort @@ -100,7 +106,7 @@ typedef int (*ArrayListEqualFunc)(void *data1, void *data2); * are equal. */ -typedef int (*ArrayListCompareFunc)(void *data1, void *data2); +typedef int (*ArrayListCompareFunc)(ArrayListValue data1, ArrayListValue data2); /** * Allocate a new ArrayList for use. @@ -132,7 +138,7 @@ void arraylist_free(ArrayList *arraylist); * for the new entry. */ -int arraylist_append(ArrayList *arraylist, void *data); +int arraylist_append(ArrayList *arraylist, ArrayListValue data); /** * Prepend data to the beginning of an ArrayList. @@ -144,7 +150,7 @@ int arraylist_append(ArrayList *arraylist, void *data); * for the new entry. */ -int arraylist_prepend(ArrayList *arraylist, void *data); +int arraylist_prepend(ArrayList *arraylist, ArrayListValue data); /** * Remove the entry at the specified location in an ArrayList. @@ -178,7 +184,7 @@ void arraylist_remove_range(ArrayList *arraylist, int index, int length); * if it was impossible to allocate more memory). */ -int arraylist_insert(ArrayList *arraylist, int index, void *data); +int arraylist_insert(ArrayList *arraylist, int index, ArrayListValue data); /** * Find the index of a particular pointer in an ArrayList. @@ -192,7 +198,7 @@ int arraylist_insert(ArrayList *arraylist, int index, void *data); int arraylist_index_of(ArrayList *arraylist, ArrayListEqualFunc callback, - void *data); + ArrayListValue data); /** * Remove all entries from an ArrayList. diff --git a/src/avltree.c b/src/avltree.c index 39e13e5..acdd8ca 100644 --- a/src/avltree.c +++ b/src/avltree.c @@ -43,8 +43,8 @@ struct _AVLTreeNode { AVLTreeNode *left_child; AVLTreeNode *right_child; AVLTreeNode *parent; - void *key; - void *value; + AVLTreeKey key; + AVLTreeValue value; int height; }; @@ -334,7 +334,7 @@ static AVLTreeNode *avltree_node_balance(AVLTree *tree, AVLTreeNode *node) return node; } -AVLTreeNode *avltree_insert(AVLTree *tree, void *key, void *value) +AVLTreeNode *avltree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) { AVLTreeNode **rover; AVLTreeNode *new_node; @@ -553,7 +553,7 @@ void avltree_remove_node(AVLTree *tree, AVLTreeNode *node) /* Remove a node by key */ -int avltree_remove(AVLTree *tree, void *key) +int avltree_remove(AVLTree *tree, AVLTreeKey key) { AVLTreeNode *node; @@ -574,7 +574,7 @@ int avltree_remove(AVLTree *tree, void *key) return 1; } -AVLTreeNode *avltree_lookup_node(AVLTree *tree, void *key) +AVLTreeNode *avltree_lookup_node(AVLTree *tree, AVLTreeKey key) { AVLTreeNode *node; int diff; @@ -606,7 +606,7 @@ AVLTreeNode *avltree_lookup_node(AVLTree *tree, void *key) return NULL; } -void *avltree_lookup(AVLTree *tree, void *key) +AVLTreeValue avltree_lookup(AVLTree *tree, AVLTreeKey key) { AVLTreeNode *node; @@ -615,7 +615,7 @@ void *avltree_lookup(AVLTree *tree, void *key) node = avltree_lookup_node(tree, key); if (node == NULL) { - return NULL; + return AVL_TREE_NULL; } else { return node->value; } @@ -626,13 +626,12 @@ AVLTreeNode *avltree_root_node(AVLTree *tree) return tree->root_node; } - -void *avltree_node_key(AVLTreeNode *node) +AVLTreeKey avltree_node_key(AVLTreeNode *node) { return node->key; } -void *avltree_node_value(AVLTreeNode *node) +AVLTreeValue avltree_node_value(AVLTreeNode *node) { return node->value; } @@ -658,7 +657,7 @@ int avltree_num_entries(AVLTree *tree) } static void avltree_to_array_add_subtree(AVLTreeNode *subtree, - void **array, + AVLTreeValue *array, int *index) { if (subtree == NULL) { @@ -679,14 +678,14 @@ static void avltree_to_array_add_subtree(AVLTreeNode *subtree, avltree_to_array_add_subtree(subtree->right_child, array, index); } -void **avltree_to_array(AVLTree *tree) +AVLTreeValue *avltree_to_array(AVLTree *tree) { - void **array; + AVLTreeValue *array; int index; /* Allocate the array */ - array = malloc(sizeof(void *) * tree->num_nodes); + array = malloc(sizeof(AVLTreeValue) * tree->num_nodes); if (array == NULL) { return NULL; diff --git a/src/avltree.h b/src/avltree.h index fc60d75..821deca 100644 --- a/src/avltree.h +++ b/src/avltree.h @@ -82,6 +82,24 @@ extern "C" { typedef struct _AVLTree AVLTree; +/** + * A key for an @ref AVLTree. + */ + +typedef void *AVLTreeKey; + +/** + * A value stored in an @ref AVLTree. + */ + +typedef void *AVLTreeValue; + +/** + * A null @ref AVLTreeValue. + */ + +#define AVL_TREE_NULL ((void *) 0) + /** * A node in an AVL tree. * @@ -105,13 +123,13 @@ typedef struct _AVLTreeNode AVLTreeNode; * are equal. */ -typedef int (*AVLTreeCompareFunc)(void *data1, void *data2); +typedef int (*AVLTreeCompareFunc)(AVLTreeValue data1, AVLTreeValue data2); /** * Create a new AVL tree. * * @param compare_func Function to use when comparing keys in the tree. - * @return A new AVL tree, or NULL if it was not possible + * @return A new AVL tree, or NULL if it was not possible * to allocate the memory. */ @@ -136,7 +154,7 @@ void avltree_free(AVLTree *tree); * to allocate the new memory. */ -AVLTreeNode *avltree_insert(AVLTree *tree, void *key, void *value); +AVLTreeNode *avltree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value); /** * Remove a node from a tree. @@ -158,7 +176,7 @@ void avltree_remove_node(AVLTree *tree, AVLTreeNode *node); * the specified key was removed. */ -int avltree_remove(AVLTree *tree, void *key); +int avltree_remove(AVLTree *tree, AVLTreeKey key); /** * Search an AVL tree for a node with a particular key. This uses @@ -170,7 +188,7 @@ int avltree_remove(AVLTree *tree, void *key); * if no entry with the given key is found. */ -AVLTreeNode *avltree_lookup_node(AVLTree *tree, void *key); +AVLTreeNode *avltree_lookup_node(AVLTree *tree, AVLTreeKey key); /** * Search an AVL tree for a value corresponding to a particular key. @@ -180,11 +198,12 @@ AVLTreeNode *avltree_lookup_node(AVLTree *tree, void *key); * * @param tree The AVL tree to search. * @param key The key to search for. - * @return The value associated with the given key, or NULL - * if no entry with the given key is found. + * @return The value associated with the given key, or + * AVLTREE_NULL if no entry with the given key is + * found. */ -void *avltree_lookup(AVLTree *tree, void *key); +AVLTreeValue avltree_lookup(AVLTree *tree, AVLTreeKey key); /** * Find the root node of a tree. @@ -203,7 +222,7 @@ AVLTreeNode *avltree_root_node(AVLTree *tree); * @return The key to the given node. */ -void *avltree_node_key(AVLTreeNode *node); +AVLTreeKey avltree_node_key(AVLTreeNode *node); /** * Retrieve the value at a given tree node. @@ -212,7 +231,7 @@ void *avltree_node_key(AVLTreeNode *node); * @return The value at the given node. */ -void *avltree_node_value(AVLTreeNode *node); +AVLTreeValue avltree_node_value(AVLTreeNode *node); /** * Find the left child of a given tree node. @@ -264,7 +283,7 @@ int avltree_subtree_height(AVLTreeNode *node); * (see @ref avltree_num_entries). */ -void **avltree_to_array(AVLTree *tree); +AVLTreeValue *avltree_to_array(AVLTree *tree); /** * Retrieve the number of entries in the tree. diff --git a/src/binary-heap.c b/src/binary-heap.c index 750691f..59745f0 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -39,13 +39,13 @@ POSSIBILITY OF SUCH DAMAGE. struct _BinaryHeap { BinaryHeapType heap_type; - void **values; + BinaryHeapValue *values; int num_values; int alloced_size; BinaryHeapCompareFunc compare_func; }; -static int binary_heap_cmp(BinaryHeap *heap, void *data1, void *data2) +static int binary_heap_cmp(BinaryHeap *heap, BinaryHeapValue data1, BinaryHeapValue data2) { if (heap->heap_type == BINARY_HEAP_TYPE_MIN) { return heap->compare_func(data1, data2); @@ -72,7 +72,7 @@ BinaryHeap *binary_heap_new(BinaryHeapType heap_type, /* Initial size of 16 elements */ heap->alloced_size = 16; - heap->values = malloc(sizeof(void *) * heap->alloced_size); + heap->values = malloc(sizeof(BinaryHeapValue) * heap->alloced_size); if (heap->values == NULL) { free(heap); @@ -88,9 +88,9 @@ void binary_heap_free(BinaryHeap *heap) free(heap); } -int binary_heap_insert(BinaryHeap *heap, void *value) +int binary_heap_insert(BinaryHeap *heap, BinaryHeapValue value) { - void **new_values; + BinaryHeapValue *new_values; int index; int newsize; int parent; @@ -102,7 +102,7 @@ int binary_heap_insert(BinaryHeap *heap, void *value) /* Double the table size */ newsize = heap->alloced_size * 2; - new_values = realloc(heap->values, sizeof(void *) * newsize); + new_values = realloc(heap->values, sizeof(BinaryHeapValue) * newsize); if (new_values == NULL) { return 0; @@ -152,10 +152,10 @@ int binary_heap_insert(BinaryHeap *heap, void *value) return 1; } -void *binary_heap_pop(BinaryHeap *heap) +BinaryHeapValue binary_heap_pop(BinaryHeap *heap) { - void *result; - void *new_value; + BinaryHeapValue result; + BinaryHeapValue new_value; int index; int next_index; int child1, child2; @@ -163,7 +163,7 @@ void *binary_heap_pop(BinaryHeap *heap) /* Empty heap? */ if (heap->num_values == 0) { - return NULL; + return BINARY_HEAP_NULL; } /* Take the value from the top of the heap */ diff --git a/src/binary-heap.h b/src/binary-heap.h index b0db265..61a6037 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -65,10 +65,22 @@ extern "C" { */ typedef enum { - BINARY_HEAP_TYPE_MIN, - BINARY_HEAP_TYPE_MAX, + BINARY_HEAP_TYPE_MIN, + BINARY_HEAP_TYPE_MAX, } BinaryHeapType; +/** + * A value stored in a @ref BinaryHeap. + */ + +typedef void *BinaryHeapValue; + +/** + * A null @ref BinaryHeapValue. + */ + +#define BINARY_HEAP_NULL ((void *) 0) + /** * Type of function used to compare values in a binary heap. * @@ -79,7 +91,7 @@ typedef enum { * zero if the two are equal. */ -typedef int (*BinaryHeapCompareFunc)(void *data1, void *data2); +typedef int (*BinaryHeapCompareFunc)(BinaryHeapValue data1, BinaryHeapValue data2); /** * A binary heap data structure. @@ -118,7 +130,7 @@ void binary_heap_free(BinaryHeap *heap); * entry. */ -int binary_heap_insert(BinaryHeap *heap, void *value); +int binary_heap_insert(BinaryHeap *heap, BinaryHeapValue value); /** * Remove the first value from a binary heap. @@ -127,7 +139,7 @@ int binary_heap_insert(BinaryHeap *heap, void *value); * @return The first value in the heap. */ -void *binary_heap_pop(BinaryHeap *heap); +BinaryHeapValue binary_heap_pop(BinaryHeap *heap); /** * Find the number of values stored in a binary heap. diff --git a/src/binomial-heap.c b/src/binomial-heap.c index 0bcd708..ce87de2 100644 --- a/src/binomial-heap.c +++ b/src/binomial-heap.c @@ -42,7 +42,7 @@ typedef struct _BinomialTree BinomialTree; struct _BinomialTree { - void *value; + BinomialHeapValue value; unsigned short order; unsigned short refcount; BinomialTree **subtrees; @@ -57,7 +57,9 @@ struct _BinomialHeap int roots_length; }; -static int binomial_heap_cmp(BinomialHeap *heap, void *data1, void *data2) +static int binomial_heap_cmp(BinomialHeap *heap, + BinomialHeapValue data1, + BinomialHeapValue data2) { if (heap->heap_type == BINOMIAL_HEAP_TYPE_MIN) { return heap->compare_func(data1, data2); @@ -351,7 +353,7 @@ void binomial_heap_free(BinomialHeap *heap) free(heap); } -int binomial_heap_insert(BinomialHeap *heap, void *value) +int binomial_heap_insert(BinomialHeap *heap, BinomialHeapValue value) { BinomialHeap fake_heap; BinomialTree *new_tree; @@ -397,16 +399,16 @@ int binomial_heap_insert(BinomialHeap *heap, void *value) return result; } -void *binomial_heap_pop(BinomialHeap *heap) +BinomialHeapValue binomial_heap_pop(BinomialHeap *heap) { BinomialTree *least_tree; BinomialHeap fake_heap; - void *result; + BinomialHeapValue result; int least; int i; if (heap->num_values == 0) { - return NULL; + return BINOMIAL_HEAP_NULL; } /* Find the tree with the lowest root value */ @@ -464,7 +466,7 @@ void *binomial_heap_pop(BinomialHeap *heap) /* Pop failed */ - return NULL; + return BINOMIAL_HEAP_NULL; } } diff --git a/src/binomial-heap.h b/src/binomial-heap.h index cd78335..9d80659 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -65,10 +65,22 @@ extern "C" { */ typedef enum { - BINOMIAL_HEAP_TYPE_MIN, - BINOMIAL_HEAP_TYPE_MAX, + BINOMIAL_HEAP_TYPE_MIN, + BINOMIAL_HEAP_TYPE_MAX, } BinomialHeapType; +/** + * A value stored in a @ref BinomialHeap. + */ + +typedef void *BinomialHeapValue; + +/** + * A null @ref BinomialHeapValue. + */ + +#define BINOMIAL_HEAP_NULL ((void *) 0) + /** * Type of function used to compare values in a binomial heap. * @@ -79,7 +91,8 @@ typedef enum { * zero if the two are equal. */ -typedef int (*BinomialHeapCompareFunc)(void *data1, void *data2); +typedef int (*BinomialHeapCompareFunc)(BinomialHeapValue data1, + BinomialHeapValue data2); /** * A binomial heap data structure. @@ -118,7 +131,7 @@ void binomial_heap_free(BinomialHeap *heap); * entry. */ -int binomial_heap_insert(BinomialHeap *heap, void *value); +int binomial_heap_insert(BinomialHeap *heap, BinomialHeapValue value); /** * Remove the first value from a binomial heap. @@ -127,7 +140,7 @@ int binomial_heap_insert(BinomialHeap *heap, void *value); * @return The first value in the heap. */ -void *binomial_heap_pop(BinomialHeap *heap); +BinomialHeapValue binomial_heap_pop(BinomialHeap *heap); /** * Find the number of values stored in a binomial heap. diff --git a/src/bloom-filter.c b/src/bloom-filter.c index 7db7876..33ccce1 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -112,7 +112,7 @@ void bloom_filter_free(BloomFilter *bloomfilter) free(bloomfilter); } -void bloom_filter_insert(BloomFilter *bloomfilter, void *value) +void bloom_filter_insert(BloomFilter *bloomfilter, BloomFilterValue value) { unsigned long hash; unsigned long subhash; @@ -144,7 +144,7 @@ void bloom_filter_insert(BloomFilter *bloomfilter, void *value) } } -int bloom_filter_query(BloomFilter *bloomfilter, void *value) +int bloom_filter_query(BloomFilter *bloomfilter, BloomFilterValue value) { unsigned long hash; unsigned long subhash; diff --git a/src/bloom-filter.h b/src/bloom-filter.h index b16b97c..24833d3 100644 --- a/src/bloom-filter.h +++ b/src/bloom-filter.h @@ -65,6 +65,12 @@ extern "C" { typedef struct _BloomFilter BloomFilter; +/** + * A value stored in a @ref BloomFilter. + */ + +typedef void *BloomFilterValue; + /** * Hash function used to generate hash values for values inserted into a * bloom filter. @@ -73,7 +79,7 @@ typedef struct _BloomFilter BloomFilter; * @return The hash value. */ -typedef unsigned long (*BloomFilterHashFunc)(void *data); +typedef unsigned long (*BloomFilterHashFunc)(BloomFilterValue data); /** * Create a new bloom filter. @@ -114,7 +120,7 @@ void bloom_filter_free(BloomFilter *bloomfilter); * @param value The value to insert. */ -void bloom_filter_insert(BloomFilter *bloomfilter, void *value); +void bloom_filter_insert(BloomFilter *bloomfilter, BloomFilterValue value); /** * Query a bloom filter for a particular value. @@ -127,7 +133,7 @@ void bloom_filter_insert(BloomFilter *bloomfilter, void *value); * have been inserted. */ -int bloom_filter_query(BloomFilter *bloomfilter, void *value); +int bloom_filter_query(BloomFilter *bloomfilter, BloomFilterValue value); /** * Read the contents of a bloom filter into an array. diff --git a/src/hashtable.c b/src/hashtable.c index a56d0a0..67fc5b5 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -43,8 +43,8 @@ POSSIBILITY OF SUCH DAMAGE. typedef struct _HashTableEntry HashTableEntry; struct _HashTableEntry { - void *key; - void *value; + HashTableKey key; + HashTableValue value; HashTableEntry *next; }; @@ -53,8 +53,8 @@ struct _HashTable { int table_size; HashTableHashFunc hash_func; HashTableEqualFunc equal_func; - HashTableFreeFunc key_free_func; - HashTableFreeFunc value_free_func; + HashTableKeyFreeFunc key_free_func; + HashTableValueFreeFunc value_free_func; int entries; int prime_index; }; @@ -185,8 +185,8 @@ void hash_table_free(HashTable *hashtable) } void hash_table_register_free_functions(HashTable *hashtable, - HashTableFreeFunc key_free_func, - HashTableFreeFunc value_free_func) + HashTableKeyFreeFunc key_free_func, + HashTableValueFreeFunc value_free_func) { hashtable->key_free_func = key_free_func; hashtable->value_free_func = value_free_func; @@ -250,7 +250,7 @@ static int hash_table_enlarge(HashTable *hashtable) return 1; } -int hash_table_insert(HashTable *hashtable, void *key, void *value) +int hash_table_insert(HashTable *hashtable, HashTableKey key, HashTableValue value) { HashTableEntry *rover; HashTableEntry *newentry; @@ -335,7 +335,7 @@ int hash_table_insert(HashTable *hashtable, void *key, void *value) return 1; } -void *hash_table_lookup(HashTable *hashtable, void *key) +HashTableValue hash_table_lookup(HashTable *hashtable, HashTableKey key) { HashTableEntry *rover; int index; @@ -361,10 +361,10 @@ void *hash_table_lookup(HashTable *hashtable, void *key) /* Not found */ - return NULL; + return HASH_TABLE_NULL; } -int hash_table_remove(HashTable *hashtable, void *key) +int hash_table_remove(HashTable *hashtable, HashTableKey key) { HashTableEntry **rover; HashTableEntry *entry; @@ -458,10 +458,10 @@ int hash_table_iter_has_more(HashTableIterator *iterator) return iterator->next_entry != NULL; } -void *hash_table_iter_next(HashTableIterator *iterator) +HashTableValue hash_table_iter_next(HashTableIterator *iterator) { HashTable *hashtable; - void *result; + HashTableValue result; int chain; hashtable = iterator->hashtable; @@ -469,7 +469,7 @@ void *hash_table_iter_next(HashTableIterator *iterator) /* No more entries? */ if (iterator->next_entry == NULL) { - return NULL; + return HASH_TABLE_NULL; } /* Result is immediately available */ diff --git a/src/hashtable.h b/src/hashtable.h index c70e632..61d3ed8 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -71,6 +71,24 @@ typedef struct _HashTable HashTable; typedef struct _HashTableIterator HashTableIterator; +/** + * A key to look up a value in a @ref HashTable. + */ + +typedef void *HashTableKey; + +/** + * A value stored in a @ref HashTable. + */ + +typedef void *HashTableValue; + +/** + * A null @ref HashTableValue. + */ + +#define HASH_TABLE_NULL ((void *) 0) + /** * Hash function used to generate hash values for keys used in a hash * table. @@ -79,7 +97,7 @@ typedef struct _HashTableIterator HashTableIterator; * @return The hash value. */ -typedef unsigned long (*HashTableHashFunc)(void *data); +typedef unsigned long (*HashTableHashFunc)(HashTableKey data); /** * Function used to compare two keys for equality. @@ -88,14 +106,21 @@ typedef unsigned long (*HashTableHashFunc)(void *data); * not equal. */ -typedef int (*HashTableEqualFunc)(void *data1, void *data2); +typedef int (*HashTableEqualFunc)(HashTableKey data1, HashTableKey data2); /** - * Type of function used to free keys and values when entries are - * removed from a hash table. + * Type of function used to free keys when entries are removed from a + * hash table. + */ + +typedef void (*HashTableKeyFreeFunc)(HashTableKey data); + +/** + * Type of function used to free values when entries are removed from a + * hash table. */ -typedef void (*HashTableFreeFunc)(void *data); +typedef void (*HashTableValueFreeFunc)(HashTableValue data); /** * Create a new hash table. @@ -130,8 +155,8 @@ void hash_table_free(HashTable *hashtable); */ void hash_table_register_free_functions(HashTable *hashtable, - HashTableFreeFunc key_free_func, - HashTableFreeFunc value_free_func); + HashTableKeyFreeFunc key_free_func, + HashTableValueFreeFunc value_free_func); /** * Insert a value into a hash table, overwriting any existing entry @@ -145,18 +170,18 @@ void hash_table_register_free_functions(HashTable *hashtable, * memory for the new entry. */ -int hash_table_insert(HashTable *hashtable, void *key, void *value); +int hash_table_insert(HashTable *hashtable, HashTableKey key, HashTableValue value); /** * Look up a value in a hash table by key. * * @param hashtable The hash table. * @param key The key of the value to look up. - * @return The value, or NULL if there is no value with - * that key in the hash table. + * @return The value, or @ref HASH_TABLE_NULL if there + * is no value with that key in the hash table. */ -void *hash_table_lookup(HashTable *hashtable, void *key); +HashTableValue hash_table_lookup(HashTable *hashtable, HashTableKey key); /** * Remove a value from a hash table. @@ -167,7 +192,7 @@ void *hash_table_lookup(HashTable *hashtable, void *key); * specified key was not found in the hash table. */ -int hash_table_remove(HashTable *hashtable, void *key); +int hash_table_remove(HashTable *hashtable, HashTableKey key); /** * Retrieve the number of entries in a hash table. @@ -208,11 +233,12 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * Using a hash table iterator, retrieve the next key. * * @param iterator The hash table iterator. - * @return The next key from the hash table, or NULL - * if there are no more keys to iterate over. + * @return The next key from the hash table, or + * @ref HASH_TABLE_NULL if there are no more + * keys to iterate over. */ -void *hash_table_iter_next(HashTableIterator *iterator); +HashTableValue hash_table_iter_next(HashTableIterator *iterator); /** * Free back a hash table iterator object. This must be done once diff --git a/src/list.c b/src/list.c index 25237e2..553762f 100644 --- a/src/list.c +++ b/src/list.c @@ -40,7 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. /* A doubly-linked list */ struct _ListEntry { - void *data; + ListValue data; ListEntry *prev; ListEntry *next; }; @@ -73,7 +73,7 @@ void list_free(ListEntry *list) } } -ListEntry *list_prepend(ListEntry **list, void *data) +ListEntry *list_prepend(ListEntry **list, ListValue data) { ListEntry *newentry; @@ -99,7 +99,7 @@ ListEntry *list_prepend(ListEntry **list, void *data) return newentry; } -ListEntry *list_append(ListEntry **list, void *data) +ListEntry *list_append(ListEntry **list, ListValue data) { ListEntry *rover; ListEntry *newentry; @@ -139,7 +139,7 @@ ListEntry *list_append(ListEntry **list, void *data) return newentry; } -void *list_data(ListEntry *listentry) +ListValue list_data(ListEntry *listentry) { return listentry->data; } @@ -181,7 +181,7 @@ ListEntry *list_nth_entry(ListEntry *list, int n) return entry; } -void *list_nth_data(ListEntry *list, int n) +ListValue list_nth_data(ListEntry *list, int n) { ListEntry *entry; @@ -192,7 +192,7 @@ void *list_nth_data(ListEntry *list, int n) /* If out of range, return NULL, otherwise return the data */ if (entry == NULL) { - return NULL; + return LIST_NULL; } else { return entry->data; } @@ -218,18 +218,18 @@ int list_length(ListEntry *list) return length; } -void **list_to_array(ListEntry *list) +ListValue *list_to_array(ListEntry *list) { ListEntry *rover; int listlen; - void **array; + ListValue *array; int i; /* Allocate an array equal in size to the list length */ listlen = list_length(list); - array = malloc(sizeof(void *) * listlen); + array = malloc(sizeof(ListValue) * listlen); if (array == NULL) { return NULL; @@ -301,7 +301,7 @@ int list_remove_entry(ListEntry **list, ListEntry *entry) return 1; } -int list_remove_data(ListEntry **list, ListEqualFunc callback, void *data) +int list_remove_data(ListEntry **list, ListEqualFunc callback, ListValue data) { int entries_removed; ListEntry *rover; @@ -458,7 +458,7 @@ void list_sort(ListEntry **list, ListCompareFunc compare_func) ListEntry *list_find_data(ListEntry *list, ListEqualFunc callback, - void *data) + ListValue data) { ListEntry *rover; @@ -525,7 +525,7 @@ int list_iter_has_more(ListIterator *iter) } } -void *list_iter_next(ListIterator *iter) +ListValue list_iter_next(ListIterator *iter) { if (iter->prev_next == NULL) { /* First call to list_iter_next. Initialise. */ @@ -560,7 +560,7 @@ void *list_iter_next(ListIterator *iter) /* Return data from the current entry */ if (iter->current == NULL) { - return NULL; + return LIST_NULL; } else { return iter->current->data; } diff --git a/src/list.h b/src/list.h index 6547e34..ff3d093 100644 --- a/src/list.h +++ b/src/list.h @@ -81,6 +81,18 @@ typedef struct _ListEntry ListEntry; typedef struct _ListIterator ListIterator; +/** + * A value stored in a @ref List. + */ + +typedef void *ListValue; + +/** + * A null @ref ListValue. + */ + +#define LIST_NULL ((void *) 0) + /** * Callback function used to compare values in a list when sorting. * @@ -91,7 +103,7 @@ typedef struct _ListIterator ListIterator; * after data2, zero if data1 and data2 are equal. */ -typedef int (*ListCompareFunc)(void *data1, void *data2); +typedef int (*ListCompareFunc)(ListValue data1, ListValue data2); /** * Callback function used to determine of two values in a list are @@ -103,7 +115,7 @@ typedef int (*ListCompareFunc)(void *data1, void *data2); * if they are not equal. */ -typedef int (*ListEqualFunc)(void *data1, void *data2); +typedef int (*ListEqualFunc)(ListValue data1, ListValue data2); /** * Free an entire list. @@ -122,7 +134,7 @@ void list_free(ListEntry *list); * to allocate the memory for the new entry. */ -ListEntry *list_prepend(ListEntry **list, void *data); +ListEntry *list_prepend(ListEntry **list, ListValue data); /** * Append data to the end of a list. @@ -133,7 +145,7 @@ ListEntry *list_prepend(ListEntry **list, void *data); * to allocate the memory for the new entry. */ -ListEntry *list_append(ListEntry **list, void *data); +ListEntry *list_append(ListEntry **list, ListValue data); /** * Retrieve the previous entry in a list. @@ -162,7 +174,7 @@ ListEntry *list_next(ListEntry *listentry); * @return The data at the list entry. */ -void *list_data(ListEntry *listentry); +ListValue list_data(ListEntry *listentry); /** * Retrieve the entry at a specified index in a list. @@ -179,11 +191,11 @@ ListEntry *list_nth_entry(ListEntry *list, int n); * * @param list The list. * @param n The index into the list . - * @return The data at the specified index, or NULL if + * @return The data at the specified index, or LIST_NULL if * unsuccessful. */ -void *list_nth_data(ListEntry *list, int n); +ListValue list_nth_data(ListEntry *list, int n); /** * Find the length of a list. @@ -204,7 +216,7 @@ int list_length(ListEntry *list); * of the list (see @ref list_length). */ -void **list_to_array(ListEntry *list); +ListValue *list_to_array(ListEntry *list); /** * Remove an entry from a list. @@ -227,7 +239,7 @@ int list_remove_entry(ListEntry **list, ListEntry *entry); * @return The number of entries removed from the list. */ -int list_remove_data(ListEntry **list, ListEqualFunc callback, void *data); +int list_remove_data(ListEntry **list, ListEqualFunc callback, ListValue data); /** * Sort a list. @@ -251,7 +263,7 @@ void list_sort(ListEntry **list, ListCompareFunc compare_func); ListEntry *list_find_data(ListEntry *list, ListEqualFunc callback, - void *data); + ListValue data); /** * Create an iterator to iterate over the values in a list. @@ -282,11 +294,11 @@ int list_iter_has_more(ListIterator *iterator); * Using a list iterator, retrieve the next value from the list. * * @param iterator The list iterator. - * @return The next value from the list, or NULL if there are - * no more values in the list. + * @return The next value from the list, or LIST_NULL if + * there are no more values in the list. */ -void *list_iter_next(ListIterator *iterator); +ListValue list_iter_next(ListIterator *iterator); /** * Delete the current entry in the list (the value last returned from diff --git a/src/queue.c b/src/queue.c index 1b70dc2..e67159d 100644 --- a/src/queue.c +++ b/src/queue.c @@ -42,7 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. typedef struct _QueueEntry QueueEntry; struct _QueueEntry { - void *data; + QueueValue data; QueueEntry *prev; QueueEntry *next; }; @@ -81,7 +81,7 @@ void queue_free(Queue *queue) free(queue); } -int queue_push_head(Queue *queue, void *data) +int queue_push_head(Queue *queue, QueueValue data) { QueueEntry *new_entry; @@ -122,15 +122,15 @@ int queue_push_head(Queue *queue, void *data) return 1; } -void *queue_pop_head(Queue *queue) +QueueValue queue_pop_head(Queue *queue) { QueueEntry *entry; - void *result; + QueueValue result; /* Check the queue is not empty */ if (queue_is_empty(queue)) { - return NULL; + return QUEUE_NULL; } /* Unlink the first entry from the head of the queue */ @@ -159,16 +159,16 @@ void *queue_pop_head(Queue *queue) return result; } -void *queue_peek_head(Queue *queue) +QueueValue queue_peek_head(Queue *queue) { if (queue_is_empty(queue)) { - return NULL; + return QUEUE_NULL; } else { return queue->head->data; } } -int queue_push_tail(Queue *queue, void *data) +int queue_push_tail(Queue *queue, QueueValue data) { QueueEntry *new_entry; @@ -209,15 +209,15 @@ int queue_push_tail(Queue *queue, void *data) return 1; } -void *queue_pop_tail(Queue *queue) +QueueValue queue_pop_tail(Queue *queue) { QueueEntry *entry; - void *result; + QueueValue result; /* Check the queue is not empty */ if (queue_is_empty(queue)) { - return NULL; + return QUEUE_NULL; } /* Unlink the first entry from the tail of the queue */ @@ -247,10 +247,10 @@ void *queue_pop_tail(Queue *queue) return result; } -void *queue_peek_tail(Queue *queue) +QueueValue queue_peek_tail(Queue *queue) { if (queue_is_empty(queue)) { - return NULL; + return QUEUE_NULL; } else { return queue->tail->data; } diff --git a/src/queue.h b/src/queue.h index 86eda52..3ea912d 100644 --- a/src/queue.h +++ b/src/queue.h @@ -67,6 +67,18 @@ extern "C" { typedef struct _Queue Queue; +/** + * A value stored in a @ref Queue. + */ + +typedef void *QueueValue; + +/** + * A null @ref QueueValue. + */ + +#define QUEUE_NULL ((void *) 0) + /** * Create a new double-ended queue. * @@ -94,28 +106,28 @@ void queue_free(Queue *queue); * new entry. */ -int queue_push_head(Queue *queue, void *data); +int queue_push_head(Queue *queue, QueueValue data); /** * Remove data from the head of a queue. * * @param queue The queue. - * @return Data at the head of the queue, or NULL if the + * @return Data at the head of the queue, or QUEUE_NULL if the * queue is empty. */ -void *queue_pop_head(Queue *queue); +QueueValue queue_pop_head(Queue *queue); /** * Read data from the head of queue, without removing it from * the queue. * * @param queue The queue. - * @return Data at the head of the queue, or NULL if the + * @return Data at the head of the queue, or QUEUE_NULL if the * queue is empty. */ -void *queue_peek_head(Queue *queue); +QueueValue queue_peek_head(Queue *queue); /** * Add data to the tail of a queue. @@ -127,28 +139,28 @@ void *queue_peek_head(Queue *queue); * new entry. */ -int queue_push_tail(Queue *queue, void *data); +int queue_push_tail(Queue *queue, QueueValue data); /** * Remove data from the tail of a queue. * * @param queue The queue. - * @return Data at the head of the queue, or NULL if the + * @return Data at the head of the queue, or QUEUE_NULL if the * queue is empty. */ -void *queue_pop_tail(Queue *queue); +QueueValue queue_pop_tail(Queue *queue); /** * Read data from the tail of queue, without removing it from * the queue. * * @param queue The queue. - * @return Data at the tail of the queue, or NULL if the + * @return Data at the tail of the queue, or QUEUE_NULL if the * queue is empty. */ -void *queue_peek_tail(Queue *queue); +QueueValue queue_peek_tail(Queue *queue); /** * Query if any data is currently in a queue. diff --git a/src/slist.c b/src/slist.c index 5663b9b..e26ba05 100644 --- a/src/slist.c +++ b/src/slist.c @@ -40,7 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. /* A singly-linked list */ struct _SListEntry { - void *data; + SListValue data; SListEntry *next; }; @@ -72,7 +72,7 @@ void slist_free(SListEntry *list) } } -SListEntry *slist_prepend(SListEntry **list, void *data) +SListEntry *slist_prepend(SListEntry **list, SListValue data) { SListEntry *newentry; @@ -94,7 +94,7 @@ SListEntry *slist_prepend(SListEntry **list, void *data) return newentry; } -SListEntry *slist_append(SListEntry **list, void *data) +SListEntry *slist_append(SListEntry **list, SListValue data) { SListEntry *rover; SListEntry *newentry; @@ -132,7 +132,7 @@ SListEntry *slist_append(SListEntry **list, void *data) return newentry; } -void *slist_data(SListEntry *listentry) +SListValue slist_data(SListEntry *listentry) { return listentry->data; } @@ -169,7 +169,7 @@ SListEntry *slist_nth_entry(SListEntry *list, int n) return entry; } -void *slist_nth_data(SListEntry *list, int n) +SListValue slist_nth_data(SListEntry *list, int n) { SListEntry *entry; @@ -180,7 +180,7 @@ void *slist_nth_data(SListEntry *list, int n) /* If out of range, return NULL, otherwise return the data */ if (entry == NULL) { - return NULL; + return SLIST_NULL; } else { return entry->data; } @@ -206,18 +206,18 @@ int slist_length(SListEntry *list) return length; } -void **slist_to_array(SListEntry *list) +SListValue *slist_to_array(SListEntry *list) { SListEntry *rover; int listlen; - void **array; + SListValue *array; int i; /* Allocate an array equal in size to the list length */ listlen = slist_length(list); - array = malloc(sizeof(void *) * listlen); + array = malloc(sizeof(SListValue) * listlen); if (array == NULL) { return NULL; @@ -293,7 +293,7 @@ int slist_remove_entry(SListEntry **list, SListEntry *entry) return 1; } -int slist_remove_data(SListEntry **list, SListEqualFunc callback, void *data) +int slist_remove_data(SListEntry **list, SListEqualFunc callback, SListValue data) { SListEntry **rover; SListEntry *next; @@ -425,7 +425,7 @@ void slist_sort(SListEntry **list, SListCompareFunc compare_func) SListEntry *slist_find_data(SListEntry *list, SListEqualFunc callback, - void *data) + SListValue data) { SListEntry *rover; @@ -493,7 +493,7 @@ int slist_iter_has_more(SListIterator *iter) } } -void *slist_iter_next(SListIterator *iter) +SListValue slist_iter_next(SListIterator *iter) { if (iter->prev_next == NULL) { @@ -527,7 +527,7 @@ void *slist_iter_next(SListIterator *iter) } if (iter->current == NULL) { - return NULL; + return SLIST_NULL; } else { return iter->current->data; } diff --git a/src/slist.h b/src/slist.h index 553a55a..05a2a4e 100644 --- a/src/slist.h +++ b/src/slist.h @@ -90,6 +90,18 @@ typedef struct _SListEntry SListEntry; typedef struct _SListIterator SListIterator; +/** + * Value stored in a @ref SList. + */ + +typedef void *SListValue; + +/** + * A null @ref SListValue. + */ + +#define SLIST_NULL ((void *) 0) + /** * Callback function used to compare values in a list when sorting. * @@ -98,7 +110,7 @@ typedef struct _SListIterator SListIterator; * zero if data1 and data2 are equal. */ -typedef int (*SListCompareFunc)(void *data1, void *data2); +typedef int (*SListCompareFunc)(SListValue data1, SListValue data2); /** * Callback function used to determine of two values in a list are @@ -108,7 +120,7 @@ typedef int (*SListCompareFunc)(void *data1, void *data2); * are not equal. */ -typedef int (*SListEqualFunc)(void *data1, void *data2); +typedef int (*SListEqualFunc)(SListValue data1, SListValue data2); /** * Free an entire list. @@ -127,7 +139,7 @@ void slist_free(SListEntry *list); * to allocate a new entry. */ -SListEntry *slist_prepend(SListEntry **list, void *data); +SListEntry *slist_prepend(SListEntry **list, SListValue data); /** * Append data to the end of a list. @@ -138,7 +150,7 @@ SListEntry *slist_prepend(SListEntry **list, void *data); * to allocate a new entry. */ -SListEntry *slist_append(SListEntry **list, void *data); +SListEntry *slist_append(SListEntry **list, SListValue data); /** * Retrieve the next entry in a list. @@ -156,7 +168,7 @@ SListEntry *slist_next(SListEntry *listentry); * @return The data at the list entry. */ -void *slist_data(SListEntry *listentry); +SListValue slist_data(SListEntry *listentry); /** * Retrieve the entry at a specified index in a list. @@ -173,11 +185,11 @@ SListEntry *slist_nth_entry(SListEntry *list, int n); * * @param list The list. * @param n The index into the list . - * @return The data at the specified index, or NULL if + * @return The data at the specified index, or @ref SLIST_NULL if * unsuccessful. */ -void *slist_nth_data(SListEntry *list, int n); +SListValue slist_nth_data(SListEntry *list, int n); /** * Find the length of a list. @@ -198,7 +210,7 @@ int slist_length(SListEntry *list); * equal to the length of the list (see @ref slist_length). */ -void **slist_to_array(SListEntry *list); +SListValue *slist_to_array(SListEntry *list); /** * Remove an entry from a list. @@ -221,7 +233,7 @@ int slist_remove_entry(SListEntry **list, SListEntry *entry); * @return The number of entries removed from the list. */ -int slist_remove_data(SListEntry **list, SListEqualFunc callback, void *data); +int slist_remove_data(SListEntry **list, SListEqualFunc callback, SListValue data); /** * Sort a list. @@ -245,7 +257,7 @@ void slist_sort(SListEntry **list, SListCompareFunc compare_func); SListEntry *slist_find_data(SListEntry *list, SListEqualFunc callback, - void *data); + SListValue data); /** * Create a new @ref SListIterator structure to iterate over a list. @@ -275,11 +287,11 @@ int slist_iter_has_more(SListIterator *iterator); * Using a list iterator, retrieve the next value from the list. * * @param iterator The list iterator. - * @return The next value from the list, or NULL if there are - * no more values in the list. + * @return The next value from the list, or SLIST_NULL if + * there are no more values in the list. */ -void *slist_iter_next(SListIterator *iterator); +SListValue slist_iter_next(SListIterator *iterator); /** * Delete the current entry in the list (the value last returned from diff --git a/src/trie.c b/src/trie.c index d86f837..7d36ca2 100644 --- a/src/trie.c +++ b/src/trie.c @@ -43,7 +43,7 @@ POSSIBILITY OF SUCH DAMAGE. typedef struct _TrieNode TrieNode; struct _TrieNode { - void *data; + TrieValue data; unsigned int use_count; TrieNode *next[256]; }; @@ -163,7 +163,7 @@ static void trie_insert_rollback(Trie *trie, char *key) } } -int trie_insert(Trie *trie, char *key, void *value) +int trie_insert(Trie *trie, char *key, TrieValue value) { TrieNode **rover; TrieNode *node; @@ -172,7 +172,7 @@ int trie_insert(Trie *trie, char *key, void *value) /* Cannot insert NULL values */ - if (value == NULL) { + if (value == TRIE_NULL) { return 0; } @@ -183,7 +183,7 @@ int trie_insert(Trie *trie, char *key, void *value) /* Already in the tree? If so, replace the existing value and * return success. */ - if (node != NULL && node->data != NULL) { + if (node != NULL && node->data != TRIE_NULL) { node->data = value; return 1; } @@ -259,8 +259,8 @@ int trie_remove(Trie *trie, char *key) node = trie_find_end(trie, key); - if (node != NULL && node->data != NULL) { - node->data = NULL; + if (node != NULL && node->data != TRIE_NULL) { + node->data = TRIE_NULL; } else { return 0; } @@ -324,7 +324,7 @@ int trie_remove(Trie *trie, char *key) return 1; } -void *trie_lookup(Trie *trie, char *key) +TrieValue trie_lookup(Trie *trie, char *key) { TrieNode *node; @@ -333,7 +333,7 @@ void *trie_lookup(Trie *trie, char *key) if (node != NULL) { return node->data; } else { - return NULL; + return TRIE_NULL; } } diff --git a/src/trie.h b/src/trie.h index 41fd6c1..5fb03ad 100644 --- a/src/trie.h +++ b/src/trie.h @@ -61,6 +61,18 @@ extern "C" { typedef struct _Trie Trie; +/** + * Value stored in a @ref Trie. + */ + +typedef void *TrieValue; + +/** + * A null @ref TrieValue. + */ + +#define TRIE_NULL ((void *) 0) + /** * Create a new trie. * @@ -90,18 +102,18 @@ void trie_free(Trie *trie); * memory for the new entry. */ -int trie_insert(Trie *trie, char *key, void *value); +int trie_insert(Trie *trie, char *key, TrieValue value); /** * Look up a value from its key in a trie. * * @param trie The trie. * @param key The key. - * @return The value associated with the key, or NULL if - * not found in the trie. + * @return The value associated with the key, or + * TRIE_NULL if not found in the trie. */ -void *trie_lookup(Trie *trie, char *key); +TrieValue trie_lookup(Trie *trie, char *key); /** * Remove an entry from a trie. From bc2cb02df3dbf446f391ea6db9bd20d19cb07352 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 22 Nov 2006 00:06:44 +0000 Subject: [PATCH 038/250] Separate out set value type to a separate type. --- src/set.c | 24 ++++++++++++------------ src/set.h | 30 +++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/set.c b/src/set.c index 2b30e6b..1912a89 100644 --- a/src/set.c +++ b/src/set.c @@ -42,7 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. typedef struct _SetEntry SetEntry; struct _SetEntry { - void *data; + SetValue data; SetEntry *next; }; @@ -241,7 +241,7 @@ static int set_enlarge(Set *set) return 1; } -int set_insert(Set *set, void *data) +int set_insert(Set *set, SetValue data) { SetEntry *newentry; SetEntry *rover; @@ -307,7 +307,7 @@ int set_insert(Set *set, void *data) return 1; } -int set_remove(Set *set, void *data) +int set_remove(Set *set, SetValue data) { SetEntry **rover; SetEntry *entry; @@ -353,7 +353,7 @@ int set_remove(Set *set, void *data) return 0; } -int set_query(Set *set, void *data) +int set_query(Set *set, SetValue data) { SetEntry *rover; int index; @@ -389,16 +389,16 @@ int set_num_entries(Set *set) return set->entries; } -void **set_to_array(Set *set) +SetValue *set_to_array(Set *set) { - void **array; + SetValue *array; int array_counter; int i; SetEntry *rover; /* Create an array to hold the set entries */ - array = malloc(sizeof(void *) * set->entries); + array = malloc(sizeof(SetValue) * set->entries); if (array == NULL) { return NULL; @@ -432,7 +432,7 @@ Set *set_union(Set *set1, Set *set2) { SetIterator *iterator; Set *new_set; - void *value; + SetValue value; new_set = set_new(set1->hash_func, set1->equal_func); @@ -496,7 +496,7 @@ Set *set_intersection(Set *set1, Set *set2) { Set *new_set; SetIterator *iterator; - void *value; + SetValue value; new_set = set_new(set1->hash_func, set2->equal_func); @@ -569,10 +569,10 @@ SetIterator *set_iterate(Set *set) return iter; } -void *set_iter_next(SetIterator *iterator) +SetValue set_iter_next(SetIterator *iterator) { Set *set; - void *result; + SetValue result; int chain; set = iterator->set; @@ -580,7 +580,7 @@ void *set_iter_next(SetIterator *iterator) /* No more entries? */ if (iterator->next_entry == NULL) { - return NULL; + return SET_NULL; } /* We have the result immediately */ diff --git a/src/set.h b/src/set.h index f45e9c4..3f26ed0 100644 --- a/src/set.h +++ b/src/set.h @@ -79,25 +79,37 @@ typedef struct _Set Set; typedef struct _SetIterator SetIterator; +/** + * A value stored in a @ref Set. + */ + +typedef void *SetValue; + +/** + * A null @ref SetValue. + */ + +#define SET_NULL ((void *) 0) + /** * Hash function. Generates a hash key for data to be stored in a set. */ -typedef unsigned long (*SetHashFunc)(void *data); +typedef unsigned long (*SetHashFunc)(SetValue data); /** * Equality function. Compares two values to determine if they are * equivalent. */ -typedef int (*SetEqualFunc)(void *data1, void *data2); +typedef int (*SetEqualFunc)(SetValue data1, SetValue data2); /** * Function used to free values stored in a set. See * @ref set_register_free_function. */ -typedef void (*SetFreeFunc)(void *data); +typedef void (*SetFreeFunc)(SetValue data); /** * Create a new set. @@ -141,7 +153,7 @@ void set_register_free_function(Set *set, SetFreeFunc free_func); * new entry. */ -int set_insert(Set *set, void *data); +int set_insert(Set *set, SetValue data); /** * Remove a value from a set. @@ -153,7 +165,7 @@ int set_insert(Set *set, void *data); * found in the set. */ -int set_remove(Set *set, void *data); +int set_remove(Set *set, SetValue data); /** * Query if a particular value is in a set. @@ -164,7 +176,7 @@ int set_remove(Set *set, void *data); * data is in the set. */ -int set_query(Set *set, void *data); +int set_query(Set *set, SetValue data); /** * Retrieve the number of entries in a set @@ -182,7 +194,7 @@ int set_num_entries(Set *set); * @return An array containing all entries in the set. */ -void **set_to_array(Set *set); +SetValue *set_to_array(Set *set); /** * Perform a union of two sets. @@ -236,11 +248,11 @@ int set_iter_has_more(SetIterator *iterator); * Using a set iterator, retrieve the next value from the set. * * @param iterator The set iterator. - * @return The next value from the set, or NULL if no + * @return The next value from the set, or SET_NULL if no * more values are available. */ -void *set_iter_next(SetIterator *iterator); +SetValue set_iter_next(SetIterator *iterator); /** * Free back a set iterator object. From 0c54cd44957a751d972d81606cacd219d9e8a1da Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 22 Nov 2006 00:15:27 +0000 Subject: [PATCH 039/250] Fix bug in set_to_array. --- src/set.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/set.c b/src/set.c index 1912a89..29b2396 100644 --- a/src/set.c +++ b/src/set.c @@ -408,7 +408,7 @@ SetValue *set_to_array(Set *set) /* Iterate over all entries in all chains */ - for (i=0; ientries; ++i) { + for (i=0; itable_size; ++i) { rover = set->table[i]; From b75724f473444083fa30301ae6bf62f33670fb44 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 22 Nov 2006 00:31:34 +0000 Subject: [PATCH 040/250] Add new headers to libcalg.h. --- src/libcalg.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libcalg.h b/src/libcalg.h index 8bc6425..8800385 100644 --- a/src/libcalg.h +++ b/src/libcalg.h @@ -47,6 +47,9 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include +#include +#include #include #include #include From 4525571e50b90c33dc0e5511b4acc02fbf362859 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 22 Nov 2006 00:41:28 +0000 Subject: [PATCH 041/250] Set reference count when allocating new trees. --- src/binomial-heap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/binomial-heap.c b/src/binomial-heap.c index ce87de2..3406c47 100644 --- a/src/binomial-heap.c +++ b/src/binomial-heap.c @@ -128,7 +128,8 @@ static BinomialTree *binomial_tree_merge(BinomialHeap *heap, if (new_tree == NULL) { return NULL; } - + + new_tree->refcount = 0; new_tree->order = tree1->order + 1; /* Take the smallest value of the two trees */ From 97428bf4cb166872dca0e565911ebd776096e4d6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 10 Jun 2007 02:07:20 +0000 Subject: [PATCH 042/250] Set svn:ignore property on all directories. From ab3764562094802106b9d567db1d87e28eeccc04 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 10 Jun 2007 02:17:05 +0000 Subject: [PATCH 043/250] Rename avltree_* -> avl_tree_*, avltree.[ch] -> avl-tree.[ch] for consistency with other files. --- doc/intro.h | 2 +- src/Makefile.am | 4 +- src/{avltree.c => avl-tree.c} | 102 +++++++++++------------ src/{avltree.h => avl-tree.h} | 72 ++++++++-------- src/libcalg.h | 2 +- test/Makefile.am | 2 +- test/{test-avltree.c => test-avl-tree.c} | 92 ++++++++++---------- 7 files changed, 138 insertions(+), 138 deletions(-) rename src/{avltree.c => avl-tree.c} (81%) rename src/{avltree.h => avl-tree.h} (81%) rename test/{test-avltree.c => test-avl-tree.c} (69%) diff --git a/doc/intro.h b/doc/intro.h index 0964c5e..3dd5725 100644 --- a/doc/intro.h +++ b/doc/intro.h @@ -70,7 +70,7 @@ POSSIBILITY OF SUCH DAMAGE. * * @subsection Binary_search_trees Binary search trees * - * @li @link avltree.h AVL tree @endlink: Balanced binary search tree + * @li @link avl-tree.h AVL tree @endlink: Balanced binary search tree * with O(log n) worst case performance. * * @section Utility_functions Utility functions diff --git a/src/Makefile.am b/src/Makefile.am index 63a6ea8..9021e70 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,13 +7,13 @@ MAIN_HEADERFILES = libcalg.h CALG_HEADERFILES=\ arraylist.h compare-int.h hash-int.h hashtable.h set.h \ -avltree.h compare-pointer.h hash-pointer.h list.h slist.h \ +avl-tree.h compare-pointer.h hash-pointer.h list.h slist.h \ queue.h compare-string.h hash-string.h trie.h binary-heap.h \ bloom-filter.h binomial-heap.h SRC=\ arraylist.c compare-pointer.c hash-pointer.c list.c slist.c \ -avltree.c compare-string.c hash-string.c queue.c trie.c \ +avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hashtable.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c diff --git a/src/avltree.c b/src/avl-tree.c similarity index 81% rename from src/avltree.c rename to src/avl-tree.c index acdd8ca..2511987 100644 --- a/src/avltree.c +++ b/src/avl-tree.c @@ -35,7 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include -#include "avltree.h" +#include "avl-tree.h" /* AVL Tree (balanced binary search tree) */ @@ -54,7 +54,7 @@ struct _AVLTree { int num_nodes; }; -AVLTree *avltree_new(AVLTreeCompareFunc compare_func) +AVLTree *avl_tree_new(AVLTreeCompareFunc compare_func) { AVLTree *new_tree; @@ -71,30 +71,30 @@ AVLTree *avltree_new(AVLTreeCompareFunc compare_func) return new_tree; } -static void avltree_free_subtree(AVLTree *tree, AVLTreeNode *node) +static void avl_tree_free_subtree(AVLTree *tree, AVLTreeNode *node) { if (node == NULL) { return; } - avltree_free_subtree(tree, node->left_child); - avltree_free_subtree(tree, node->right_child); + avl_tree_free_subtree(tree, node->left_child); + avl_tree_free_subtree(tree, node->right_child); free(node); } -void avltree_free(AVLTree *tree) +void avl_tree_free(AVLTree *tree) { /* Destroy all nodes */ - avltree_free_subtree(tree, tree->root_node); + avl_tree_free_subtree(tree, tree->root_node); /* Free back the main tree data structure */ free(tree); } -int avltree_subtree_height(AVLTreeNode *node) +int avl_tree_subtree_height(AVLTreeNode *node) { if (node == NULL) { return 0; @@ -107,12 +107,12 @@ int avltree_subtree_height(AVLTreeNode *node) * children. This does not update the height variable of any parent * nodes. */ -static void avltree_update_height(AVLTreeNode *node) +static void avl_tree_update_height(AVLTreeNode *node) { int left_height, right_height; - left_height = avltree_subtree_height(node->left_child); - right_height = avltree_subtree_height(node->right_child); + left_height = avl_tree_subtree_height(node->left_child); + right_height = avl_tree_subtree_height(node->right_child); if (left_height > right_height) { node->height = left_height + 1; @@ -139,7 +139,7 @@ static void avltree_update_height(AVLTreeNode *node) * A C */ -static void avltree_rotate_left(AVLTree *tree, AVLTreeNode *node) +static void avl_tree_rotate_left(AVLTree *tree, AVLTreeNode *node) { AVLTreeNode *parent; AVLTreeNode *new_root; @@ -187,8 +187,8 @@ static void avltree_rotate_left(AVLTree *tree, AVLTreeNode *node) /* Update heights of the affected nodes */ - avltree_update_height(new_root); - avltree_update_height(node); + avl_tree_update_height(new_root); + avl_tree_update_height(node); } /* Rotate a section of the tree right. 'node' is the node at the top @@ -209,7 +209,7 @@ static void avltree_rotate_left(AVLTree *tree, AVLTreeNode *node) * C E */ -static void avltree_rotate_right(AVLTree *tree, AVLTreeNode *node) +static void avl_tree_rotate_right(AVLTree *tree, AVLTreeNode *node) { AVLTreeNode *parent; AVLTreeNode *new_root; @@ -257,8 +257,8 @@ static void avltree_rotate_right(AVLTree *tree, AVLTreeNode *node) /* Update heights of the affected nodes */ - avltree_update_height(new_root); - avltree_update_height(node); + avl_tree_update_height(new_root); + avl_tree_update_height(node); } /* Balance a particular tree node. @@ -266,7 +266,7 @@ static void avltree_rotate_right(AVLTree *tree, AVLTreeNode *node) * Returns the root node of the new subtree which is replacing the * old one. */ -static AVLTreeNode *avltree_node_balance(AVLTree *tree, AVLTreeNode *node) +static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) { AVLTreeNode *new_root; int diff; @@ -275,21 +275,21 @@ static AVLTreeNode *avltree_node_balance(AVLTree *tree, AVLTreeNode *node) * (difference between left and right > 2), then rotate nodes * around to fix it */ - diff = avltree_subtree_height(node->right_child) - - avltree_subtree_height(node->left_child); + diff = avl_tree_subtree_height(node->right_child) + - avl_tree_subtree_height(node->left_child); if (diff >= 2) { /* Biased toward the right side too much. */ - if (avltree_subtree_height(node->right_child->right_child) - <= avltree_subtree_height(node->right_child->left_child)) { + if (avl_tree_subtree_height(node->right_child->right_child) + <= avl_tree_subtree_height(node->right_child->left_child)) { /* If the right child is biased toward the left * side, it must be rotated right first (double * rotation) */ - avltree_rotate_right(tree, node->right_child); + avl_tree_rotate_right(tree, node->right_child); } /* Perform a left rotation. After this, the right child will @@ -298,7 +298,7 @@ static AVLTreeNode *avltree_node_balance(AVLTree *tree, AVLTreeNode *node) new_root = node->right_child; - avltree_rotate_left(tree, node); + avl_tree_rotate_left(tree, node); node = new_root; @@ -306,14 +306,14 @@ static AVLTreeNode *avltree_node_balance(AVLTree *tree, AVLTreeNode *node) /* Biased toward the left side too much. */ - if (avltree_subtree_height(node->left_child->left_child) - <= avltree_subtree_height(node->left_child->right_child)) { + if (avl_tree_subtree_height(node->left_child->left_child) + <= avl_tree_subtree_height(node->left_child->right_child)) { /* If the left child is biased toward the right * side, it must be rotated right left (double * rotation) */ - avltree_rotate_left(tree, node->left_child); + avl_tree_rotate_left(tree, node->left_child); } /* Perform a right rotation. After this, the left child @@ -322,19 +322,19 @@ static AVLTreeNode *avltree_node_balance(AVLTree *tree, AVLTreeNode *node) new_root = node->left_child; - avltree_rotate_right(tree, node); + avl_tree_rotate_right(tree, node); node = new_root; } /* Update the height of this node */ - avltree_update_height(node); + avl_tree_update_height(node); return node; } -AVLTreeNode *avltree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) +AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) { AVLTreeNode **rover; AVLTreeNode *new_node; @@ -382,7 +382,7 @@ AVLTreeNode *avltree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) /* Balance this node if necessary */ - node = avltree_node_balance(tree, node); + node = avl_tree_node_balance(tree, node); /* Go to this node's parent */ @@ -398,7 +398,7 @@ AVLTreeNode *avltree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) /* Remove a node from a tree */ -void avltree_remove_node(AVLTree *tree, AVLTreeNode *node) +void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) { AVLTreeNode *swap_node; AVLTreeNode *rover; @@ -543,7 +543,7 @@ void avltree_remove_node(AVLTree *tree, AVLTreeNode *node) /* Possibly rebalance this subtree */ - rover = avltree_node_balance(tree, rover); + rover = avl_tree_node_balance(tree, rover); /* Go to the node's parent */ @@ -553,13 +553,13 @@ void avltree_remove_node(AVLTree *tree, AVLTreeNode *node) /* Remove a node by key */ -int avltree_remove(AVLTree *tree, AVLTreeKey key) +int avl_tree_remove(AVLTree *tree, AVLTreeKey key) { AVLTreeNode *node; /* Find the node to remove */ - node = avltree_lookup_node(tree, key); + node = avl_tree_lookup_node(tree, key); if (node == NULL) { /* Not found in tree */ @@ -569,12 +569,12 @@ int avltree_remove(AVLTree *tree, AVLTreeKey key) /* Remove the node */ - avltree_remove_node(tree, node); + avl_tree_remove_node(tree, node); return 1; } -AVLTreeNode *avltree_lookup_node(AVLTree *tree, AVLTreeKey key) +AVLTreeNode *avl_tree_lookup_node(AVLTree *tree, AVLTreeKey key) { AVLTreeNode *node; int diff; @@ -606,13 +606,13 @@ AVLTreeNode *avltree_lookup_node(AVLTree *tree, AVLTreeKey key) return NULL; } -AVLTreeValue avltree_lookup(AVLTree *tree, AVLTreeKey key) +AVLTreeValue avl_tree_lookup(AVLTree *tree, AVLTreeKey key) { AVLTreeNode *node; /* Find the node */ - node = avltree_lookup_node(tree, key); + node = avl_tree_lookup_node(tree, key); if (node == NULL) { return AVL_TREE_NULL; @@ -621,42 +621,42 @@ AVLTreeValue avltree_lookup(AVLTree *tree, AVLTreeKey key) } } -AVLTreeNode *avltree_root_node(AVLTree *tree) +AVLTreeNode *avl_tree_root_node(AVLTree *tree) { return tree->root_node; } -AVLTreeKey avltree_node_key(AVLTreeNode *node) +AVLTreeKey avl_tree_node_key(AVLTreeNode *node) { return node->key; } -AVLTreeValue avltree_node_value(AVLTreeNode *node) +AVLTreeValue avl_tree_node_value(AVLTreeNode *node) { return node->value; } -AVLTreeNode *avltree_node_left_child(AVLTreeNode *node) +AVLTreeNode *avl_tree_node_left_child(AVLTreeNode *node) { return node->left_child; } -AVLTreeNode *avltree_node_right_child(AVLTreeNode *node) +AVLTreeNode *avl_tree_node_right_child(AVLTreeNode *node) { return node->right_child; } -AVLTreeNode *avltree_node_parent(AVLTreeNode *node) +AVLTreeNode *avl_tree_node_parent(AVLTreeNode *node) { return node->parent; } -int avltree_num_entries(AVLTree *tree) +int avl_tree_num_entries(AVLTree *tree) { return tree->num_nodes; } -static void avltree_to_array_add_subtree(AVLTreeNode *subtree, +static void avl_tree_to_array_add_subtree(AVLTreeNode *subtree, AVLTreeValue *array, int *index) { @@ -666,7 +666,7 @@ static void avltree_to_array_add_subtree(AVLTreeNode *subtree, /* Add left subtree first */ - avltree_to_array_add_subtree(subtree->left_child, array, index); + avl_tree_to_array_add_subtree(subtree->left_child, array, index); /* Add this node */ @@ -675,10 +675,10 @@ static void avltree_to_array_add_subtree(AVLTreeNode *subtree, /* Finally add right subtree */ - avltree_to_array_add_subtree(subtree->right_child, array, index); + avl_tree_to_array_add_subtree(subtree->right_child, array, index); } -AVLTreeValue *avltree_to_array(AVLTree *tree) +AVLTreeValue *avl_tree_to_array(AVLTree *tree) { AVLTreeValue *array; int index; @@ -695,7 +695,7 @@ AVLTreeValue *avltree_to_array(AVLTree *tree) /* Add all keys */ - avltree_to_array_add_subtree(tree->root_node, array, &index); + avl_tree_to_array_add_subtree(tree->root_node, array, &index); return array; } diff --git a/src/avltree.h b/src/avl-tree.h similarity index 81% rename from src/avltree.h rename to src/avl-tree.h index 821deca..01cd9a7 100644 --- a/src/avltree.h +++ b/src/avl-tree.h @@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. */ -/** @file avltree.h +/** @file avl-tree.h * * @brief Balanced binary tree * @@ -49,22 +49,22 @@ POSSIBILITY OF SUCH DAMAGE. * as a mapping (searching for a value based on its key), or * as a set of keys which is always ordered. * - * To create a new AVL tree, use @ref avltree_new. To destroy - * an AVL tree, use @ref avltree_free. + * To create a new AVL tree, use @ref avl_tree_new. To destroy + * an AVL tree, use @ref avl_tree_free. * * To insert a new key-value pair into an AVL tree, use - * @ref avltree_insert. To remove an entry from an - * AVL tree, use @ref avltree_remove or @ref avltree_remove_node. + * @ref avl_tree_insert. To remove an entry from an + * AVL tree, use @ref avl_tree_remove or @ref avl_tree_remove_node. * - * To search an AVL tree, use @ref avltree_lookup or - * @ref avltree_lookup_node. + * To search an AVL tree, use @ref avl_tree_lookup or + * @ref avl_tree_lookup_node. * * Tree nodes can be queried using the - * @ref avltree_node_left_child, - * @ref avltree_node_right_child, - * @ref avltree_node_parent, - * @ref avltree_node_key and - * @ref avltree_node_value functions. + * @ref avl_tree_node_left_child, + * @ref avl_tree_node_right_child, + * @ref avl_tree_node_parent, + * @ref avl_tree_node_key and + * @ref avl_tree_node_value functions. */ #ifndef ALGORITHM_AVLTREE_H @@ -77,7 +77,7 @@ extern "C" { /** * An AVL tree balanced binary tree. * - * @see avltree_new + * @see avl_tree_new */ typedef struct _AVLTree AVLTree; @@ -103,11 +103,11 @@ typedef void *AVLTreeValue; /** * A node in an AVL tree. * - * @see avltree_node_left_child - * @see avltree_node_right_child - * @see avltree_node_parent - * @see avltree_node_key - * @see avltree_node_value + * @see avl_tree_node_left_child + * @see avl_tree_node_right_child + * @see avl_tree_node_parent + * @see avl_tree_node_key + * @see avl_tree_node_value */ typedef struct _AVLTreeNode AVLTreeNode; @@ -133,7 +133,7 @@ typedef int (*AVLTreeCompareFunc)(AVLTreeValue data1, AVLTreeValue data2); * to allocate the memory. */ -AVLTree *avltree_new(AVLTreeCompareFunc compare_func); +AVLTree *avl_tree_new(AVLTreeCompareFunc compare_func); /** * Destroy an AVL tree. @@ -141,7 +141,7 @@ AVLTree *avltree_new(AVLTreeCompareFunc compare_func); * @param tree The tree to destroy. */ -void avltree_free(AVLTree *tree); +void avl_tree_free(AVLTree *tree); /** * Insert a new key-value pair into an AVL tree. @@ -154,7 +154,7 @@ void avltree_free(AVLTree *tree); * to allocate the new memory. */ -AVLTreeNode *avltree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value); +AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value); /** * Remove a node from a tree. @@ -163,7 +163,7 @@ AVLTreeNode *avltree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value); * @param node The node to remove */ -void avltree_remove_node(AVLTree *tree, AVLTreeNode *node); +void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node); /** * Remove an entry from a tree, specifying the key of the node to @@ -176,7 +176,7 @@ void avltree_remove_node(AVLTree *tree, AVLTreeNode *node); * the specified key was removed. */ -int avltree_remove(AVLTree *tree, AVLTreeKey key); +int avl_tree_remove(AVLTree *tree, AVLTreeKey key); /** * Search an AVL tree for a node with a particular key. This uses @@ -188,12 +188,12 @@ int avltree_remove(AVLTree *tree, AVLTreeKey key); * if no entry with the given key is found. */ -AVLTreeNode *avltree_lookup_node(AVLTree *tree, AVLTreeKey key); +AVLTreeNode *avl_tree_lookup_node(AVLTree *tree, AVLTreeKey key); /** * Search an AVL tree for a value corresponding to a particular key. * This uses the tree as a mapping. Note that this performs - * identically to @ref avltree_lookup_node, except that the value + * identically to @ref avl_tree_lookup_node, except that the value * at the node is returned rather than the node itself. * * @param tree The AVL tree to search. @@ -203,7 +203,7 @@ AVLTreeNode *avltree_lookup_node(AVLTree *tree, AVLTreeKey key); * found. */ -AVLTreeValue avltree_lookup(AVLTree *tree, AVLTreeKey key); +AVLTreeValue avl_tree_lookup(AVLTree *tree, AVLTreeKey key); /** * Find the root node of a tree. @@ -213,7 +213,7 @@ AVLTreeValue avltree_lookup(AVLTree *tree, AVLTreeKey key); * empty. */ -AVLTreeNode *avltree_root_node(AVLTree *tree); +AVLTreeNode *avl_tree_root_node(AVLTree *tree); /** * Retrieve the key for a given tree node. @@ -222,7 +222,7 @@ AVLTreeNode *avltree_root_node(AVLTree *tree); * @return The key to the given node. */ -AVLTreeKey avltree_node_key(AVLTreeNode *node); +AVLTreeKey avl_tree_node_key(AVLTreeNode *node); /** * Retrieve the value at a given tree node. @@ -231,7 +231,7 @@ AVLTreeKey avltree_node_key(AVLTreeNode *node); * @return The value at the given node. */ -AVLTreeValue avltree_node_value(AVLTreeNode *node); +AVLTreeValue avl_tree_node_value(AVLTreeNode *node); /** * Find the left child of a given tree node. @@ -241,7 +241,7 @@ AVLTreeValue avltree_node_value(AVLTreeNode *node); * node has no left child. */ -AVLTreeNode *avltree_node_left_child(AVLTreeNode *node); +AVLTreeNode *avl_tree_node_left_child(AVLTreeNode *node); /** * Find the right child of a given tree node. @@ -251,7 +251,7 @@ AVLTreeNode *avltree_node_left_child(AVLTreeNode *node); * node has no right child. */ -AVLTreeNode *avltree_node_right_child(AVLTreeNode *node); +AVLTreeNode *avl_tree_node_right_child(AVLTreeNode *node); /** * Find the parent node of a given tree node. @@ -261,7 +261,7 @@ AVLTreeNode *avltree_node_right_child(AVLTreeNode *node); * this is the root node. */ -AVLTreeNode *avltree_node_parent(AVLTreeNode *node); +AVLTreeNode *avl_tree_node_parent(AVLTreeNode *node); /** * Find the height of a subtree. @@ -270,7 +270,7 @@ AVLTreeNode *avltree_node_parent(AVLTreeNode *node); * @return The height of the subtree. */ -int avltree_subtree_height(AVLTreeNode *node); +int avl_tree_subtree_height(AVLTreeNode *node); /** * Convert the keys in an AVL tree into a C array. This allows @@ -280,10 +280,10 @@ int avltree_subtree_height(AVLTreeNode *node); * @return A newly allocated C array containing all the keys * in the tree, in order. The length of the array * is equal to the number of entries in the tree - * (see @ref avltree_num_entries). + * (see @ref avl_tree_num_entries). */ -AVLTreeValue *avltree_to_array(AVLTree *tree); +AVLTreeValue *avl_tree_to_array(AVLTree *tree); /** * Retrieve the number of entries in the tree. @@ -292,7 +292,7 @@ AVLTreeValue *avltree_to_array(AVLTree *tree); * @return The number of key-value pairs stored in the tree. */ -int avltree_num_entries(AVLTree *tree); +int avl_tree_num_entries(AVLTree *tree); #ifdef __cplusplus } diff --git a/src/libcalg.h b/src/libcalg.h index 8800385..b14c0d1 100644 --- a/src/libcalg.h +++ b/src/libcalg.h @@ -46,7 +46,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include -#include +#include #include #include #include diff --git a/test/Makefile.am b/test/Makefile.am index a3024a8..6b1dab7 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,7 +1,7 @@ TESTS = \ test-arraylist \ - test-avltree \ + test-avl-tree \ test-binary-heap \ test-binomial-heap \ test-bloom-filter \ diff --git a/test/test-avltree.c b/test/test-avl-tree.c similarity index 69% rename from test/test-avltree.c rename to test/test-avl-tree.c index b5710bd..096f809 100644 --- a/test/test-avltree.c +++ b/test/test-avl-tree.c @@ -37,7 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include -#include "avltree.h" +#include "avl-tree.h" #include "compare-int.h" int find_subtree_height(AVLTreeNode *node) @@ -48,8 +48,8 @@ int find_subtree_height(AVLTreeNode *node) return 0; } - left_height = find_subtree_height(avltree_node_left_child(node)); - right_height = find_subtree_height(avltree_node_right_child(node)); + left_height = find_subtree_height(avl_tree_node_left_child(node)); + right_height = find_subtree_height(avl_tree_node_right_child(node)); if (left_height > right_height) { return left_height + 1; @@ -72,16 +72,16 @@ int validate_subtree(AVLTreeNode *node) return 0; } - left_node = avltree_node_left_child(node); - right_node = avltree_node_right_child(node); + left_node = avl_tree_node_left_child(node); + right_node = avl_tree_node_right_child(node); /* Check the parent references of the children */ if (left_node != NULL) { - assert(avltree_node_parent(left_node) == node); + assert(avl_tree_node_parent(left_node) == node); } if (right_node != NULL) { - assert(avltree_node_parent(right_node) == node); + assert(avl_tree_node_parent(right_node) == node); } /* Recursively validate the left and right subtrees, @@ -91,7 +91,7 @@ int validate_subtree(AVLTreeNode *node) /* Check that the keys are in the correct order */ - key = (int *) avltree_node_key(node); + key = (int *) avl_tree_node_key(node); assert(*key > counter); counter = *key; @@ -99,10 +99,10 @@ int validate_subtree(AVLTreeNode *node) right_height = validate_subtree(right_node); /* Check that the returned height value matches the - * result of avltree_subtree_height(). */ + * result of avl_tree_subtree_height(). */ - assert(avltree_subtree_height(left_node) == left_height); - assert(avltree_subtree_height(right_node) == right_height); + assert(avl_tree_subtree_height(left_node) == left_height); + assert(avl_tree_subtree_height(right_node) == right_height); /* Check this node is balanced */ @@ -121,24 +121,24 @@ void validate_tree(AVLTree *tree) { AVLTreeNode *root_node; - root_node = avltree_root_node(tree); + root_node = avl_tree_root_node(tree); counter = -1; validate_subtree(root_node); } -void test_avltree_new(void) +void test_avl_tree_new(void) { AVLTree *tree; - tree = avltree_new((AVLTreeCompareFunc) int_compare); + tree = avl_tree_new((AVLTreeCompareFunc) int_compare); assert(tree != NULL); - assert(avltree_root_node(tree) == NULL); - assert(avltree_num_entries(tree) == 0); + assert(avl_tree_root_node(tree) == NULL); + assert(avl_tree_num_entries(tree) == 0); } -void test_avltree_insert_lookup(void) +void test_avl_tree_insert_lookup(void) { AVLTree *tree; AVLTreeNode *node; @@ -148,33 +148,33 @@ void test_avltree_insert_lookup(void) /* Create a tree containing some values. Validate the * tree is consistent at all stages. */ - tree = avltree_new((AVLTreeCompareFunc) int_compare); + tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<1000; ++i) { key = (int *) malloc(sizeof(int)); *key = i; - avltree_insert(tree, key, NULL); + avl_tree_insert(tree, key, NULL); - assert(avltree_num_entries(tree) == i+1); + assert(avl_tree_num_entries(tree) == i+1); validate_tree(tree); } - assert(avltree_root_node(tree) != NULL); + assert(avl_tree_root_node(tree) != NULL); /* Check that all values can be read back again */ for (i=0; i<1000; ++i) { - node = avltree_lookup_node(tree, &i); + node = avl_tree_lookup_node(tree, &i); assert(node != NULL); } /* Check that invalid nodes are not found */ i = -1; - assert(avltree_lookup_node(tree, &i) == NULL); + assert(avl_tree_lookup_node(tree, &i) == NULL); i = 100000; - assert(avltree_lookup_node(tree, &i) == NULL); + assert(avl_tree_lookup_node(tree, &i) == NULL); } AVLTree *create_tree(void) @@ -185,34 +185,34 @@ AVLTree *create_tree(void) /* Create a tree and fill with nodes */ - tree = avltree_new((AVLTreeCompareFunc) int_compare); + tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<1000; ++i) { key = (int *) malloc(sizeof(int)); *key = i; - avltree_insert(tree, key, NULL); + avl_tree_insert(tree, key, NULL); } return tree; } -void test_avltree_free(void) +void test_avl_tree_free(void) { AVLTree *tree; /* Try freeing an empty tree */ - tree = avltree_new((AVLTreeCompareFunc) int_compare); - avltree_free(tree); + tree = avl_tree_new((AVLTreeCompareFunc) int_compare); + avl_tree_free(tree); /* Create a big tree and free it */ tree = create_tree(); - avltree_free(tree); + avl_tree_free(tree); } -void test_avltree_remove(void) +void test_avl_tree_remove(void) { AVLTree *tree; int i; @@ -222,29 +222,29 @@ void test_avltree_remove(void) /* Try removing invalid entries */ i = 100000; - assert(avltree_remove(tree, &i) == 0); + assert(avl_tree_remove(tree, &i) == 0); i = -1; - assert(avltree_remove(tree, &i) == 0); + assert(avl_tree_remove(tree, &i) == 0); /* Delete the nodes from the tree */ for (i=0; i<1000; ++i) { /* Remove this entry */ - assert(avltree_remove(tree, &i) != 0); + assert(avl_tree_remove(tree, &i) != 0); validate_tree(tree); - assert(avltree_num_entries(tree) == 1000 - (i+1)); + assert(avl_tree_num_entries(tree) == 1000 - (i+1)); } /* All entries removed, should be empty now */ - assert(avltree_root_node(tree) == NULL); + assert(avl_tree_root_node(tree) == NULL); } -void test_avltree_to_array(void) +void test_avl_tree_to_array(void) { AVLTree *tree; int entries[] = { 89, 23, 42, 4, 16, 15, 8, 99, 50, 30 }; @@ -255,17 +255,17 @@ void test_avltree_to_array(void) /* Add all entries to the tree */ - tree = avltree_new((AVLTreeCompareFunc) int_compare); + tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i Date: Sun, 10 Jun 2007 02:55:59 +0000 Subject: [PATCH 044/250] Test bloom_filter_free. --- test/test-bloom-filter.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/test-bloom-filter.c b/test/test-bloom-filter.c index 31d4f38..3235c21 100644 --- a/test/test-bloom-filter.c +++ b/test/test-bloom-filter.c @@ -14,9 +14,13 @@ void test_bloom_filter_new_free(void) assert(filter != NULL); + bloom_filter_free(filter); + filter = bloom_filter_new(128, string_hash, 64); assert(filter != NULL); + + bloom_filter_free(filter); } void test_bloom_filter_insert_query(void) From a7452e382a72ee3bc5d3cfc3d493847adb6e9970 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 10 Jun 2007 02:56:57 +0000 Subject: [PATCH 045/250] Test set_register_free_function. --- test/test-set.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/test-set.c b/test/test-set.c index 2f9fdab..5017c2d 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -43,6 +43,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "compare-pointer.h" #include "hash-pointer.h" +int allocated_values; + Set *generate_set(void) { Set *set; @@ -377,6 +379,61 @@ void test_set_iterating_remove(void) set_free(set); } +int *new_value(int value) +{ + int *result; + + result = malloc(sizeof(int)); + *result = value; + + ++allocated_values; + + return result; +} + +void free_value(void *value) +{ + free(value); + + --allocated_values; +} + +void test_set_free_function(void) +{ + Set *set; + int i; + int *value; + + /* Create a set and fill it with 1000 values */ + + set = set_new(int_hash, int_equal); + + set_register_free_function(set, free_value); + + allocated_values = 0; + + for (i=0; i<1000; ++i) { + value = new_value(i); + + set_insert(set, value); + } + + assert(allocated_values == 1000); + + /* Test removing a value */ + + i = 500; + set_remove(set, &i); + + assert(allocated_values == 999); + + /* Test freeing the set */ + + set_free(set); + + assert(allocated_values == 0); +} + int main(int argc, char *argv[]) { test_set_new(); @@ -389,6 +446,7 @@ int main(int argc, char *argv[]) test_set_iterating(); test_set_iterating_remove(); test_set_to_array(); + test_set_free_function(); return 0; } From 5c678d98756a7a7c730a8a159cecb5d20704ebe3 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 10 Jun 2007 02:57:45 +0000 Subject: [PATCH 046/250] Test hash_table_register_free_functions. --- test/test-hashtable.c | 106 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/test/test-hashtable.c b/test/test-hashtable.c index 4ff8bb4..e8854c8 100644 --- a/test/test-hashtable.c +++ b/test/test-hashtable.c @@ -42,6 +42,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "compare-int.h" int value1 = 1, value2 = 2, value3 = 3, value4 = 4; +int allocated_keys = 0; +int allocated_values = 0; /* Generates a hashtable for use in tests containing 10,000 entries */ @@ -258,6 +260,109 @@ void test_hash_table_iterating_remove(void) } } +/* Create a new key */ + +int *new_key(int value) +{ + int *result; + + result = malloc(sizeof(int)); + *result = value; + + ++allocated_keys; + + return result; +} + +/* Callback function invoked when a key is freed */ + +void free_key(void *key) +{ + free(key); + + --allocated_keys; +} + +/* Create a new value */ + +int *new_value(int value) +{ + int *result; + + result = malloc(sizeof(int)); + *result = value; + + ++allocated_values; + + return result; +} + +/* Callback function invoked when a value is freed */ + +void free_value(void *value) +{ + free(value); + + --allocated_values; +} + +/* Test the use of functions to free keys / values when they are removed. */ + +void test_hash_table_free_functions(void) +{ + HashTable *hashtable; + int *key; + int *value; + int i; + + /* Create a hash table, fill it with values */ + + hashtable = hash_table_new(int_hash, int_equal); + + hash_table_register_free_functions(hashtable, free_key, free_value); + + allocated_values = 0; + + for (i=0; i<1000; ++i) + { + key = new_key(i); + value = new_value(99); + + hash_table_insert(hashtable, key, value); + } + + assert(allocated_keys == 1000); + assert(allocated_values == 1000); + + /* Check that removing a key works */ + + i = 500; + hash_table_remove(hashtable, &i); + + assert(allocated_keys == 999); + assert(allocated_values == 999); + + /* Check that replacing an existing key works */ + + key = new_key(600); + value = new_value(999); + + assert(allocated_keys == 1000); + assert(allocated_values == 1000); + + hash_table_insert(hashtable, key, value); + + assert(allocated_keys == 999); + assert(allocated_values == 999); + + /* A free of the hash table should free all of the keys and values */ + + hash_table_free(hashtable); + + assert(allocated_keys == 0); + assert(allocated_values == 0); +} + int main(int argc, char *argv[]) { test_hash_table_new(); @@ -266,6 +371,7 @@ int main(int argc, char *argv[]) test_hash_table_remove(); test_hash_table_iterating(); test_hash_table_iterating_remove(); + test_hash_table_free_functions(); return 0; } From 5b36b6fd8db5a847969ba67f587a6f2ed3c8441f Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 10 Jun 2007 03:22:20 +0000 Subject: [PATCH 047/250] Rename hashtable.[ch] -> hash-table.[ch] for consistency. Rename all instances of hashtable to hash_table. --- doc/intro.h | 4 +- src/Makefile.am | 8 +- src/{hashtable.c => hash-table.c} | 172 ++++++++++--------- src/{hashtable.h => hash-table.h} | 39 +++-- src/libcalg.h | 2 +- test/Makefile.am | 2 +- test/{test-hashtable.c => test-hash-table.c} | 109 ++++++------ 7 files changed, 171 insertions(+), 165 deletions(-) rename src/{hashtable.c => hash-table.c} (68%) rename src/{hashtable.h => hash-table.h} (87%) rename test/{test-hashtable.c => test-hash-table.c} (71%) diff --git a/doc/intro.h b/doc/intro.h index 3dd5725..415d737 100644 --- a/doc/intro.h +++ b/doc/intro.h @@ -64,8 +64,8 @@ POSSIBILITY OF SUCH DAMAGE. * * @subsection Mappings * - * @li @link hashtable.h Hash table @endlink: Collection of values which can be - * addressed using a key. + * @li @link hash-table.h Hash table @endlink: Collection of values which + * can be addressed using a key. * @li @link trie.h Trie @endlink: Fast mapping using strings as keys. * * @subsection Binary_search_trees Binary search trees diff --git a/src/Makefile.am b/src/Makefile.am index 9021e70..d5f23c7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,15 +6,15 @@ lib_LTLIBRARIES=libcalg.la MAIN_HEADERFILES = libcalg.h CALG_HEADERFILES=\ -arraylist.h compare-int.h hash-int.h hashtable.h set.h \ -avl-tree.h compare-pointer.h hash-pointer.h list.h slist.h \ -queue.h compare-string.h hash-string.h trie.h binary-heap.h \ +arraylist.h compare-int.h hash-int.h hash-table.h set.h \ +avl-tree.h compare-pointer.h hash-pointer.h list.h slist.h \ +queue.h compare-string.h hash-string.h trie.h binary-heap.h \ bloom-filter.h binomial-heap.h SRC=\ arraylist.c compare-pointer.c hash-pointer.c list.c slist.c \ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ -compare-int.c hash-int.c hashtable.c set.c binary-heap.c \ +compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) diff --git a/src/hashtable.c b/src/hash-table.c similarity index 68% rename from src/hashtable.c rename to src/hash-table.c index 67fc5b5..460634c 100644 --- a/src/hashtable.c +++ b/src/hash-table.c @@ -38,7 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include -#include "hashtable.h" +#include "hash-table.h" typedef struct _HashTableEntry HashTableEntry; @@ -60,7 +60,7 @@ struct _HashTable { }; struct _HashTableIterator { - HashTable *hashtable; + HashTable *hash_table; HashTableEntry *current_entry; HashTableEntry *next_entry; int next_chain; @@ -81,45 +81,49 @@ static const unsigned int hash_table_primes[] = { static const int hash_table_num_primes = sizeof(hash_table_primes) / sizeof(int); -/* Internal function used to allocate the table on hashtable creation +/* Internal function used to allocate the table on hash table creation * and when enlarging the table */ -static int hash_table_allocate_table(HashTable *hashtable) +static int hash_table_allocate_table(HashTable *hash_table) { + int new_table_size; + /* Determine the table size based on the current prime index. * An attempt is made here to ensure sensible behavior if the * maximum prime is exceeded, but in practice other things are * likely to break long before that happens. */ - if (hashtable->prime_index < hash_table_num_primes) { - hashtable->table_size = hash_table_primes[hashtable->prime_index]; + if (hash_table->prime_index < hash_table_num_primes) { + new_table_size = hash_table_primes[hash_table->prime_index]; } else { - hashtable->table_size = hashtable->entries * 10; + new_table_size = hash_table->entries * 10; } + hash_table->table_size = new_table_size; + /* Allocate the table and initialise to NULL for all entries */ - hashtable->table = calloc(hashtable->table_size, - sizeof(HashTableEntry *)); + hash_table->table = calloc(hash_table->table_size, + sizeof(HashTableEntry *)); - return hashtable->table != NULL; + return hash_table->table != NULL; } /* Free an entry, calling the free functions if there are any registered */ -static void hash_table_free_entry(HashTable *hashtable, HashTableEntry *entry) +static void hash_table_free_entry(HashTable *hash_table, HashTableEntry *entry) { /* If there is a function registered for freeing keys, use it to free * the key */ - if (hashtable->key_free_func != NULL) { - hashtable->key_free_func(entry->key); + if (hash_table->key_free_func != NULL) { + hash_table->key_free_func(entry->key); } /* Likewise with the value */ - if (hashtable->value_free_func != NULL) { - hashtable->value_free_func(entry->value); + if (hash_table->value_free_func != NULL) { + hash_table->value_free_func(entry->value); } /* Free the data structure */ @@ -130,35 +134,35 @@ static void hash_table_free_entry(HashTable *hashtable, HashTableEntry *entry) HashTable *hash_table_new(HashTableHashFunc hash_func, HashTableEqualFunc equal_func) { - HashTable *hashtable; + HashTable *hash_table; /* Allocate a new hash table structure */ - hashtable = (HashTable *) malloc(sizeof(HashTable)); + hash_table = (HashTable *) malloc(sizeof(HashTable)); - if (hashtable == NULL) { + if (hash_table == NULL) { return NULL; } - hashtable->hash_func = hash_func; - hashtable->equal_func = equal_func; - hashtable->key_free_func = NULL; - hashtable->value_free_func = NULL; - hashtable->entries = 0; - hashtable->prime_index = 0; + hash_table->hash_func = hash_func; + hash_table->equal_func = equal_func; + hash_table->key_free_func = NULL; + hash_table->value_free_func = NULL; + hash_table->entries = 0; + hash_table->prime_index = 0; /* Allocate the table */ - if (!hash_table_allocate_table(hashtable)) { - free(hashtable); + if (!hash_table_allocate_table(hash_table)) { + free(hash_table); return NULL; } - return hashtable; + return hash_table; } -void hash_table_free(HashTable *hashtable) +void hash_table_free(HashTable *hash_table) { HashTableEntry *rover; HashTableEntry *next; @@ -166,34 +170,34 @@ void hash_table_free(HashTable *hashtable) /* Free all entries in all chains */ - for (i=0; itable_size; ++i) { - rover = hashtable->table[i]; + for (i=0; itable_size; ++i) { + rover = hash_table->table[i]; while (rover != NULL) { next = rover->next; - hash_table_free_entry(hashtable, rover); + hash_table_free_entry(hash_table, rover); rover = next; } } /* Free the table */ - free(hashtable->table); + free(hash_table->table); /* Free the hash table structure */ - free(hashtable); + free(hash_table); } -void hash_table_register_free_functions(HashTable *hashtable, +void hash_table_register_free_functions(HashTable *hash_table, HashTableKeyFreeFunc key_free_func, HashTableValueFreeFunc value_free_func) { - hashtable->key_free_func = key_free_func; - hashtable->value_free_func = value_free_func; + hash_table->key_free_func = key_free_func; + hash_table->value_free_func = value_free_func; } -static int hash_table_enlarge(HashTable *hashtable) +static int hash_table_enlarge(HashTable *hash_table) { HashTableEntry **old_table; int old_table_size; @@ -205,21 +209,21 @@ static int hash_table_enlarge(HashTable *hashtable) /* Store a copy of the old table */ - old_table = hashtable->table; - old_table_size = hashtable->table_size; - old_prime_index = hashtable->prime_index; + old_table = hash_table->table; + old_table_size = hash_table->table_size; + old_prime_index = hash_table->prime_index; /* Allocate a new, larger table */ - ++hashtable->prime_index; + ++hash_table->prime_index; - if (!hash_table_allocate_table(hashtable)) { + if (!hash_table_allocate_table(hash_table)) { /* Failed to allocate the new table */ - hashtable->table = old_table; - hashtable->table_size = old_table_size; - hashtable->prime_index = old_prime_index; + hash_table->table = old_table; + hash_table->table_size = old_table_size; + hash_table->prime_index = old_prime_index; return 0; } @@ -234,12 +238,12 @@ static int hash_table_enlarge(HashTable *hashtable) /* Find the index into the new table */ - index = hashtable->hash_func(rover->key) % hashtable->table_size; + index = hash_table->hash_func(rover->key) % hash_table->table_size; /* Link this entry into the chain */ - rover->next = hashtable->table[index]; - hashtable->table[index] = rover; + rover->next = hash_table->table[index]; + hash_table->table[index] = rover; /* Advance to next in the chain */ @@ -250,7 +254,7 @@ static int hash_table_enlarge(HashTable *hashtable) return 1; } -int hash_table_insert(HashTable *hashtable, HashTableKey key, HashTableValue value) +int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue value) { HashTableEntry *rover; HashTableEntry *newentry; @@ -260,11 +264,11 @@ int hash_table_insert(HashTable *hashtable, HashTableKey key, HashTableValue val * size, the number of hash collisions increases and performance * decreases. Enlarge the table size to prevent this happening */ - if ((hashtable->entries * 3) / hashtable->table_size > 0) { + if ((hash_table->entries * 3) / hash_table->table_size > 0) { /* Table is more than 1/3 full */ - if (!hash_table_enlarge(hashtable)) { + if (!hash_table_enlarge(hash_table)) { /* Failed to enlarge the table */ @@ -274,30 +278,30 @@ int hash_table_insert(HashTable *hashtable, HashTableKey key, HashTableValue val /* Generate the hash of the key and hence the index into the table */ - index = hashtable->hash_func(key) % hashtable->table_size; + index = hash_table->hash_func(key) % hash_table->table_size; /* Traverse the chain at this location and look for an existing * entry with the same key */ - rover = hashtable->table[index]; + rover = hash_table->table[index]; while (rover != NULL) { - if (hashtable->equal_func(rover->key, key) != 0) { + if (hash_table->equal_func(rover->key, key) != 0) { /* Same key: overwrite this entry with new data */ /* If there is a value free function, free the old data * before adding in the new data */ - if (hashtable->value_free_func != NULL) { - hashtable->value_free_func(rover->value); + if (hash_table->value_free_func != NULL) { + hash_table->value_free_func(rover->value); } /* Same with the key: use the new key value and free * the old one */ - if (hashtable->key_free_func != NULL) { - hashtable->key_free_func(rover->key); + if (hash_table->key_free_func != NULL) { + hash_table->key_free_func(rover->key); } rover->key = key; @@ -310,7 +314,7 @@ int hash_table_insert(HashTable *hashtable, HashTableKey key, HashTableValue val rover = rover->next; } - /* Not in the hashtable yet. Create a new entry */ + /* Not in the hash table yet. Create a new entry */ newentry = (HashTableEntry *) malloc(sizeof(HashTableEntry)); @@ -323,34 +327,34 @@ int hash_table_insert(HashTable *hashtable, HashTableKey key, HashTableValue val /* Link into the list */ - newentry->next = hashtable->table[index]; - hashtable->table[index] = newentry; + newentry->next = hash_table->table[index]; + hash_table->table[index] = newentry; /* Maintain the count of the number of entries */ - ++hashtable->entries; + ++hash_table->entries; /* Added successfully */ return 1; } -HashTableValue hash_table_lookup(HashTable *hashtable, HashTableKey key) +HashTableValue hash_table_lookup(HashTable *hash_table, HashTableKey key) { HashTableEntry *rover; int index; /* Generate the hash of the key and hence the index into the table */ - index = hashtable->hash_func(key) % hashtable->table_size; + index = hash_table->hash_func(key) % hash_table->table_size; /* Walk the chain at this index until the corresponding entry is * found */ - rover = hashtable->table[index]; + rover = hash_table->table[index]; while (rover != NULL) { - if (hashtable->equal_func(key, rover->key) != 0) { + if (hash_table->equal_func(key, rover->key) != 0) { /* Found the entry. Return the data. */ @@ -364,7 +368,7 @@ HashTableValue hash_table_lookup(HashTable *hashtable, HashTableKey key) return HASH_TABLE_NULL; } -int hash_table_remove(HashTable *hashtable, HashTableKey key) +int hash_table_remove(HashTable *hash_table, HashTableKey key) { HashTableEntry **rover; HashTableEntry *entry; @@ -373,7 +377,7 @@ int hash_table_remove(HashTable *hashtable, HashTableKey key) /* Generate the hash of the key and hence the index into the table */ - index = hashtable->hash_func(key) % hashtable->table_size; + index = hash_table->hash_func(key) % hash_table->table_size; /* Rover points at the pointer which points at the current entry * in the chain being inspected. ie. the entry in the table, or @@ -381,11 +385,11 @@ int hash_table_remove(HashTable *hashtable, HashTableKey key) * allows us to unlink the entry when we find it. */ result = 0; - rover = &hashtable->table[index]; + rover = &hash_table->table[index]; while (*rover != NULL) { - if (hashtable->equal_func(key, (*rover)->key) != 0) { + if (hash_table->equal_func(key, (*rover)->key) != 0) { /* This is the entry to remove */ @@ -397,11 +401,11 @@ int hash_table_remove(HashTable *hashtable, HashTableKey key) /* Destroy the entry structure */ - hash_table_free_entry(hashtable, entry); + hash_table_free_entry(hash_table, entry); /* Track count of entries */ - --hashtable->entries; + --hash_table->entries; result = 1; @@ -416,12 +420,12 @@ int hash_table_remove(HashTable *hashtable, HashTableKey key) return result; } -int hash_table_num_entries(HashTable *hashtable) +int hash_table_num_entries(HashTable *hash_table) { - return hashtable->entries; + return hash_table->entries; } -HashTableIterator *hash_table_iterate(HashTable *hashtable) +HashTableIterator *hash_table_iterate(HashTable *hash_table) { HashTableIterator *iterator; int chain; @@ -432,7 +436,7 @@ HashTableIterator *hash_table_iterate(HashTable *hashtable) return NULL; } - iterator->hashtable = hashtable; + iterator->hash_table = hash_table; iterator->current_entry = NULL; /* Default value of next if no entries are found. */ @@ -441,10 +445,10 @@ HashTableIterator *hash_table_iterate(HashTable *hashtable) /* Find the first entry */ - for (chain=0; chaintable_size; ++chain) { + for (chain=0; chaintable_size; ++chain) { - if (hashtable->table[chain] != NULL) { - iterator->next_entry = hashtable->table[chain]; + if (hash_table->table[chain] != NULL) { + iterator->next_entry = hash_table->table[chain]; iterator->next_chain = chain; break; } @@ -460,11 +464,11 @@ int hash_table_iter_has_more(HashTableIterator *iterator) HashTableValue hash_table_iter_next(HashTableIterator *iterator) { - HashTable *hashtable; + HashTable *hash_table; HashTableValue result; int chain; - hashtable = iterator->hashtable; + hash_table = iterator->hash_table; /* No more entries? */ @@ -495,12 +499,12 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) iterator->next_entry = NULL; - while (chain < hashtable->table_size) { + while (chain < hash_table->table_size) { /* Is there anything in this chain? */ - if (hashtable->table[chain] != NULL) { - iterator->next_entry = hashtable->table[chain]; + if (hash_table->table[chain] != NULL) { + iterator->next_entry = hash_table->table[chain]; break; } diff --git a/src/hashtable.h b/src/hash-table.h similarity index 87% rename from src/hashtable.h rename to src/hash-table.h index 61d3ed8..94cb7c2 100644 --- a/src/hashtable.h +++ b/src/hash-table.h @@ -34,7 +34,7 @@ POSSIBILITY OF SUCH DAMAGE. */ /** - * @file hashtable.h + * @file hash-table.h * * @brief Hash table. * @@ -52,8 +52,8 @@ POSSIBILITY OF SUCH DAMAGE. * To look up a value by its key, use @ref hash_table_lookup. */ -#ifndef ALGORITHM_HASHTABLE_H -#define ALGORITHM_HASHTABLE_H +#ifndef ALGORITHM_HASH_TABLE_H +#define ALGORITHM_HASH_TABLE_H #ifdef __cplusplus extern "C" { @@ -140,21 +140,21 @@ HashTable *hash_table_new(HashTableHashFunc hash_func, /** * Destroy a hash table. * - * @param hashtable The hash table to destroy. + * @param hash_table The hash table to destroy. */ -void hash_table_free(HashTable *hashtable); +void hash_table_free(HashTable *hash_table); /** * Register functions used to free the key and value when an entry is * removed from a hash table. * - * @param hashtable The hash table. + * @param hash_table The hash table. * @param key_free_func Function used to free keys. * @param value_free_func Function used to free values. */ -void hash_table_register_free_functions(HashTable *hashtable, +void hash_table_register_free_functions(HashTable *hash_table, HashTableKeyFreeFunc key_free_func, HashTableValueFreeFunc value_free_func); @@ -162,7 +162,7 @@ void hash_table_register_free_functions(HashTable *hashtable, * Insert a value into a hash table, overwriting any existing entry * using the same key. * - * @param hashtable The hash table. + * @param hash_table The hash table. * @param key The key for the new value. * @param value The value to insert. * @return Non-zero if the value was added successfully, @@ -170,52 +170,55 @@ void hash_table_register_free_functions(HashTable *hashtable, * memory for the new entry. */ -int hash_table_insert(HashTable *hashtable, HashTableKey key, HashTableValue value); +int hash_table_insert(HashTable *hash_table, + HashTableKey key, + HashTableValue value); /** * Look up a value in a hash table by key. * - * @param hashtable The hash table. + * @param hash_table The hash table. * @param key The key of the value to look up. * @return The value, or @ref HASH_TABLE_NULL if there * is no value with that key in the hash table. */ -HashTableValue hash_table_lookup(HashTable *hashtable, HashTableKey key); +HashTableValue hash_table_lookup(HashTable *hash_table, + HashTableKey key); /** * Remove a value from a hash table. * - * @param hashtable The hash table. + * @param hash_table The hash table. * @param key The key of the value to remove. * @return Non-zero if a key was removed, or zero if the * specified key was not found in the hash table. */ -int hash_table_remove(HashTable *hashtable, HashTableKey key); +int hash_table_remove(HashTable *hash_table, HashTableKey key); /** * Retrieve the number of entries in a hash table. * - * @param hashtable The hash table. + * @param hash_table The hash table. * @return The number of entries in the hash table. */ -int hash_table_num_entries(HashTable *hashtable); +int hash_table_num_entries(HashTable *hash_table); /** * Create a new @ref HashTableIterator to iterate over a hash table. * Note: iterators should be freed back with * @ref hash_table_iter_free once iterating has completed. * - * @param hashtable The hash table. + * @param hash_table The hash table. * @return A pointer to a new @ref HashTableIterator * to iterate over the hash table, or NULL * if it was not possible to allocate the * memory. */ -HashTableIterator *hash_table_iterate(HashTable *hashtable); +HashTableIterator *hash_table_iterate(HashTable *hash_table); /** * Determine if there are more keys in the hash table to iterate @@ -253,5 +256,5 @@ void hash_table_iter_free(HashTableIterator *iterator); } #endif -#endif /* #ifndef ALGORITHM_HASHTABLE_H */ +#endif /* #ifndef ALGORITHM_HASH_TABLE_H */ diff --git a/src/libcalg.h b/src/libcalg.h index b14c0d1..02af015 100644 --- a/src/libcalg.h +++ b/src/libcalg.h @@ -50,7 +50,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include +#include #include #include #include diff --git a/test/Makefile.am b/test/Makefile.am index 6b1dab7..ae833a1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -10,7 +10,7 @@ TESTS = \ test-queue \ test-compare-functions \ test-hash-functions \ - test-hashtable \ + test-hash-table \ test-set \ test-trie diff --git a/test/test-hashtable.c b/test/test-hash-table.c similarity index 71% rename from test/test-hashtable.c rename to test/test-hash-table.c index e8854c8..fb1cb61 100644 --- a/test/test-hashtable.c +++ b/test/test-hash-table.c @@ -37,7 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include -#include "hashtable.h" +#include "hash-table.h" #include "hash-int.h" #include "compare-int.h" @@ -45,17 +45,17 @@ int value1 = 1, value2 = 2, value3 = 3, value4 = 4; int allocated_keys = 0; int allocated_values = 0; -/* Generates a hashtable for use in tests containing 10,000 entries */ +/* Generates a hash table for use in tests containing 10,000 entries */ -HashTable *generate_hashtable(void) +HashTable *generate_hash_table(void) { - HashTable *hashtable; + HashTable *hash_table; int *value; int i; /* Allocate a new hash table */ - hashtable = hash_table_new(int_hash, int_equal); + hash_table = hash_table_new(int_hash, int_equal); /* Insert lots of values */ @@ -64,57 +64,57 @@ HashTable *generate_hashtable(void) *value = i; - hash_table_insert(hashtable, value, value); + hash_table_insert(hash_table, value, value); } - return hashtable; + return hash_table; } void test_hash_table_new(void) { - HashTable *hashtable; + HashTable *hash_table; - hashtable = hash_table_new(int_hash, int_equal); + hash_table = hash_table_new(int_hash, int_equal); - assert(hashtable != NULL); + assert(hash_table != NULL); } void test_hash_table_free(void) { - HashTable *hashtable; + HashTable *hash_table; - hashtable = hash_table_new(int_hash, int_equal); + hash_table = hash_table_new(int_hash, int_equal); /* Add some values */ - hash_table_insert(hashtable, &value1, &value1); - hash_table_insert(hashtable, &value2, &value2); - hash_table_insert(hashtable, &value3, &value3); - hash_table_insert(hashtable, &value4, &value4); + hash_table_insert(hash_table, &value1, &value1); + hash_table_insert(hash_table, &value2, &value2); + hash_table_insert(hash_table, &value3, &value3); + hash_table_insert(hash_table, &value4, &value4); /* Free the hash table */ - hash_table_free(hashtable); + hash_table_free(hash_table); } /* Test insert and lookup functions */ void test_hash_table_insert_lookup(void) { - HashTable *hashtable; + HashTable *hash_table; int *value; int i; /* Generate a hash table */ - hashtable = generate_hashtable(); + hash_table = generate_hash_table(); - assert(hash_table_num_entries(hashtable) == 10000); + assert(hash_table_num_entries(hash_table) == 10000); /* Check all values */ for (i=0; i<10000; ++i) { - value = (int *) hash_table_lookup(hashtable, &i); + value = (int *) hash_table_lookup(hash_table, &i); assert(*value == i); } @@ -122,64 +122,64 @@ void test_hash_table_insert_lookup(void) /* Lookup on invalid values returns NULL */ i = -1; - assert(hash_table_lookup(hashtable, &i) == NULL); + assert(hash_table_lookup(hash_table, &i) == NULL); i = 10000; - assert(hash_table_lookup(hashtable, &i) == NULL); + assert(hash_table_lookup(hash_table, &i) == NULL); /* Insert overwrites existing entries with the same key */ value = (int *) malloc(sizeof(int)); *value = 12345; i = 5000; - hash_table_insert(hashtable, &i, value); - value = (int *) hash_table_lookup(hashtable, &i); + hash_table_insert(hash_table, &i, value); + value = (int *) hash_table_lookup(hash_table, &i); assert(*value == 12345); } void test_hash_table_remove(void) { - HashTable *hashtable; + HashTable *hash_table; int i; - hashtable = generate_hashtable(); + hash_table = generate_hash_table(); - assert(hash_table_num_entries(hashtable) == 10000); + assert(hash_table_num_entries(hash_table) == 10000); i = 5000; - assert(hash_table_lookup(hashtable, &i) != NULL); + assert(hash_table_lookup(hash_table, &i) != NULL); /* Remove an entry */ - hash_table_remove(hashtable, &i); + hash_table_remove(hash_table, &i); /* Check entry counter */ - assert(hash_table_num_entries(hashtable) == 9999); + assert(hash_table_num_entries(hash_table) == 9999); /* Check that NULL is returned now */ - assert(hash_table_lookup(hashtable, &i) == NULL); + assert(hash_table_lookup(hash_table, &i) == NULL); /* Try removing a non-existent entry */ i = -1; - hash_table_remove(hashtable, &i); + hash_table_remove(hash_table, &i); - assert(hash_table_num_entries(hashtable) == 9999); + assert(hash_table_num_entries(hash_table) == 9999); } void test_hash_table_iterating(void) { - HashTable *hashtable; + HashTable *hash_table; HashTableIterator *iterator; int count; - hashtable = generate_hashtable(); + hash_table = generate_hash_table(); /* Iterate over all values in the table */ count = 0; - iterator = hash_table_iterate(hashtable); + iterator = hash_table_iterate(hash_table); while (hash_table_iter_has_more(iterator)) { hash_table_iter_next(iterator); @@ -193,9 +193,9 @@ void test_hash_table_iterating(void) /* Test iterating over an empty table */ - hashtable = hash_table_new(int_hash, int_equal); + hash_table = hash_table_new(int_hash, int_equal); - iterator = hash_table_iterate(hashtable); + iterator = hash_table_iterate(hash_table); assert(hash_table_iter_has_more(iterator) == 0); @@ -208,21 +208,21 @@ void test_hash_table_iterating(void) void test_hash_table_iterating_remove(void) { - HashTable *hashtable; + HashTable *hash_table; HashTableIterator *iterator; int *val; int count; int removed; int i; - hashtable = generate_hashtable(); + hash_table = generate_hash_table(); /* Iterate over all values in the table */ count = 0; removed = 0; - iterator = hash_table_iterate(hashtable); + iterator = hash_table_iterate(hash_table); while (hash_table_iter_has_more(iterator)) { @@ -233,7 +233,7 @@ void test_hash_table_iterating_remove(void) /* Remove every hundredth entry */ if (*val % 100 == 0) { - hash_table_remove(hashtable, val); + hash_table_remove(hash_table, val); ++removed; } @@ -247,15 +247,15 @@ void test_hash_table_iterating_remove(void) assert(removed == removed); assert(count == 10000); - assert(hash_table_num_entries(hashtable) == 10000 - removed); + assert(hash_table_num_entries(hash_table) == 10000 - removed); /* Check all entries divisible by 100 were really removed */ for (i=0; i<10000; ++i) { if (i % 100 == 0) { - assert(hash_table_lookup(hashtable, &i) == NULL); + assert(hash_table_lookup(hash_table, &i) == NULL); } else { - assert(hash_table_lookup(hashtable, &i) != NULL); + assert(hash_table_lookup(hash_table, &i) != NULL); } } } @@ -310,25 +310,24 @@ void free_value(void *value) void test_hash_table_free_functions(void) { - HashTable *hashtable; + HashTable *hash_table; int *key; int *value; int i; /* Create a hash table, fill it with values */ - hashtable = hash_table_new(int_hash, int_equal); + hash_table = hash_table_new(int_hash, int_equal); - hash_table_register_free_functions(hashtable, free_key, free_value); + hash_table_register_free_functions(hash_table, free_key, free_value); allocated_values = 0; - for (i=0; i<1000; ++i) - { + for (i=0; i<1000; ++i) { key = new_key(i); value = new_value(99); - hash_table_insert(hashtable, key, value); + hash_table_insert(hash_table, key, value); } assert(allocated_keys == 1000); @@ -337,7 +336,7 @@ void test_hash_table_free_functions(void) /* Check that removing a key works */ i = 500; - hash_table_remove(hashtable, &i); + hash_table_remove(hash_table, &i); assert(allocated_keys == 999); assert(allocated_values == 999); @@ -350,14 +349,14 @@ void test_hash_table_free_functions(void) assert(allocated_keys == 1000); assert(allocated_values == 1000); - hash_table_insert(hashtable, key, value); + hash_table_insert(hash_table, key, value); assert(allocated_keys == 999); assert(allocated_values == 999); /* A free of the hash table should free all of the keys and values */ - hash_table_free(hashtable); + hash_table_free(hash_table); assert(allocated_keys == 0); assert(allocated_values == 0); From 0b581c8a4d54ce91f50748c1cf794265cfafcd47 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 9 Sep 2007 21:02:42 +0000 Subject: [PATCH 048/250] Add missing copyright notice. --- test/test-bloom-filter.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/test-bloom-filter.c b/test/test-bloom-filter.c index 3235c21..acafb4a 100644 --- a/test/test-bloom-filter.c +++ b/test/test-bloom-filter.c @@ -1,3 +1,37 @@ + +/* + +Copyright (c) 2006, Simon Howard +All rights reserved. + +Redistribution and use in source and binomial forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binomial form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ #include #include From 759e062834e33768ccdcb96775e6f74b748f6630 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 2 Oct 2007 00:13:07 +0000 Subject: [PATCH 049/250] Return the value from the hash table iterator, not the key. --- src/hash-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hash-table.c b/src/hash-table.c index 460634c..e3bf3c2 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -479,7 +479,7 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) /* Result is immediately available */ iterator->current_entry = iterator->next_entry; - result = iterator->current_entry->key; + result = iterator->current_entry->value; /* Find the next entry */ From 91ec298fb6d943a679546e1994a4b7819e4602cc Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 16 Apr 2008 19:57:09 +0000 Subject: [PATCH 050/250] Don't allocate hash table iterators; take a pointer to a structure to initialise. --- src/hash-table.c | 35 ++++++----------------------------- src/hash-table.h | 38 +++++++++++++++++++++----------------- test/test-hash-table.c | 26 ++++++++++---------------- 3 files changed, 37 insertions(+), 62 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index e3bf3c2..2086f87 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -40,8 +40,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "hash-table.h" -typedef struct _HashTableEntry HashTableEntry; - struct _HashTableEntry { HashTableKey key; HashTableValue value; @@ -59,13 +57,6 @@ struct _HashTable { int prime_index; }; -struct _HashTableIterator { - HashTable *hash_table; - HashTableEntry *current_entry; - HashTableEntry *next_entry; - int next_chain; -}; - /* This is a set of good hash table prime numbers, from: * http://planetmath.org/encyclopedia/GoodHashTablePrimes.html * Each prime is roughly double the previous value, and as far as @@ -425,19 +416,11 @@ int hash_table_num_entries(HashTable *hash_table) return hash_table->entries; } -HashTableIterator *hash_table_iterate(HashTable *hash_table) +void hash_table_iterate(HashTable *hash_table, HashTableIterator *iterator) { - HashTableIterator *iterator; int chain; - iterator = (HashTableIterator *) malloc(sizeof(HashTableIterator)); - - if (iterator == NULL) { - return NULL; - } - iterator->hash_table = hash_table; - iterator->current_entry = NULL; /* Default value of next if no entries are found. */ @@ -453,8 +436,6 @@ HashTableIterator *hash_table_iterate(HashTable *hash_table) break; } } - - return iterator; } int hash_table_iter_has_more(HashTableIterator *iterator) @@ -464,6 +445,7 @@ int hash_table_iter_has_more(HashTableIterator *iterator) HashTableValue hash_table_iter_next(HashTableIterator *iterator) { + HashTableEntry *current_entry; HashTable *hash_table; HashTableValue result; int chain; @@ -478,16 +460,16 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) /* Result is immediately available */ - iterator->current_entry = iterator->next_entry; - result = iterator->current_entry->value; + current_entry = iterator->next_entry; + result = current_entry->value; /* Find the next entry */ - if (iterator->current_entry->next != NULL) { + if (current_entry->next != NULL) { /* Next entry in current chain */ - iterator->next_entry = iterator->current_entry->next; + iterator->next_entry = current_entry->next; } else { @@ -519,8 +501,3 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) return result; } -void hash_table_iter_free(HashTableIterator *iterator) -{ - free(iterator); -} - diff --git a/src/hash-table.h b/src/hash-table.h index 94cb7c2..beff33d 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -71,6 +71,12 @@ typedef struct _HashTable HashTable; typedef struct _HashTableIterator HashTableIterator; +/** + * Internal structure representing an entry in a hash table. + */ + +typedef struct _HashTableEntry HashTableEntry; + /** * A key to look up a value in a @ref HashTable. */ @@ -83,6 +89,16 @@ typedef void *HashTableKey; typedef void *HashTableValue; +/** + * Definition of a @ref HashTableIterator. + */ + +struct _HashTableIterator { + HashTable *hash_table; + HashTableEntry *next_entry; + int next_chain; +}; + /** * A null @ref HashTableValue. */ @@ -207,18 +223,15 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key); int hash_table_num_entries(HashTable *hash_table); /** - * Create a new @ref HashTableIterator to iterate over a hash table. - * Note: iterators should be freed back with - * @ref hash_table_iter_free once iterating has completed. + * Initialise a @ref HashTableIterator to iterate over a hash table. * * @param hash_table The hash table. - * @return A pointer to a new @ref HashTableIterator - * to iterate over the hash table, or NULL - * if it was not possible to allocate the - * memory. + * @param iter Pointer to an iterator structure to + * initialise. + * @param */ -HashTableIterator *hash_table_iterate(HashTable *hash_table); +void hash_table_iterate(HashTable *hash_table, HashTableIterator *iter); /** * Determine if there are more keys in the hash table to iterate @@ -243,15 +256,6 @@ int hash_table_iter_has_more(HashTableIterator *iterator); HashTableValue hash_table_iter_next(HashTableIterator *iterator); -/** - * Free back a hash table iterator object. This must be done once - * iterating has completed. - * - * @param iterator The hash table iterator. - */ - -void hash_table_iter_free(HashTableIterator *iterator); - #ifdef __cplusplus } #endif diff --git a/test/test-hash-table.c b/test/test-hash-table.c index fb1cb61..d6f03db 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -170,7 +170,7 @@ void test_hash_table_remove(void) void test_hash_table_iterating(void) { HashTable *hash_table; - HashTableIterator *iterator; + HashTableIterator iterator; int count; hash_table = generate_hash_table(); @@ -179,27 +179,23 @@ void test_hash_table_iterating(void) count = 0; - iterator = hash_table_iterate(hash_table); + hash_table_iterate(hash_table, &iterator); - while (hash_table_iter_has_more(iterator)) { - hash_table_iter_next(iterator); + while (hash_table_iter_has_more(&iterator)) { + hash_table_iter_next(&iterator); ++count; } - hash_table_iter_free(iterator); - assert(count == 10000); /* Test iterating over an empty table */ hash_table = hash_table_new(int_hash, int_equal); - iterator = hash_table_iterate(hash_table); - - assert(hash_table_iter_has_more(iterator) == 0); + hash_table_iterate(hash_table, &iterator); - hash_table_iter_free(iterator); + assert(hash_table_iter_has_more(&iterator) == 0); } /* Demonstrates the ability to iteratively remove objects from @@ -209,7 +205,7 @@ void test_hash_table_iterating(void) void test_hash_table_iterating_remove(void) { HashTable *hash_table; - HashTableIterator *iterator; + HashTableIterator iterator; int *val; int count; int removed; @@ -222,13 +218,13 @@ void test_hash_table_iterating_remove(void) count = 0; removed = 0; - iterator = hash_table_iterate(hash_table); + hash_table_iterate(hash_table, &iterator); - while (hash_table_iter_has_more(iterator)) { + while (hash_table_iter_has_more(&iterator)) { /* Read the next value */ - val = (int *) hash_table_iter_next(iterator); + val = (int *) hash_table_iter_next(&iterator); /* Remove every hundredth entry */ @@ -240,8 +236,6 @@ void test_hash_table_iterating_remove(void) ++count; } - hash_table_iter_free(iterator); - /* Check counts */ assert(removed == removed); From 00cca71d41ded7176f0b5f0d4bce52f00b7fc8a8 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 16 Apr 2008 20:08:05 +0000 Subject: [PATCH 051/250] Make the set type take a pointer to a structure to initialise rather than allocating an iterator. --- src/set.c | 65 +++++++++++++------------------------------------ src/set.h | 33 +++++++++++++++---------- test/test-set.c | 25 ++++++++----------- 3 files changed, 47 insertions(+), 76 deletions(-) diff --git a/src/set.c b/src/set.c index 29b2396..0783671 100644 --- a/src/set.c +++ b/src/set.c @@ -39,8 +39,6 @@ POSSIBILITY OF SUCH DAMAGE. /* A set */ -typedef struct _SetEntry SetEntry; - struct _SetEntry { SetValue data; SetEntry *next; @@ -56,13 +54,6 @@ struct _Set { SetFreeFunc free_func; }; -struct _SetIterator { - Set *set; - SetEntry *current_entry; - SetEntry *next_entry; - int next_chain; -}; - /* This is a set of good hash table prime numbers, from: * http://planetmath.org/encyclopedia/GoodHashTablePrimes.html * Each prime is roughly double the previous value, and as far as @@ -430,7 +421,7 @@ SetValue *set_to_array(Set *set) Set *set_union(Set *set1, Set *set2) { - SetIterator *iterator; + SetIterator iterator; Set *new_set; SetValue value; @@ -442,13 +433,13 @@ Set *set_union(Set *set1, Set *set2) /* Add all values from the first set */ - iterator = set_iterate(set1); + set_iterate(set1, &iterator); - while (set_iter_has_more(iterator)) { + while (set_iter_has_more(&iterator)) { /* Read the next value */ - value = set_iter_next(iterator); + value = set_iter_next(&iterator); /* Copy the value into the new set */ @@ -460,18 +451,16 @@ Set *set_union(Set *set1, Set *set2) return NULL; } } - - set_iter_free(iterator); /* Add all values from the second set */ - iterator = set_iterate(set2); + set_iterate(set2, &iterator); - while (set_iter_has_more(iterator)) { + while (set_iter_has_more(&iterator)) { /* Read the next value */ - value = set_iter_next(iterator); + value = set_iter_next(&iterator); /* Has this value been put into the new set already? * If so, do not insert this again */ @@ -487,15 +476,13 @@ Set *set_union(Set *set1, Set *set2) } } - set_iter_free(iterator); - return new_set; } Set *set_intersection(Set *set1, Set *set2) { Set *new_set; - SetIterator *iterator; + SetIterator iterator; SetValue value; new_set = set_new(set1->hash_func, set2->equal_func); @@ -506,13 +493,13 @@ Set *set_intersection(Set *set1, Set *set2) /* Iterate over all values in set 1. */ - iterator = set_iterate(set1); + set_iterate(set1, &iterator); - while (set_iter_has_more(iterator)) { + while (set_iter_has_more(&iterator)) { /* Get the next value */ - value = set_iter_next(iterator); + value = set_iter_next(&iterator); /* Is this value in set 2 as well? If so, it should be * in the new set. */ @@ -530,26 +517,14 @@ Set *set_intersection(Set *set1, Set *set2) } } - set_iter_free(iterator); - return new_set; } -SetIterator *set_iterate(Set *set) +void set_iterate(Set *set, SetIterator *iter) { - SetIterator *iter; int chain; - /* Create a new iterator object */ - - iter = malloc(sizeof(SetIterator)); - - if (iter == NULL) { - return NULL; - } - iter->set = set; - iter->current_entry = NULL; iter->next_entry = NULL; /* Find the first entry */ @@ -565,14 +540,13 @@ SetIterator *set_iterate(Set *set) } iter->next_chain = chain; - - return iter; } SetValue set_iter_next(SetIterator *iterator) { Set *set; SetValue result; + SetEntry *current_entry; int chain; set = iterator->set; @@ -585,16 +559,16 @@ SetValue set_iter_next(SetIterator *iterator) /* We have the result immediately */ - iterator->current_entry = iterator->next_entry; - result = iterator->current_entry->data; + current_entry = iterator->next_entry; + result = current_entry->data; /* Advance next_entry to the next SetEntry in the Set. */ - if (iterator->current_entry->next != NULL) { + if (current_entry->next != NULL) { /* Use the next value in this chain */ - iterator->next_entry = iterator->current_entry->next; + iterator->next_entry = current_entry->next; } else { @@ -635,8 +609,3 @@ int set_iter_has_more(SetIterator *iterator) return iterator->next_entry != NULL; } -void set_iter_free(SetIterator *iterator) -{ - free(iterator); -} - diff --git a/src/set.h b/src/set.h index 3f26ed0..66534f9 100644 --- a/src/set.h +++ b/src/set.h @@ -79,12 +79,28 @@ typedef struct _Set Set; typedef struct _SetIterator SetIterator; +/** + * Internal structure representing an entry in the set. + */ + +typedef struct _SetEntry SetEntry; + /** * A value stored in a @ref Set. */ typedef void *SetValue; +/** + * Definition of a @ref SetIterator. + */ + +struct _SetIterator { + Set *set; + SetEntry *next_entry; + int next_chain; +}; + /** * A null @ref SetValue. */ @@ -221,15 +237,14 @@ Set *set_union(Set *set1, Set *set2); Set *set_intersection(Set *set1, Set *set2); /** - * Create an iterator to iterate over the values in a set. - * It should be noted that a set iterator must be freed once iterating - * has been completed. This should be done using @ref set_iter_free. + * Initialise a @ref SetIterator structure to iterate over the values + * in a set. * * @param set The set to iterate over. - * @return A new iterator object. + * @param iter Pointer to an iterator structure to initialise. */ -SetIterator *set_iterate(Set *set); +void set_iterate(Set *set, SetIterator *iter); /** * Determine if there are more values in the set to iterate over. @@ -254,14 +269,6 @@ int set_iter_has_more(SetIterator *iterator); SetValue set_iter_next(SetIterator *iterator); -/** - * Free back a set iterator object. - * - * @param iterator The iterator to free. - */ - -void set_iter_free(SetIterator *iterator); - #ifdef __cplusplus } #endif diff --git a/test/test-set.c b/test/test-set.c index 5017c2d..b309091 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -294,7 +294,7 @@ void test_set_to_array(void) void test_set_iterating(void) { Set *set; - SetIterator *iterator; + SetIterator iterator; int count; set = generate_set(); @@ -302,17 +302,15 @@ void test_set_iterating(void) /* Iterate over all values in the set */ count = 0; - iterator = set_iterate(set); + set_iterate(set, &iterator); - while (set_iter_has_more(iterator)) { + while (set_iter_has_more(&iterator)) { - set_iter_next(iterator); + set_iter_next(&iterator); ++count; } - set_iter_free(iterator); - /* Check final count */ assert(count == 10000); @@ -323,11 +321,10 @@ void test_set_iterating(void) set = set_new(int_hash, int_equal); - iterator = set_iterate(set); + set_iterate(set, &iterator); - assert(set_iter_has_more(iterator) == 0); + assert(set_iter_has_more(&iterator) == 0); - set_iter_free(iterator); set_free(set); } @@ -338,7 +335,7 @@ void test_set_iterating(void) void test_set_iterating_remove(void) { Set *set; - SetIterator *iterator; + SetIterator iterator; int count; int removed; int *val; @@ -350,11 +347,11 @@ void test_set_iterating_remove(void) /* Iterate over all values in the set */ - iterator = set_iterate(set); + set_iterate(set, &iterator); - while (set_iter_has_more(iterator)) { + while (set_iter_has_more(&iterator)) { - val = (int *) set_iter_next(iterator); + val = (int *) set_iter_next(&iterator); if ((*val % 100) == 0) { @@ -368,8 +365,6 @@ void test_set_iterating_remove(void) ++count; } - set_iter_free(iterator); - /* Check final counts */ assert(count == 10000); From 27ff12983abc96d238bce80d5afed18f1db18898 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 16 Apr 2008 20:25:12 +0000 Subject: [PATCH 052/250] Make the singly-linked list type take a pointer to a structure to initialise rather than allocating an iterator. --- src/slist.c | 27 +-------------------------- src/slist.h | 27 ++++++++++++++------------- test/test-slist.c | 30 ++++++++++++------------------ 3 files changed, 27 insertions(+), 57 deletions(-) diff --git a/src/slist.c b/src/slist.c index e26ba05..edee7a0 100644 --- a/src/slist.c +++ b/src/slist.c @@ -44,14 +44,6 @@ struct _SListEntry { SListEntry *next; }; -/* Iterator for iterating over a singly-linked list. */ - -struct _SListIterator { - SListEntry **list; - SListEntry **prev_next; - SListEntry *current; -}; - void slist_free(SListEntry *list) { SListEntry *entry; @@ -442,18 +434,8 @@ SListEntry *slist_find_data(SListEntry *list, return NULL; } -SListIterator *slist_iterate(SListEntry **list) +void slist_iterate(SListEntry **list, SListIterator *iter) { - SListIterator *iter; - - /* Allocate the new structure */ - - iter = malloc(sizeof(SListIterator)); - - if (iter == NULL) { - return NULL; - } - /* Save the list location */ iter->list = list; @@ -462,8 +444,6 @@ SListIterator *slist_iterate(SListEntry **list) iter->prev_next = NULL; iter->current = NULL; - - return iter; } int slist_iter_has_more(SListIterator *iter) @@ -555,8 +535,3 @@ void slist_iter_remove(SListIterator *iter) } } -void slist_iter_free(SListIterator *iter) -{ - free(iter); -} - diff --git a/src/slist.h b/src/slist.h index 05a2a4e..c34c462 100644 --- a/src/slist.h +++ b/src/slist.h @@ -96,6 +96,16 @@ typedef struct _SListIterator SListIterator; typedef void *SListValue; +/** + * Definition of a @ref SListIterator. + */ + +struct _SListIterator { + SListEntry **list; + SListEntry **prev_next; + SListEntry *current; +}; + /** * A null @ref SListValue. */ @@ -260,15 +270,14 @@ SListEntry *slist_find_data(SListEntry *list, SListValue data); /** - * Create a new @ref SListIterator structure to iterate over a list. - * The iterator should be freed once iterating has completed, using - * the function @ref list_iter_free. + * Initialise a @ref SListIterator structure to iterate over a list. * * @param list Pointer to the list to iterate over. - * @return A new @ref SListIterator. + * @param iter Pointer to a @ref SListIterator structure to + * initialise. */ -SListIterator *slist_iterate(SListEntry **list); +void slist_iterate(SListEntry **list, SListIterator *iter); /** * Determine if there are more values in the list to iterate over. When @@ -302,13 +311,5 @@ SListValue slist_iter_next(SListIterator *iterator); void slist_iter_remove(SListIterator *iterator); -/** - * Free back a list iterator. - * - * @param iterator The list iterator. - */ - -void slist_iter_free(SListIterator *iterator); - #endif /* #ifndef ALGORITHM_SLIST_H */ diff --git a/test/test-slist.c b/test/test-slist.c index 839de91..e1fe68f 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -364,7 +364,7 @@ void test_slist_to_array(void) void test_slist_iterate(void) { SListEntry *list; - SListIterator *iter; + SListIterator iter; int *data; int a; int i; @@ -382,38 +382,34 @@ void test_slist_iterate(void) counter = 0; - iter = slist_iterate(&list); + slist_iterate(&list, &iter); /* Test remove before slist_iter_next has been called */ - slist_iter_remove(iter); + slist_iter_remove(&iter); /* Iterate over the list */ - while (slist_iter_has_more(iter)) { + while (slist_iter_has_more(&iter)) { - data = (int *) slist_iter_next(iter); + data = (int *) slist_iter_next(&iter); ++counter; /* Remove half the entries from the list */ if ((counter % 2) == 0) { - slist_iter_remove(iter); + slist_iter_remove(&iter); /* Test double remove */ - slist_iter_remove(iter); + slist_iter_remove(&iter); } } /* Test remove at the end of a list */ - slist_iter_remove(iter); - - /* Destroy the iterator */ - - slist_iter_free(iter); + slist_iter_remove(&iter); assert(counter == 50); assert(slist_length(list) == 25); @@ -423,22 +419,20 @@ void test_slist_iterate(void) list = NULL; counter = 0; - iter = slist_iterate(&list); + slist_iterate(&list, &iter); - while (slist_iter_has_more(iter)) { + while (slist_iter_has_more(&iter)) { - data = (int *) slist_iter_next(iter); + data = (int *) slist_iter_next(&iter); ++counter; /* Remove half the entries from the list */ if ((counter % 2) == 0) { - slist_iter_remove(iter); + slist_iter_remove(&iter); } } - - slist_iter_free(iter); assert(counter == 0); } From 05676d7c846311bde9fd7c4f722723385428e958 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 16 Apr 2008 20:41:46 +0000 Subject: [PATCH 053/250] Make the doubly-linked list type take a pointer to a structure to initialise rather than allocating an iterator. --- src/list.c | 27 +-------------------------- src/list.h | 27 +++++++++++++-------------- test/test-list.c | 26 +++++++++++--------------- 3 files changed, 25 insertions(+), 55 deletions(-) diff --git a/src/list.c b/src/list.c index 553762f..2ec7907 100644 --- a/src/list.c +++ b/src/list.c @@ -45,14 +45,6 @@ struct _ListEntry { ListEntry *next; }; -/* Iterator for iterating over a doubly-linked list. */ - -struct _ListIterator { - ListEntry **list; - ListEntry **prev_next; - ListEntry *current; -}; - void list_free(ListEntry *list) { ListEntry *entry; @@ -475,18 +467,8 @@ ListEntry *list_find_data(ListEntry *list, return NULL; } -ListIterator *list_iterate(ListEntry **list) +void list_iterate(ListEntry **list, ListIterator *iter) { - ListIterator *iter; - - /* Create a new iterator */ - - iter = malloc(sizeof(ListIterator)); - - if (iter == NULL) { - return NULL; - } - /* Save pointer to the list */ iter->list = list; @@ -495,8 +477,6 @@ ListIterator *list_iterate(ListEntry **list) iter->prev_next = NULL; iter->current = NULL; - - return iter; } int list_iter_has_more(ListIterator *iter) @@ -586,8 +566,3 @@ void list_iter_remove(ListIterator *iter) } } -void list_iter_free(ListIterator *iter) -{ - free(iter); -} - diff --git a/src/list.h b/src/list.h index ff3d093..ded6e7e 100644 --- a/src/list.h +++ b/src/list.h @@ -87,6 +87,16 @@ typedef struct _ListIterator ListIterator; typedef void *ListValue; +/** + * Definition of a @ref ListIterator. + */ + +struct _ListIterator { + ListEntry **list; + ListEntry **prev_next; + ListEntry *current; +}; + /** * A null @ref ListValue. */ @@ -266,16 +276,13 @@ ListEntry *list_find_data(ListEntry *list, ListValue data); /** - * Create an iterator to iterate over the values in a list. - * The iterator should be freed once iterating has completed, using - * the function @ref list_iter_free. + * Initialise a @ref ListIterator structure to iterate over a list. * * @param list A pointer to the list to iterate over. - * @return A new iterator, or NULL if it was not possible - * to allocate the memory for the iterator. + * @param iter A pointer to an iterator structure to initialise. */ -ListIterator *list_iterate(ListEntry **list); +void list_iterate(ListEntry **list, ListIterator *iter); /** * Determine if there are more values in the list to iterate over. When @@ -309,13 +316,5 @@ ListValue list_iter_next(ListIterator *iterator); void list_iter_remove(ListIterator *iterator); -/** - * Free back a list iterator. - * - * @param iterator The list iterator. - */ - -void list_iter_free(ListIterator *iterator); - #endif /* #ifndef ALGORITHM_LIST_H */ diff --git a/test/test-list.c b/test/test-list.c index c25bbc8..fe3ea9b 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -389,7 +389,7 @@ void test_list_to_array(void) void test_list_iterate(void) { ListEntry *list; - ListIterator *iter; + ListIterator iter; int i; int a; int counter; @@ -407,36 +407,32 @@ void test_list_iterate(void) counter = 0; - iter = list_iterate(&list); + list_iterate(&list, &iter); /* Test remove before list_iter_next has been called */ - list_iter_remove(iter); + list_iter_remove(&iter); /* Iterate over the list */ - while (list_iter_has_more(iter)) { - data = (int *) list_iter_next(iter); + while (list_iter_has_more(&iter)) { + data = (int *) list_iter_next(&iter); ++counter; if ((counter % 2) == 0) { /* Delete half the entries in the list. */ - list_iter_remove(iter); + list_iter_remove(&iter); /* Test double remove */ - list_iter_remove(iter); + list_iter_remove(&iter); } } /* Test remove at the end of a list */ - list_iter_remove(iter); - - /* Destroy the iterator */ - - list_iter_free(iter); + list_iter_remove(&iter); assert(counter == 50); assert(list_length(list) == 25); @@ -446,10 +442,10 @@ void test_list_iterate(void) list = NULL; counter = 0; - iter = list_iterate(&list); + list_iterate(&list, &iter); - while (list_iter_has_more(iter)) { - data = (int *) list_iter_next(iter); + while (list_iter_has_more(&iter)) { + data = (int *) list_iter_next(&iter); ++counter; } From 3ef977beffb555e77a82517d37aecef4b112d012 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 30 May 2008 00:51:18 +0000 Subject: [PATCH 054/250] Simplify linked list iterators and reduce iterator structure size. --- src/list.c | 71 ++++++++++++++++++++-------------------------------- src/list.h | 1 - src/slist.c | 72 ++++++++++++++++++----------------------------------- src/slist.h | 1 - 4 files changed, 51 insertions(+), 94 deletions(-) diff --git a/src/list.c b/src/list.c index 2ec7907..bceb3eb 100644 --- a/src/list.c +++ b/src/list.c @@ -469,30 +469,23 @@ ListEntry *list_find_data(ListEntry *list, void list_iterate(ListEntry **list, ListIterator *iter) { - /* Save pointer to the list */ - - iter->list = list; + /* Start iterating from the beginning of the list. */ + + iter->prev_next = list; - /* These are NULL until the first call to list_iter_next: */ + /* We have not yet read the first item. */ - iter->prev_next = NULL; iter->current = NULL; } int list_iter_has_more(ListIterator *iter) { - if (iter->prev_next == NULL) { - - /* The list has just been created. list_iter_next - * has not been called yet. There are more entries - * if the list is not empty. */ - - return *iter->list != NULL; - - } else if (*iter->prev_next != iter->current) { + if (iter->current == NULL) { - /* The entry last returned by list_iter_next has been - * deleted. The next entry is indincated by prev_next. */ + /* Either we have not read the first entry, the current + * item was removed or we have reached the end of the + * list. Use prev_next to determine if we have a next + * value to iterate over. */ return *iter->prev_next != NULL; @@ -507,22 +500,11 @@ int list_iter_has_more(ListIterator *iter) ListValue list_iter_next(ListIterator *iter) { - if (iter->prev_next == NULL) { - /* First call to list_iter_next. Initialise. */ - - /* Initial previous next link is the pointer to the list - * start variable */ - - iter->prev_next = iter->list; - - /* Start at the first element */ - - iter->current = *iter->list; - - } else if (*iter->prev_next != iter->current) { + if (iter->current == NULL) { - /* The value last returned by list_iter_next was deleted. - * Use prev_next to find the next entry. */ + /* Either we are reading the first entry, we have reached + * the end of the list, or the previous entry was removed. + * Get the next entry with iter->prev_next. */ iter->current = *iter->prev_next; @@ -531,13 +513,11 @@ ListValue list_iter_next(ListIterator *iter) /* Last value returned from list_iter_next was not deleted. * Advance to the next entry. */ - if (iter->current != NULL) { - iter->prev_next = &iter->current->next; - iter->current = iter->current->next; - } + iter->prev_next = &iter->current->next; + iter->current = iter->current->next; } - /* Return data from the current entry */ + /* Have we reached the end of the list? */ if (iter->current == NULL) { return LIST_NULL; @@ -548,21 +528,24 @@ ListValue list_iter_next(ListIterator *iter) void list_iter_remove(ListIterator *iter) { - if (iter->prev_next == NULL) { - - /* list_iter_next has not been called yet. */ - - } else if (*iter->prev_next != iter->current) { + if (iter->current == NULL) { - /* Current entry was already deleted. */ + /* Either we have not yet read the first item, we have + * reached the end of the list, or we have already removed + * the current value. Either way, do nothing. */ } else { /* Remove the current entry */ - if (iter->current != NULL) { - list_remove_entry(iter->list, iter->current); + *iter->prev_next = iter->current->next; + + if (iter->current->next != NULL) { + iter->current->next->prev = iter->current->prev; } + + free(iter->current); + iter->current = NULL; } } diff --git a/src/list.h b/src/list.h index ded6e7e..ff1fc63 100644 --- a/src/list.h +++ b/src/list.h @@ -92,7 +92,6 @@ typedef void *ListValue; */ struct _ListIterator { - ListEntry **list; ListEntry **prev_next; ListEntry *current; }; diff --git a/src/slist.c b/src/slist.c index edee7a0..5c471d5 100644 --- a/src/slist.c +++ b/src/slist.c @@ -436,30 +436,23 @@ SListEntry *slist_find_data(SListEntry *list, void slist_iterate(SListEntry **list, SListIterator *iter) { - /* Save the list location */ + /* Start iterating from the beginning of the list. */ - iter->list = list; + iter->prev_next = list; - /* These are NULL as we have not read the first item yet */ + /* We have not yet read the first item. */ - iter->prev_next = NULL; iter->current = NULL; } int slist_iter_has_more(SListIterator *iter) { - if (iter->prev_next == NULL) { - - /* The iterator has just been created. slist_iter_next - * has not been called yet. There are more entries if - * the list itself is not empty. */ - - return *iter->list != NULL; - - } else if (*iter->prev_next != iter->current) { + if (iter->current == NULL) { - /* The entry last returned from slist_iter_next has been - * deleted. The next entry is indicated by prev_next. */ + /* Either we have not read the first entry, the current + * item was removed or we have reached the end of the + * list. Use prev_next to determine if we have a next + * value to iterate over. */ return *iter->prev_next != NULL; @@ -469,29 +462,16 @@ int slist_iter_has_more(SListIterator *iter) * is a next entry if current->next is not NULL. */ return iter->current->next != NULL; - } } SListValue slist_iter_next(SListIterator *iter) { - if (iter->prev_next == NULL) { - - /* This is the first call to slist_iter_next. */ - - /* Initial prev_next is the list start variable */ - - iter->prev_next = iter->list; - - /* Start at the first element */ - - iter->current = *iter->list; - - } else if (*iter->prev_next != iter->current) { + if (iter->current == NULL) { - /* The value last returned by slist_iter_next was - * deleted. Use prev_next to find the next - * entry. */ + /* Either we are reading the first entry, we have reached + * the end of the list, or the previous entry was removed. + * Get the next entry with iter->prev_next. */ iter->current = *iter->prev_next; @@ -500,38 +480,34 @@ SListValue slist_iter_next(SListIterator *iter) /* Last value returned from slist_iter_next was not * deleted. Advance to the next entry. */ - if (iter->current != NULL) { - iter->prev_next = &iter->current->next; - iter->current = iter->current->next; - } + iter->prev_next = &iter->current->next; + iter->current = iter->current->next; } + /* Have we reached the end of the list? */ + if (iter->current == NULL) { return SLIST_NULL; } else { return iter->current->data; } - } void slist_iter_remove(SListIterator *iter) { - if (iter->prev_next == NULL) { - - /* slist_iter_next has not been called yet. */ - - } else if (*iter->prev_next != iter->current) { + if (iter->current == NULL) { - /* Current entry was already deleted */ - + /* Either we have not yet read the first item, we have + * reached the end of the list, or we have already removed + * the current value. Either way, do nothing. */ + } else { /* Remove the current entry */ - if (iter->current != NULL) { - *iter->prev_next = iter->current->next; - free(iter->current); - } + *iter->prev_next = iter->current->next; + free(iter->current); + iter->current = NULL; } } diff --git a/src/slist.h b/src/slist.h index c34c462..3f9dcfe 100644 --- a/src/slist.h +++ b/src/slist.h @@ -101,7 +101,6 @@ typedef void *SListValue; */ struct _SListIterator { - SListEntry **list; SListEntry **prev_next; SListEntry *current; }; From 73414fc1f4740abfe463108c488c03eba3569d71 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 30 May 2008 20:23:33 +0000 Subject: [PATCH 055/250] Make list iterators cope with the current element being removed independent of the iterator remove function. Add test cases for this. --- src/list.c | 6 +++--- src/slist.c | 6 +++--- test/test-list.c | 42 ++++++++++++++++++++++++++++++++++++++++++ test/test-slist.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 6 deletions(-) diff --git a/src/list.c b/src/list.c index bceb3eb..cd22467 100644 --- a/src/list.c +++ b/src/list.c @@ -480,7 +480,7 @@ void list_iterate(ListEntry **list, ListIterator *iter) int list_iter_has_more(ListIterator *iter) { - if (iter->current == NULL) { + if (iter->current == NULL || iter->current != *iter->prev_next) { /* Either we have not read the first entry, the current * item was removed or we have reached the end of the @@ -500,7 +500,7 @@ int list_iter_has_more(ListIterator *iter) ListValue list_iter_next(ListIterator *iter) { - if (iter->current == NULL) { + if (iter->current == NULL || iter->current != *iter->prev_next) { /* Either we are reading the first entry, we have reached * the end of the list, or the previous entry was removed. @@ -528,7 +528,7 @@ ListValue list_iter_next(ListIterator *iter) void list_iter_remove(ListIterator *iter) { - if (iter->current == NULL) { + if (iter->current == NULL || iter->current != *iter->prev_next) { /* Either we have not yet read the first item, we have * reached the end of the list, or we have already removed diff --git a/src/slist.c b/src/slist.c index 5c471d5..dc5b1f2 100644 --- a/src/slist.c +++ b/src/slist.c @@ -447,7 +447,7 @@ void slist_iterate(SListEntry **list, SListIterator *iter) int slist_iter_has_more(SListIterator *iter) { - if (iter->current == NULL) { + if (iter->current == NULL || iter->current != *iter->prev_next) { /* Either we have not read the first entry, the current * item was removed or we have reached the end of the @@ -467,7 +467,7 @@ int slist_iter_has_more(SListIterator *iter) SListValue slist_iter_next(SListIterator *iter) { - if (iter->current == NULL) { + if (iter->current == NULL || iter->current != *iter->prev_next) { /* Either we are reading the first entry, we have reached * the end of the list, or the previous entry was removed. @@ -495,7 +495,7 @@ SListValue slist_iter_next(SListIterator *iter) void slist_iter_remove(SListIterator *iter) { - if (iter->current == NULL) { + if (iter->current == NULL || iter->current != *iter->prev_next) { /* Either we have not yet read the first item, we have * reached the end of the list, or we have already removed diff --git a/test/test-list.c b/test/test-list.c index fe3ea9b..db0dd87 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -452,6 +452,47 @@ void test_list_iterate(void) assert(counter == 0); } +/* Test that the iterator functions can survive removal of the current + * value using the normal remove functions. */ + +void test_list_iterate_bad_remove(void) +{ + ListEntry *list; + ListIterator iter; + int values[49]; + int i; + int *val; + + /* Create a list with 49 entries */ + + list = NULL; + + for (i=0; i<49; ++i) { + values[i] = i; + list_prepend(&list, &values[i]); + } + + /* Iterate over the list, removing each element in turn. We + * use an odd number of list elements so that the first and + * last entries are removed. */ + + list_iterate(&list, &iter); + + while (list_iter_has_more(&iter)) { + val = list_iter_next(&iter); + + /* Remove all the even numbers. Check that list_iter_remove + * can cope with the fact that the current element has + * already been removed. */ + + if ((*val % 2) == 0) { + assert(list_remove_data(&list, int_equal, val) != 0); + list_iter_remove(&iter); + } + } +} + + int main(int argc, char *argv[]) { test_list_append(); @@ -467,6 +508,7 @@ int main(int argc, char *argv[]) test_list_find_data(); test_list_to_array(); test_list_iterate(); + test_list_iterate_bad_remove(); return 0; } diff --git a/test/test-slist.c b/test/test-slist.c index e1fe68f..560433f 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -437,6 +437,45 @@ void test_slist_iterate(void) assert(counter == 0); } +/* Test that the iterator functions can survive removal of the current + * value using the normal remove functions. */ + +void test_slist_iterate_bad_remove(void) +{ + SListEntry *list; + SListIterator iter; + int values[49]; + int i; + int *val; + + /* Create a list with 49 entries */ + + list = NULL; + + for (i=0; i<49; ++i) { + values[i] = i; + slist_prepend(&list, &values[i]); + } + + /* Iterate over the list, removing each element in turn. We + * use an odd number of list elements so that the first and + * last entries are removed. */ + + slist_iterate(&list, &iter); + + while (slist_iter_has_more(&iter)) { + val = slist_iter_next(&iter); + + /* Remove all the even numbers. Check that slist_iter_remove + * can cope with the fact that the current element has + * already been removed. */ + + if ((*val % 2) == 0) { + assert(slist_remove_data(&list, int_equal, val) != 0); + slist_iter_remove(&iter); + } + } +} int main(int argc, char *argv[]) { @@ -453,6 +492,7 @@ int main(int argc, char *argv[]) test_slist_find_data(); test_slist_to_array(); test_slist_iterate(); + test_slist_iterate_bad_remove(); return 0; } From 1cf6f0dfbee254a2baf9d2e1127f31c17a29a95e Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 30 May 2008 20:26:07 +0000 Subject: [PATCH 056/250] Fix tabs/spaces. --- src/list.c | 20 ++++++++++---------- src/set.c | 4 ++-- test/test-binomial-heap.c | 2 +- test/test-hash-table.c | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/list.c b/src/list.c index cd22467..6b64c99 100644 --- a/src/list.c +++ b/src/list.c @@ -482,10 +482,10 @@ int list_iter_has_more(ListIterator *iter) { if (iter->current == NULL || iter->current != *iter->prev_next) { - /* Either we have not read the first entry, the current - * item was removed or we have reached the end of the - * list. Use prev_next to determine if we have a next - * value to iterate over. */ + /* Either we have not read the first entry, the current + * item was removed or we have reached the end of the + * list. Use prev_next to determine if we have a next + * value to iterate over. */ return *iter->prev_next != NULL; @@ -502,9 +502,9 @@ ListValue list_iter_next(ListIterator *iter) { if (iter->current == NULL || iter->current != *iter->prev_next) { - /* Either we are reading the first entry, we have reached - * the end of the list, or the previous entry was removed. - * Get the next entry with iter->prev_next. */ + /* Either we are reading the first entry, we have reached + * the end of the list, or the previous entry was removed. + * Get the next entry with iter->prev_next. */ iter->current = *iter->prev_next; @@ -530,9 +530,9 @@ void list_iter_remove(ListIterator *iter) { if (iter->current == NULL || iter->current != *iter->prev_next) { - /* Either we have not yet read the first item, we have - * reached the end of the list, or we have already removed - * the current value. Either way, do nothing. */ + /* Either we have not yet read the first item, we have + * reached the end of the list, or we have already removed + * the current value. Either way, do nothing. */ } else { diff --git a/src/set.c b/src/set.c index 0783671..9d44083 100644 --- a/src/set.c +++ b/src/set.c @@ -433,7 +433,7 @@ Set *set_union(Set *set1, Set *set2) /* Add all values from the first set */ - set_iterate(set1, &iterator); + set_iterate(set1, &iterator); while (set_iter_has_more(&iterator)) { @@ -546,7 +546,7 @@ SetValue set_iter_next(SetIterator *iterator) { Set *set; SetValue result; - SetEntry *current_entry; + SetEntry *current_entry; int chain; set = iterator->set; diff --git a/test/test-binomial-heap.c b/test/test-binomial-heap.c index 03bf5ae..abcd39d 100644 --- a/test/test-binomial-heap.c +++ b/test/test-binomial-heap.c @@ -129,7 +129,7 @@ void test_max_heap(void) int main(int argc, char *argv[]) { test_binomial_heap_new_free(); - test_binomial_heap_insert(); + test_binomial_heap_insert(); test_min_heap(); test_max_heap(); diff --git a/test/test-hash-table.c b/test/test-hash-table.c index d6f03db..439a719 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -315,7 +315,7 @@ void test_hash_table_free_functions(void) hash_table_register_free_functions(hash_table, free_key, free_value); - allocated_values = 0; + allocated_values = 0; for (i=0; i<1000; ++i) { key = new_key(i); From ee19774531c06ce0ac9859d098ea3af44f8ba3ea Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 14:41:25 +0000 Subject: [PATCH 057/250] Indentation fixes. --- src/bloom-filter.c | 8 ++++---- src/hash-table.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bloom-filter.c b/src/bloom-filter.c index 33ccce1..bb66f2a 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -89,8 +89,8 @@ BloomFilter *bloom_filter_new(unsigned int table_size, } /* Allocate table, each entry is one bit; these are packed into - * bytes. When allocating we must round the length up to the nearest - * byte. */ + * bytes. When allocating we must round the length up to the nearest + * byte. */ filter->table = calloc((table_size + 7) / 8, 1); @@ -124,7 +124,7 @@ void bloom_filter_insert(BloomFilter *bloomfilter, BloomFilterValue value) hash = bloomfilter->hash_func(value); /* Generate multiple unique hashes by XORing with values in the - * salt table. */ + * salt table. */ for (i=0; inum_functions; ++i) { @@ -158,7 +158,7 @@ int bloom_filter_query(BloomFilter *bloomfilter, BloomFilterValue value) hash = bloomfilter->hash_func(value); /* Generate multiple unique hashes by XORing with values in the - * salt table. */ + * salt table. */ for (i=0; inum_functions; ++i) { diff --git a/src/hash-table.c b/src/hash-table.c index 2086f87..c29fa86 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -445,7 +445,7 @@ int hash_table_iter_has_more(HashTableIterator *iterator) HashTableValue hash_table_iter_next(HashTableIterator *iterator) { - HashTableEntry *current_entry; + HashTableEntry *current_entry; HashTable *hash_table; HashTableValue result; int chain; From e76f4322b3e073ebc334599fe2e3c202b7e4cce5 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 15:41:54 +0000 Subject: [PATCH 058/250] Use string keys for test cases to ensure hash collisions occur and are tested. --- test/test-hash-table.c | 72 ++++++++++++++++++++++++------------------ test/test-set.c | 51 ++++++++++++++++++------------ 2 files changed, 71 insertions(+), 52 deletions(-) diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 439a719..6f1b6dc 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -35,11 +35,14 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include "hash-table.h" #include "hash-int.h" #include "compare-int.h" +#include "hash-string.h" +#include "compare-string.h" int value1 = 1, value2 = 2, value3 = 3, value4 = 4; int allocated_keys = 0; @@ -50,19 +53,23 @@ int allocated_values = 0; HashTable *generate_hash_table(void) { HashTable *hash_table; - int *value; + char buf[10]; + char *value; int i; - /* Allocate a new hash table */ + /* Allocate a new hash table. We use a hash table with keys that are + * string versions of the integer values 0..9999 to ensure that there + * will be collisions within the hash table (using integer values + * with int_hash causes no collisions) */ - hash_table = hash_table_new(int_hash, int_equal); + hash_table = hash_table_new(string_hash, string_equal); /* Insert lots of values */ for (i=0; i<10000; ++i) { - value = (int *) malloc(sizeof(int)); + sprintf(buf, "%i", i); - *value = i; + value = strdup(buf); hash_table_insert(hash_table, value, value); } @@ -102,7 +109,8 @@ void test_hash_table_free(void) void test_hash_table_insert_lookup(void) { HashTable *hash_table; - int *value; + char buf[10]; + char *value; int i; /* Generate a hash table */ @@ -114,42 +122,41 @@ void test_hash_table_insert_lookup(void) /* Check all values */ for (i=0; i<10000; ++i) { - value = (int *) hash_table_lookup(hash_table, &i); + sprintf(buf, "%i", i); + value = hash_table_lookup(hash_table, buf); - assert(*value == i); + assert(strcmp(value, buf) == 0); } /* Lookup on invalid values returns NULL */ - i = -1; - assert(hash_table_lookup(hash_table, &i) == NULL); - i = 10000; - assert(hash_table_lookup(hash_table, &i) == NULL); + sprintf(buf, "%i", -1); + assert(hash_table_lookup(hash_table, buf) == NULL); + sprintf(buf, "%i", 10000); + assert(hash_table_lookup(hash_table, buf) == NULL); /* Insert overwrites existing entries with the same key */ - value = (int *) malloc(sizeof(int)); - *value = 12345; - i = 5000; - hash_table_insert(hash_table, &i, value); - value = (int *) hash_table_lookup(hash_table, &i); - assert(*value == 12345); + sprintf(buf, "%i", 12345); + hash_table_insert(hash_table, buf, "hello world"); + value = hash_table_lookup(hash_table, buf); + assert(strcmp(value, "hello world") == 0); } void test_hash_table_remove(void) { HashTable *hash_table; - int i; + char buf[10]; hash_table = generate_hash_table(); assert(hash_table_num_entries(hash_table) == 10000); - i = 5000; - assert(hash_table_lookup(hash_table, &i) != NULL); + sprintf(buf, "%i", 5000); + assert(hash_table_lookup(hash_table, buf) != NULL); /* Remove an entry */ - hash_table_remove(hash_table, &i); + hash_table_remove(hash_table, buf); /* Check entry counter */ @@ -157,12 +164,12 @@ void test_hash_table_remove(void) /* Check that NULL is returned now */ - assert(hash_table_lookup(hash_table, &i) == NULL); + assert(hash_table_lookup(hash_table, buf) == NULL); /* Try removing a non-existent entry */ - i = -1; - hash_table_remove(hash_table, &i); + sprintf(buf, "%i", -1); + hash_table_remove(hash_table, buf); assert(hash_table_num_entries(hash_table) == 9999); } @@ -206,7 +213,8 @@ void test_hash_table_iterating_remove(void) { HashTable *hash_table; HashTableIterator iterator; - int *val; + char buf[10]; + char *val; int count; int removed; int i; @@ -224,11 +232,11 @@ void test_hash_table_iterating_remove(void) /* Read the next value */ - val = (int *) hash_table_iter_next(&iterator); + val = hash_table_iter_next(&iterator); /* Remove every hundredth entry */ - if (*val % 100 == 0) { + if ((atoi(val) % 100) == 0) { hash_table_remove(hash_table, val); ++removed; } @@ -238,7 +246,7 @@ void test_hash_table_iterating_remove(void) /* Check counts */ - assert(removed == removed); + assert(removed == 100); assert(count == 10000); assert(hash_table_num_entries(hash_table) == 10000 - removed); @@ -246,10 +254,12 @@ void test_hash_table_iterating_remove(void) /* Check all entries divisible by 100 were really removed */ for (i=0; i<10000; ++i) { + sprintf(buf, "%i", i); + if (i % 100 == 0) { - assert(hash_table_lookup(hash_table, &i) == NULL); + assert(hash_table_lookup(hash_table, buf) == NULL); } else { - assert(hash_table_lookup(hash_table, &i) != NULL); + assert(hash_table_lookup(hash_table, buf) != NULL); } } } diff --git a/test/test-set.c b/test/test-set.c index b309091..d8d7ff0 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include "set.h" @@ -42,24 +43,26 @@ POSSIBILITY OF SUCH DAMAGE. #include "hash-int.h" #include "compare-pointer.h" #include "hash-pointer.h" +#include "compare-string.h" +#include "hash-string.h" int allocated_values; Set *generate_set(void) { Set *set; + char buf[10]; int i; - int *value; + char *value; - set = set_new(int_hash, int_equal); + set = set_new(string_hash, string_equal); /* Add 10,000 items sequentially, checking that the counter * works properly */ for (i=0; i<10000; ++i) { - value = (int *) malloc(sizeof(int)); - - *value = i; + sprintf(buf, "%i", i); + value = strdup(buf); set_insert(set, value); @@ -106,8 +109,6 @@ void test_set_insert(void) int numbers2[] = { 5, 6, 7, 8, 9, 10 }; int i; - set = generate_set(); - /* Perform a union of numbers1 and numbers2. Cannot add the same * value twice. */ @@ -126,6 +127,7 @@ void test_set_insert(void) void test_set_query(void) { Set *set; + char buf[10]; int i; set = generate_set(); @@ -133,20 +135,20 @@ void test_set_query(void) /* Test all values */ for (i=0; i<10000; ++i) { - assert(set_query(set, &i) != 0); + sprintf(buf, "%i", i); + assert(set_query(set, buf) != 0); } /* Test invalid values returning zero */ - i = -1; - assert(set_query(set, &i) == 0); - i = 100001; - assert(set_query(set, &i) == 0); + assert(set_query(set, "-1") == 0); + assert(set_query(set, "100001") == 0); } void test_set_remove(void) { Set *set; + char buf[10]; int i; int num_entries; @@ -158,13 +160,16 @@ void test_set_remove(void) /* Remove some entries */ for (i=4000; i<6000; ++i) { + + sprintf(buf, "%i", i); + /* Check this is in the set */ - assert(set_query(set, &i) != 0); + assert(set_query(set, buf) != 0); /* Remove it */ - assert(set_remove(set, &i) != 0); + assert(set_remove(set, buf) != 0); /* Check the number of entries decreases */ @@ -172,7 +177,7 @@ void test_set_remove(void) /* Check it is no longer in the set */ - assert(set_query(set, &i) == 0); + assert(set_query(set, buf) == 0); --num_entries; } @@ -180,12 +185,16 @@ void test_set_remove(void) /* Try to remove some invalid entries */ for (i=-1000; i<-500; ++i) { - assert(set_remove(set, &i) == 0); + sprintf(buf, "%i", i); + + assert(set_remove(set, buf) == 0); assert(set_num_entries(set) == num_entries); } for (i=50000; i<51000; ++i) { - assert(set_remove(set, &i) == 0); + sprintf(buf, "%i", i); + + assert(set_remove(set, buf) == 0); assert(set_num_entries(set) == num_entries); } } @@ -338,7 +347,7 @@ void test_set_iterating_remove(void) SetIterator iterator; int count; int removed; - int *val; + char *value; set = generate_set(); @@ -351,13 +360,13 @@ void test_set_iterating_remove(void) while (set_iter_has_more(&iterator)) { - val = (int *) set_iter_next(&iterator); + value = set_iter_next(&iterator); - if ((*val % 100) == 0) { + if ((atoi(value) % 100) == 0) { /* Remove this value */ - set_remove(set, val); + set_remove(set, value); ++removed; } From a93d2219a04e5d1408c5921bd864be9e4f26a216 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 16:49:12 +0000 Subject: [PATCH 059/250] Add tests for some uncovered code. --- test/Makefile.am | 2 +- test/test-arraylist.c | 13 ++++++++++--- test/test-binary-heap.c | 5 +++++ test/test-hash-table.c | 4 ++++ test/test-list.c | 4 ++++ test/test-set.c | 4 ++++ test/test-slist.c | 4 ++++ test/test-trie.c | 5 +++++ 8 files changed, 37 insertions(+), 4 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index ae833a1..a9ddad0 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -16,7 +16,7 @@ TESTS = \ noinst_PROGRAMS = $(TESTS) -AM_CFLAGS = -I../src -Wall +AM_CFLAGS = -I../src -Wall -fprofile-arcs -ftest-coverage LDADD = $(top_builddir)/src/libcalg.la test_arraylist_SOURCES = test-arraylist.c diff --git a/test/test-arraylist.c b/test/test-arraylist.c index 5bfbae8..8f264eb 100644 --- a/test/test-arraylist.c +++ b/test/test-arraylist.c @@ -158,6 +158,13 @@ void test_arraylist_insert(void) arraylist = generate_arraylist(); + /* Check for out of range insert */ + + assert(arraylist->length == 16); + assert(arraylist_insert(arraylist, -1, &variable1) == 0); + assert(arraylist_insert(arraylist, 17, &variable1) == 0); + assert(arraylist->length == 16); + /* Insert a new entry at index 5 */ assert(arraylist->length == 16); @@ -165,7 +172,7 @@ void test_arraylist_insert(void) assert(arraylist->data[5] == &variable2); assert(arraylist->data[6] == &variable3); - arraylist_insert(arraylist, 5, &variable4); + assert(arraylist_insert(arraylist, 5, &variable4) != 0); assert(arraylist->length == 17); assert(arraylist->data[4] == &variable1); @@ -179,7 +186,7 @@ void test_arraylist_insert(void) assert(arraylist->data[1] == &variable2); assert(arraylist->data[2] == &variable3); - arraylist_insert(arraylist, 0, &variable4); + assert(arraylist_insert(arraylist, 0, &variable4) != 0); assert(arraylist->length == 18); assert(arraylist->data[0] == &variable4); @@ -193,7 +200,7 @@ void test_arraylist_insert(void) assert(arraylist->data[16] == &variable3); assert(arraylist->data[17] == &variable4); - arraylist_insert(arraylist, 18, &variable1); + assert(arraylist_insert(arraylist, 18, &variable1) != 0); assert(arraylist->length == 19); assert(arraylist->data[15] == &variable2); diff --git a/test/test-binary-heap.c b/test/test-binary-heap.c index 3bf08ef..e9498d9 100644 --- a/test/test-binary-heap.c +++ b/test/test-binary-heap.c @@ -94,6 +94,11 @@ void test_min_heap(void) i = *val; } + /* Test popping from an empty heap */ + + assert(binary_heap_num_entries(heap) == 0); + assert(binary_heap_pop(heap) == BINARY_HEAP_NULL); + binary_heap_free(heap); } diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 6f1b6dc..8dc0219 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -196,6 +196,10 @@ void test_hash_table_iterating(void) assert(count == 10000); + /* Test iter_next after iteration has completed. */ + + assert(hash_table_iter_next(&iterator) == HASH_TABLE_NULL); + /* Test iterating over an empty table */ hash_table = hash_table_new(int_hash, int_equal); diff --git a/test/test-list.c b/test/test-list.c index db0dd87..9447edd 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -430,6 +430,10 @@ void test_list_iterate(void) } } + /* Test iter_next after iteration has completed. */ + + assert(list_iter_next(&iter) == NULL); + /* Test remove at the end of a list */ list_iter_remove(&iter); diff --git a/test/test-set.c b/test/test-set.c index d8d7ff0..3b56df2 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -320,6 +320,10 @@ void test_set_iterating(void) ++count; } + /* Test iter_next after iteration has completed. */ + + assert(set_iter_next(&iterator) == NULL); + /* Check final count */ assert(count == 10000); diff --git a/test/test-slist.c b/test/test-slist.c index 560433f..b5f9dac 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -406,6 +406,10 @@ void test_slist_iterate(void) slist_iter_remove(&iter); } } + + /* Test iter_next after iteration has completed. */ + + assert(slist_iter_next(&iter) == SLIST_NULL); /* Test remove at the end of a list */ diff --git a/test/test-trie.c b/test/test-trie.c index c6c7914..9d58a6d 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -109,6 +109,11 @@ void test_trie_insert_lookup_remove(void) assert(trie_num_entries(trie) == entries); } + /* Test lookup for non-existent values */ + + assert(trie_lookup(trie, "000000000000000") == TRIE_NULL); + assert(trie_lookup(trie, "") == TRIE_NULL); + /* Test remove on non-existent values. */ assert(trie_remove(trie, "000000000000000") == 0); From 981fa6f2939c94eba1163e30056ec434c4ae088c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 18:14:30 +0000 Subject: [PATCH 060/250] Remove coverage testing CFLAGS. --- test/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Makefile.am b/test/Makefile.am index a9ddad0..ae833a1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -16,7 +16,7 @@ TESTS = \ noinst_PROGRAMS = $(TESTS) -AM_CFLAGS = -I../src -Wall -fprofile-arcs -ftest-coverage +AM_CFLAGS = -I../src -Wall LDADD = $(top_builddir)/src/libcalg.la test_arraylist_SOURCES = test-arraylist.c From f5c844709f31b1693dcfbf4e50be831be5a7d72f Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 18:15:49 +0000 Subject: [PATCH 061/250] Use 8 space tabs, replace cvshistory with svnhistory. --- tools/cvshistory | 253 --------------------------------------------- tools/smart-indent | 2 +- tools/svnhistory | 189 +++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+), 254 deletions(-) delete mode 100755 tools/cvshistory create mode 100755 tools/svnhistory diff --git a/tools/cvshistory b/tools/cvshistory deleted file mode 100755 index d9c5784..0000000 --- a/tools/cvshistory +++ /dev/null @@ -1,253 +0,0 @@ -#!/usr/bin/perl -# -# A perl script to generate a history of CVS commits -# - -use strict; -use Date::Manip; - -my $quiet = 0; -my %changes = {}; - -sub get_change { - my ($date, $message, $author) = @_; - - my $key = int($date / 600) . ": $author : $message"; - - if (!$changes{$key}) { - $changes{$key} = { - files => [], - date => $date, - message => $message, - author => $author, - }; - } - - return $changes{$key}; -} - -sub read_file { - my $filename; - - # read headers - - while () { - chomp; - last if (/^\-+$/); - - if (/^Working file\:/) { - ($filename) = /^Working file\: (.*)$/; - } - } - - if (!$quiet) { - print STDERR "$filename\n"; - } - - # read revisions - - mainloop: while(1) { - $_ = ; chomp; - my ($revision) = /^revision (.*)/; - - $_ = ; chomp; - my ($date) = /date\: ([^\;]*)\;/; - $date = &UnixDate($date,"%s"); - - my ($author) = /author: ([^\;]*)\;/; - - my $message = ""; - - while () { - chomp; - last mainloop if /^\=+$/; - last if /^\-+$/; - next if /^branches\:/; - - $message .= "$_\n"; - } - - $message =~ s/^\n*//; - $message =~ s/\n*$//; - - my $change = get_change($date, $message, $author); - my $files = $change->{files}; - - push @$files, $filename; - } -} - -sub get_repository_name { - open (REPFILE, "CVS/Repository") or die "cant open CVS/Repository"; - - my $repname = ; - chomp $repname; - - close (REPFILE); - - return $repname; -} - -sub output_report { - my ($file) = @_; - my $title = "CVS History for '" . get_repository_name() . "'"; - - open(REPORT, ">$file") or die "cant open $file"; - - print REPORT "\n"; - print REPORT "$title\n"; - print REPORT "\n"; - - my @changekeys = sort {$changes{$a}->{date} <=> $changes{$b}->{date}} - keys %changes; - - print REPORT "

$title

\n"; - - foreach (@changekeys) { - next if !$changes{$_}->{date}; - - my $change = $changes{$_}; - print REPORT "

\n"; - print REPORT "\n"; - - print REPORT "\n"; - print REPORT "\n"; - - print REPORT "\n"; - print REPORT "\n"; - - print REPORT ""; - - my $files = $change->{files}; - - print REPORT "\n"; - - my $message = $change->{message}; - $message =~ s/\n/\\n/; - - print REPORT "\n"; - print REPORT "\n"; - - print REPORT "
Date" . localtime($change->{date}) - . "
User $change->{author}
Files"; - foreach (@$files) { - print REPORT "$_, "; - } - - print REPORT "
Message$message
\n"; - } - - print REPORT "\n\n\n"; - - close(REPORT); -} - -# output report to console - -sub console_report { - my @changekeys = sort {$changes{$b}->{date} <=> $changes{$a}->{date}} - keys %changes; - - foreach (@changekeys) { - next if !$changes{$_}->{date}; - - my $change = $changes{$_}; - - my $files = $change->{files}; - - if (scalar @$files == 1 && $files->[0] eq "ChangeLog") { - # Skip updates to the changelog itself - next; - } - - #print "Time: " . localtime($change->{date}) . "\n"; - print localtime($change->{date}) . " $change->{author}\n"; - print "\t\n"; - - if (0) { - # Prints list of files changed - - print "\t"; - my $curwid = 0; - my $first = 1; - - foreach (@$files) { - if ($first) { - $first = 0; - } else { - print ", "; - $curwid += 2; - } - if ($curwid + length("$_, ") > 70) { - $curwid = 0; - print "\n\t"; - } - print $_; - $curwid += length($_); - } - print ":\n"; - print "\t\n"; - } - - my @lines = split(/\n/, $change->{message}); - - foreach (@lines) { - print "\t$_\n"; - } - - print "\n"; - } -} - -sub usage { - print "Usage: $0 [-q] [-h] [-o file]\n"; - print "\n"; - print " -h: Print help information\n"; - print " -q: Quiet mode\n"; - print " -o: Output summary in HTML format to a file\n"; - print " If -o is not specified, an ascii report is output to the console.\n"; - exit; -} - -my $mode = 'console'; -my $outfile = ""; - -# parse command line - -for (my $i=0; $i<@ARGV; ++$i) { - if ($ARGV[$i] eq '-o' && $i+1 < @ARGV) { - ++$i; - $outfile = $ARGV[$i]; - $mode = 'html'; - } - if ($ARGV[$i] eq '-h') { - usage; - } - if ($ARGV[$i] eq '-q') { - $quiet = 1; - } -} - -if (!-e 'CVS') { - print "Error: there is no checked out CVS here. Try 'cvs checkout' first.\n"; - exit -1; -} - -open (CVSPIPE, "cvs -q log |"); - -if (!$quiet) { - print STDERR "Reading files..\n"; -} - -while () { - read_file; -} - -close(CVSPIPE); - -if ($mode eq 'html') { - output_report $outfile; -} else { - console_report; -} - diff --git a/tools/smart-indent b/tools/smart-indent index f8f9449..3e6079b 100755 --- a/tools/smart-indent +++ b/tools/smart-indent @@ -8,7 +8,7 @@ # view properly in any editor regardless of tab size. # -TAB_SIZE = 4 +TAB_SIZE = 8 def tab_out_to(characters) tabs = (characters / TAB_SIZE).to_i diff --git a/tools/svnhistory b/tools/svnhistory new file mode 100755 index 0000000..cd41b0e --- /dev/null +++ b/tools/svnhistory @@ -0,0 +1,189 @@ +#!/usr/bin/env ruby +# +# Copyright(C) Simon Howard +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +class Change + attr_accessor :author, :time, :description + + def initialize + @description = "" + end + + # Combine multiple lines of text into long run-on lines. Empty + # lines of text denote paragraphs. Lines beginning with '*' + # are also recognised as bullet point lists. + + def combine_lines(input) + result = "" + + input.each_line do |s| + s = s.chomp + + if result.length > 0 && result[-1, 1] != "\n" + + # Don't do any of this if we just started a new line + + if s =~ /^\s*$/ + # empty line; make this break a paragraph. + result += "\n\n" + elsif s =~ /^\s*\*/ + # bullet point + result += "\n" + else + result += " " + end + end + + result += s + end + + result + end + + # Reformat the description and break into lines + + def break_lines(input) + result = "" + + input.each_line do |s| + + if s =~ /^\s*$/ + # empty line + result += "\n" + else + + # Amount to indent each line by so that they align + # with the initial bullet point (if this line is a + # bullet point) + + indent_length = if s =~ /^(\s*\*\s*)/ + $1.length + else + 0 + end + + # Split this line into words, then add them to nextline + # one at a time until it reaches a 70 character limit. + + nextline = s[0, indent_length] + s = s[indent_length, s.length] + + words = s.split(/\s+/) + + words.each do |word| + + # If the next word will run over the limit, break + # onto a new line. + + if nextline.length > indent_length \ + && nextline.length + word.length + 1 > 70 + + result += nextline + "\n" + nextline = " " * indent_length + end + + # Space to separate from the previous word, but only + # if this is not the start of a line + + if nextline.length > indent_length + if nextline[-1, 1] == "." + + # Two spaces after a period + + nextline += " " + end + nextline += " " + end + + nextline += word + end + + # Print the last "unfinished" line + + if nextline.length > indent_length + result += nextline + "\n" + end + end + end + + result + end + + def remove_trailing_newlines(s) + while s[-2, 2] == "\n\n" + s = s.chop + end + + s + end + + def print_change + puts "#{@time} #{@author}" + puts "\t" + + munged = combine_lines(@description) + munged = break_lines(munged) + munged = remove_trailing_newlines(munged) + munged.each_line do |s| + puts "\t" + s + end + + puts + end +end + +changes = [] + +IO.popen("svn log .") do |io| + + current_change = nil + + io.each_line do |s| + + s = s.chomp + + if s =~ /^-+$/ + # start of a new change + + if current_change != nil + changes.push(current_change) + end + current_change = Change.new + elsif current_change.author == nil + # first line of new change + + fields = s.split(/ \| /) + current_change.author = fields[1] + + # time + timebits = fields[2].split(/\s+/) + current_change.time = timebits[0] + " " + timebits[1] + else + current_change.description += s + "\n" + end + end +end + +changes.each do |change| + change.print_change +end + From 165f774304593790102a5380b45bea8abb104554 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 18:16:21 +0000 Subject: [PATCH 062/250] Initialise new trie nodes with TRIE_NULL. --- src/trie.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/trie.c b/src/trie.c index 7d36ca2..9b9b57b 100644 --- a/src/trie.c +++ b/src/trie.c @@ -214,6 +214,8 @@ int trie_insert(Trie *trie, char *key, TrieValue value) return 0; } + node->data = TRIE_NULL; + /* Link in to the trie */ *rover = node; From 31b00c6b6c8d1fa3f2a62eb54fe1aaa705f5698b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 18:36:05 +0000 Subject: [PATCH 063/250] Documentation fixes. --- src/binary-heap.h | 9 +++++---- src/binomial-heap.h | 9 +++++---- src/hash-table.h | 5 +++++ src/list.h | 10 +++++----- src/set.h | 7 ++++++- src/slist.h | 12 ++++++++---- 6 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/binary-heap.h b/src/binary-heap.h index 61a6037..92249e6 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -58,10 +58,11 @@ extern "C" { #endif /** - * Heap type. If a heap is a min heap, the values with the lowest - * priority are stored at the top of the heap and will be the first - * returned. If a heap is a max heap, the values with the - * greatest priority are stored at the top of the heap. + * Heap type. If a heap is a min heap (@ref BINARY_HEAP_TYPE_MIN), the + * values with the lowest priority are stored at the top of the heap and + * will be the first returned. If a heap is a max heap + * (@ref BINARY_HEAP_TYPE_MAX), the values with the greatest priority are + * stored at the top of the heap. */ typedef enum { diff --git a/src/binomial-heap.h b/src/binomial-heap.h index 9d80659..3285d28 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -58,10 +58,11 @@ extern "C" { #endif /** - * Heap type. If a heap is a min heap, the values with the lowest - * priority are stored at the top of the heap and will be the first - * returned. If a heap is a max heap, the values with the - * greatest priority are stored at the top of the heap. + * Heap type. If a heap is a min heap (@ref BINOMIAL_HEAP_TYPE_MIN), the + * values with the lowest priority are stored at the top of the heap and + * will be the first returned. If a heap is a max heap + * (@ref BINOMIAL_HEAP_TYPE_MAX), the values with the greatest priority + * are stored at the top of the heap. */ typedef enum { diff --git a/src/hash-table.h b/src/hash-table.h index beff33d..075d600 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -50,6 +50,11 @@ POSSIBILITY OF SUCH DAMAGE. * To remove a value from a hash table, use @ref hash_table_remove. * * To look up a value by its key, use @ref hash_table_lookup. + * + * To iterate over all values in a hash table, use + * @ref hash_table_iterate to initialise a @ref HashTableIterator + * structure. Each value can then be read in turn using + * @ref hash_table_iter_next and @ref hash_table_iter_has_more. */ #ifndef ALGORITHM_HASH_TABLE_H diff --git a/src/list.h b/src/list.h index ff1fc63..44b2560 100644 --- a/src/list.h +++ b/src/list.h @@ -53,8 +53,10 @@ POSSIBILITY OF SUCH DAMAGE. * To remove data from a list, use @ref list_remove_entry or * @ref list_remove_data. * - * To iterate over entries in a list, use @ref list_next and @ref list_prev, - * along with the @ref list_data function to access data. + * To iterate over entries in a list, use @ref list_iterate to initialise + * a @ref ListIterator structure, with @ref list_iter_next + * @ref list_iter_has_more to retrieve each value in turn. + * @list_iter_remove can be used to remove the current entry. * * To access an entry in the list by index, use @ref list_nth_entry or * @ref list_nth_data. @@ -284,9 +286,7 @@ ListEntry *list_find_data(ListEntry *list, void list_iterate(ListEntry **list, ListIterator *iter); /** - * Determine if there are more values in the list to iterate over. When - * iteration is finished, the iterator should be freed using - * @ref list_iter_free. + * Determine if there are more values in the list to iterate over. * * @param iterator The list iterator. * @return Zero if there are no more values in the list to diff --git a/src/set.h b/src/set.h index 66534f9..4b403bc 100644 --- a/src/set.h +++ b/src/set.h @@ -51,7 +51,12 @@ POSSIBILITY OF SUCH DAMAGE. * * To query if a particular value is in a set, use @ref set_query. * - * To iterate over all values in a set, use @ref set_iterate. + * To iterate over all values in a set, use @ref set_iterate to initialise + * a @ref SetIterator structure, with @ref set_iter_next and + * @ref set_iter_has_more to read each value in turn. + * + * Two sets can be combined (union) using @ref set_union, while the + * intersection of two sets can be generated using @ref set_intersection. */ #ifndef ALGORITHM_SET_H diff --git a/src/slist.h b/src/slist.h index 3f9dcfe..699c983 100644 --- a/src/slist.h +++ b/src/slist.h @@ -64,7 +64,13 @@ POSSIBILITY OF SUCH DAMAGE. * To find a particular entry in a list by its index, use * @ref slist_nth_entry. * - * Given a particular entry in a list: + * To iterate over each value in a list, use @ref slist_iterate to + * initialise a @ref SListIterator structure, with @ref slist_iter_next + * and @ref slist_iter_has_more to retrieve each value in turn. + * @ref slist_iter_remove can be used to efficiently remove the + * current entry from the list. + * + * Given a particular entry in a list (@ref SListEntry): * * @li To find the next entry, use @ref slist_next. * @li To access the data stored at the entry, use @ref slist_data. @@ -279,9 +285,7 @@ SListEntry *slist_find_data(SListEntry *list, void slist_iterate(SListEntry **list, SListIterator *iter); /** - * Determine if there are more values in the list to iterate over. When - * iteration is finished, the iterator should be freed using - * @ref slist_iter_free. + * Determine if there are more values in the list to iterate over. * * @param iterator The list iterator. * @return Zero if there are no more values in the list to From 4eb8b90d514b0904dc9554441245b12692e74715 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 18:39:28 +0000 Subject: [PATCH 064/250] Fix documentation error. --- src/list.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/list.h b/src/list.h index 44b2560..4c1c1e2 100644 --- a/src/list.h +++ b/src/list.h @@ -54,7 +54,7 @@ POSSIBILITY OF SUCH DAMAGE. * @ref list_remove_data. * * To iterate over entries in a list, use @ref list_iterate to initialise - * a @ref ListIterator structure, with @ref list_iter_next + * a @ref ListIterator structure, with @ref list_iter_next and * @ref list_iter_has_more to retrieve each value in turn. * @list_iter_remove can be used to remove the current entry. * From ac6272d9f6a6990658e6c08d1396c3250bd44b75 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 19:08:47 +0000 Subject: [PATCH 065/250] Documentation fixes: "data"->"value". --- src/arraylist.h | 46 +++++++++++++++--------------- src/avl-tree.h | 14 +++++----- src/binary-heap.h | 14 ++++++---- src/binomial-heap.h | 15 +++++----- src/hash-table.h | 10 +++---- src/list.h | 68 ++++++++++++++++++++++----------------------- src/queue.h | 38 ++++++++++++------------- src/set.h | 37 ++++++++++++------------ src/slist.h | 63 +++++++++++++++++++++-------------------- src/trie.h | 2 +- 10 files changed, 157 insertions(+), 150 deletions(-) diff --git a/src/arraylist.h b/src/arraylist.h index f9361d9..92aa155 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -44,10 +44,10 @@ POSSIBILITY OF SUCH DAMAGE. * To create an ArrayList, use @ref arraylist_new. * To destroy an ArrayList, use @ref arraylist_free. * - * To add data an ArrayList, use @ref arraylist_prepend, + * To add a value to an ArrayList, use @ref arraylist_prepend, * @ref arraylist_append, or @ref arraylist_insert. * - * To remove data from an ArrayList, use @ref arraylist_remove + * To remove a value from an ArrayList, use @ref arraylist_remove * or @ref arraylist_remove_range. */ @@ -92,21 +92,22 @@ typedef struct _ArrayList { * @return Non-zero if the values are not equal, zero if they are equal. */ -typedef int (*ArrayListEqualFunc)(ArrayListValue data1, ArrayListValue data2); +typedef int (*ArrayListEqualFunc)(ArrayListValue value1, ArrayListValue value2); /** * Compare two values in an arraylist. Used by @ref arraylist_sort * when sorting values. * - * @param data1 The first value. - * @param data2 The second value. - * @return A negative number if data1 should be sorted - * before data2, a positive number if data2 should - * be sorted before data1, zero if the two values + * @param value1 The first value. + * @param value2 The second value. + * @return A negative number if value1 should be sorted + * before value2, a positive number if value2 should + * be sorted before value1, zero if the two values * are equal. */ -typedef int (*ArrayListCompareFunc)(ArrayListValue data1, ArrayListValue data2); +typedef int (*ArrayListCompareFunc)(ArrayListValue value1, + ArrayListValue value2); /** * Allocate a new ArrayList for use. @@ -129,10 +130,10 @@ ArrayList *arraylist_new(int length); void arraylist_free(ArrayList *arraylist); /** - * Append data to the end of an ArrayList. + * Append a value to the end of an ArrayList. * * @param arraylist The ArrayList. - * @param data The data to append. + * @param data The value to append. * @return Non-zero if the request was successful, zero * if it was not possible to allocate more memory * for the new entry. @@ -141,10 +142,10 @@ void arraylist_free(ArrayList *arraylist); int arraylist_append(ArrayList *arraylist, ArrayListValue data); /** - * Prepend data to the beginning of an ArrayList. + * Prepend a value to the beginning of an ArrayList. * * @param arraylist The ArrayList. - * @param data The data to prepend. + * @param data The value to prepend. * @return Non-zero if the request was successful, zero * if it was not possible to allocate more memory * for the new entry. @@ -172,13 +173,13 @@ void arraylist_remove(ArrayList *arraylist, int index); void arraylist_remove_range(ArrayList *arraylist, int index, int length); /** - * Insert new data at the specified index in an ArrayList. - * The index where new data can be inserted is limited by the + * Insert a value at the specified index in an ArrayList. + * The index where the new value can be inserted is limited by the * size of the ArrayList. * * @param arraylist The ArrayList. - * @param index The index at which to insert the data. - * @param data The data. + * @param index The index at which to insert the value. + * @param data The value. * @return Returns zero if unsuccessful, else non-zero * if successful (due to an invalid index or * if it was impossible to allocate more memory). @@ -187,13 +188,14 @@ void arraylist_remove_range(ArrayList *arraylist, int index, int length); int arraylist_insert(ArrayList *arraylist, int index, ArrayListValue data); /** - * Find the index of a particular pointer in an ArrayList. + * Find the index of a particular value in an ArrayList. * * @param arraylist The ArrayList to search. - * @param callback Callback function to be invoked to determine if - * values are equal to the data to search for. - * @param data The data to search for. - * @return The index of the data if found, or -1 if not found. + * @param callback Callback function to be invoked to compare + * values in the list with the value to be + * searched for. + * @param data The value to search for. + * @return The index of the value if found, or -1 if not found. */ int arraylist_index_of(ArrayList *arraylist, diff --git a/src/avl-tree.h b/src/avl-tree.h index 01cd9a7..b482f30 100644 --- a/src/avl-tree.h +++ b/src/avl-tree.h @@ -115,15 +115,15 @@ typedef struct _AVLTreeNode AVLTreeNode; /** * Type of function used to compare keys in an AVL tree. * - * @param data1 The first key. - * @param data2 The second key. - * @return A negative number if data1 should be sorted - * before data2, a positive number if data2 should - * be sorted before data1, zero if the two keys + * @param value1 The first key. + * @param value2 The second key. + * @return A negative number if value1 should be sorted + * before value2, a positive number if value2 should + * be sorted before value1, zero if the two keys * are equal. */ -typedef int (*AVLTreeCompareFunc)(AVLTreeValue data1, AVLTreeValue data2); +typedef int (*AVLTreeCompareFunc)(AVLTreeValue value1, AVLTreeValue value2); /** * Create a new AVL tree. @@ -199,7 +199,7 @@ AVLTreeNode *avl_tree_lookup_node(AVLTree *tree, AVLTreeKey key); * @param tree The AVL tree to search. * @param key The key to search for. * @return The value associated with the given key, or - * AVLTREE_NULL if no entry with the given key is + * @ref AVLTREE_NULL if no entry with the given key is * found. */ diff --git a/src/binary-heap.h b/src/binary-heap.h index 92249e6..7c2d008 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -85,14 +85,15 @@ typedef void *BinaryHeapValue; /** * Type of function used to compare values in a binary heap. * - * @param data1 The first value. - * @param data2 The second value. - * @return A negative number if data1 is less than data2, - * a positive number if data1 is greater than data2, + * @param value1 The first value. + * @param value2 The second value. + * @return A negative number if value1 is less than value2, + * a positive number if value1 is greater than value2, * zero if the two are equal. */ -typedef int (*BinaryHeapCompareFunc)(BinaryHeapValue data1, BinaryHeapValue data2); +typedef int (*BinaryHeapCompareFunc)(BinaryHeapValue value1, + BinaryHeapValue value2); /** * A binary heap data structure. @@ -137,7 +138,8 @@ int binary_heap_insert(BinaryHeap *heap, BinaryHeapValue value); * Remove the first value from a binary heap. * * @param heap The heap. - * @return The first value in the heap. + * @return The first value in the heap, or + * @ref BINARY_HEAP_NULL if the heap is empty. */ BinaryHeapValue binary_heap_pop(BinaryHeap *heap); diff --git a/src/binomial-heap.h b/src/binomial-heap.h index 3285d28..94abe48 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -85,15 +85,15 @@ typedef void *BinomialHeapValue; /** * Type of function used to compare values in a binomial heap. * - * @param data1 The first value. - * @param data2 The second value. - * @return A negative number if data1 is less than data2, - * a positive number if data1 is greater than data2, + * @param value1 The first value. + * @param value2 The second value. + * @return A negative number if value1 is less than value2, + * a positive number if value1 is greater than value2, * zero if the two are equal. */ -typedef int (*BinomialHeapCompareFunc)(BinomialHeapValue data1, - BinomialHeapValue data2); +typedef int (*BinomialHeapCompareFunc)(BinomialHeapValue value1, + BinomialHeapValue value2); /** * A binomial heap data structure. @@ -138,7 +138,8 @@ int binomial_heap_insert(BinomialHeap *heap, BinomialHeapValue value); * Remove the first value from a binomial heap. * * @param heap The heap. - * @return The first value in the heap. + * @return The first value in the heap, or + * @ref BINOMIAL_HEAP_NULL if the heap is empty. */ BinomialHeapValue binomial_heap_pop(BinomialHeap *heap); diff --git a/src/hash-table.h b/src/hash-table.h index 075d600..e1870a0 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -114,11 +114,11 @@ struct _HashTableIterator { * Hash function used to generate hash values for keys used in a hash * table. * - * @param data The value to generate a hash value for. + * @param value The value to generate a hash value for. * @return The hash value. */ -typedef unsigned long (*HashTableHashFunc)(HashTableKey data); +typedef unsigned long (*HashTableHashFunc)(HashTableKey value); /** * Function used to compare two keys for equality. @@ -127,21 +127,21 @@ typedef unsigned long (*HashTableHashFunc)(HashTableKey data); * not equal. */ -typedef int (*HashTableEqualFunc)(HashTableKey data1, HashTableKey data2); +typedef int (*HashTableEqualFunc)(HashTableKey value1, HashTableKey value2); /** * Type of function used to free keys when entries are removed from a * hash table. */ -typedef void (*HashTableKeyFreeFunc)(HashTableKey data); +typedef void (*HashTableKeyFreeFunc)(HashTableKey value); /** * Type of function used to free values when entries are removed from a * hash table. */ -typedef void (*HashTableValueFreeFunc)(HashTableValue data); +typedef void (*HashTableValueFreeFunc)(HashTableValue value); /** * Create a new hash table. diff --git a/src/list.h b/src/list.h index 4c1c1e2..6c95c02 100644 --- a/src/list.h +++ b/src/list.h @@ -48,9 +48,9 @@ POSSIBILITY OF SUCH DAMAGE. * a @ref ListEntry structure, and initialise it to NULL. * To destroy an entire list, use @ref list_free. * - * To add data to a list, use @ref list_append or @ref list_prepend. + * To add a value to a list, use @ref list_append or @ref list_prepend. * - * To remove data from a list, use @ref list_remove_entry or + * To remove a value from a list, use @ref list_remove_entry or * @ref list_remove_data. * * To iterate over entries in a list, use @ref list_iterate to initialise @@ -107,26 +107,26 @@ struct _ListIterator { /** * Callback function used to compare values in a list when sorting. * - * @param data1 The first value to compare. - * @param data2 The second value to compare. - * @return A negative value if data1 should be sorted before - * data2, a positive value if data1 should be sorted - * after data2, zero if data1 and data2 are equal. + * @param value1 The first value to compare. + * @param value2 The second value to compare. + * @return A negative value if value1 should be sorted before + * value2, a positive value if value1 should be sorted + * after value2, zero if value1 and value2 are equal. */ -typedef int (*ListCompareFunc)(ListValue data1, ListValue data2); +typedef int (*ListCompareFunc)(ListValue value1, ListValue value2); /** * Callback function used to determine of two values in a list are * equal. * - * @param data1 The first value to compare. - * @param data2 The second value to compare. - * @return A non-zero value if data1 and data2 are equal, zero + * @param value1 The first value to compare. + * @param value2 The second value to compare. + * @return A non-zero value if value1 and value2 are equal, zero * if they are not equal. */ -typedef int (*ListEqualFunc)(ListValue data1, ListValue data2); +typedef int (*ListEqualFunc)(ListValue value1, ListValue value2); /** * Free an entire list. @@ -137,23 +137,23 @@ typedef int (*ListEqualFunc)(ListValue data1, ListValue data2); void list_free(ListEntry *list); /** - * Prepend data to the start of a list. + * Prepend a value to the start of a list. * * @param list Pointer to the list to prepend to. - * @param data Data to prepend. - * @return The new entry in the list, or NULL if it was not possible - * to allocate the memory for the new entry. + * @param data The value to prepend. + * @return The new entry in the list, or NULL if it was not + * possible to allocate the memory for the new entry. */ ListEntry *list_prepend(ListEntry **list, ListValue data); /** - * Append data to the end of a list. + * Append a value to the end of a list. * * @param list Pointer to the list to append to. - * @param data Data to append. - * @return The new entry in the list, or NULL if it was not possible - * to allocate the memory for the new entry. + * @param value The value to append. + * @return The new entry in the list, or NULL if it was not + * possible to allocate the memory for the new entry. */ ListEntry *list_append(ListEntry **list, ListValue data); @@ -179,10 +179,10 @@ ListEntry *list_prev(ListEntry *listentry); ListEntry *list_next(ListEntry *listentry); /** - * Retrieve the data at a list entry. + * Retrieve the value at a list entry. * * @param listentry Pointer to the list entry. - * @return The data at the list entry. + * @return The value stored at the list entry. */ ListValue list_data(ListEntry *listentry); @@ -198,11 +198,11 @@ ListValue list_data(ListEntry *listentry); ListEntry *list_nth_entry(ListEntry *list, int n); /** - * Retrieve the data at a specified entry in the list. + * Retrieve the value at a specified index in the list. * * @param list The list. - * @param n The index into the list . - * @return The data at the specified index, or LIST_NULL if + * @param n The index into the list. + * @return The value at the specified index, or @ref LIST_NULL if * unsuccessful. */ @@ -241,12 +241,12 @@ ListValue *list_to_array(ListEntry *list); int list_remove_entry(ListEntry **list, ListEntry *entry); /** - * Remove all occurrences of a particular piece of data from a list. + * Remove all occurrences of a particular value from a list. * * @param list Pointer to the list. - * @param callback Function to invoke to compare data against the - * data to be removed. - * @param data The data to remove from the list. + * @param callback Function to invoke to compare values in the list + * with the value to be removed. + * @param data The value to remove from the list. * @return The number of entries removed from the list. */ @@ -262,12 +262,12 @@ int list_remove_data(ListEntry **list, ListEqualFunc callback, ListValue data); void list_sort(ListEntry **list, ListCompareFunc compare_func); /** - * Find the entry for a particular data item in a list. + * Find the entry for a particular value in a list. * * @param list The list to search. - * @param callback Callback function to be invoked to determine if - * values are equal to the data to search for. - * @param data The data to search for. + * @param callback Function to invoke to compare values in the list + * with the value to be searched for. + * @param data The value to search for. * @return The list entry of the item being searched for, or * NULL if not found. */ @@ -300,7 +300,7 @@ int list_iter_has_more(ListIterator *iterator); * Using a list iterator, retrieve the next value from the list. * * @param iterator The list iterator. - * @return The next value from the list, or LIST_NULL if + * @return The next value from the list, or @ref LIST_NULL if * there are no more values in the list. */ diff --git a/src/queue.h b/src/queue.h index 3ea912d..3c9f6da 100644 --- a/src/queue.h +++ b/src/queue.h @@ -39,17 +39,17 @@ POSSIBILITY OF SUCH DAMAGE. * * @brief Double-ended queue. * - * A double ended queue stores a list of pointers in order. New data + * A double ended queue stores a list of values in order. New values * can be added and removed from either end of the queue. * * To create a new queue, use @ref queue_new. To destroy a queue, use * @ref queue_free. * - * To add data to a queue, use @ref queue_push_head and + * To add values to a queue, use @ref queue_push_head and * @ref queue_push_tail. * - * To read data from the ends of a queue, use @ref queue_pop_head - * and @ref queue_pop_tail. To examine the ends without removing data + * To read values from the ends of a queue, use @ref queue_pop_head + * and @ref queue_pop_tail. To examine the ends without removing values * from the queue, use @ref queue_peek_head and @ref queue_peek_tail. * */ @@ -97,10 +97,10 @@ Queue *queue_new(void); void queue_free(Queue *queue); /** - * Add data to the head of a queue. + * Add a value to the head of a queue. * * @param queue The queue. - * @param data The data to add. + * @param data The value to add. * @return Non-zero if the value was added successfully, or zero * if it was not possible to allocate the memory for the * new entry. @@ -109,31 +109,31 @@ void queue_free(Queue *queue); int queue_push_head(Queue *queue, QueueValue data); /** - * Remove data from the head of a queue. + * Remove a value from the head of a queue. * * @param queue The queue. - * @return Data at the head of the queue, or QUEUE_NULL if the - * queue is empty. + * @return Value that was at the head of the queue, or + * @ref QUEUE_NULL if the queue is empty. */ QueueValue queue_pop_head(Queue *queue); /** - * Read data from the head of queue, without removing it from + * Read value from the head of a queue, without removing it from * the queue. * * @param queue The queue. - * @return Data at the head of the queue, or QUEUE_NULL if the + * @return Value at the head of the queue, or @ref QUEUE_NULL if the * queue is empty. */ QueueValue queue_peek_head(Queue *queue); /** - * Add data to the tail of a queue. + * Add a value to the tail of a queue. * * @param queue The queue. - * @param data The data to add. + * @param data The value to add. * @return Non-zero if the value was added successfully, or zero * if it was not possible to allocate the memory for the * new entry. @@ -142,28 +142,28 @@ QueueValue queue_peek_head(Queue *queue); int queue_push_tail(Queue *queue, QueueValue data); /** - * Remove data from the tail of a queue. + * Remove a value from the tail of a queue. * * @param queue The queue. - * @return Data at the head of the queue, or QUEUE_NULL if the - * queue is empty. + * @return Value that was at the head of the queue, or + * @ref QUEUE_NULL if the queue is empty. */ QueueValue queue_pop_tail(Queue *queue); /** - * Read data from the tail of queue, without removing it from + * Read a value from the tail of a queue, without removing it from * the queue. * * @param queue The queue. - * @return Data at the tail of the queue, or QUEUE_NULL if the + * @return Value at the tail of the queue, or QUEUE_NULL if the * queue is empty. */ QueueValue queue_peek_tail(Queue *queue); /** - * Query if any data is currently in a queue. + * Query if any values are currently in a queue. * * @param queue The queue. * @return Zero if the queue is not empty, non-zero if the queue diff --git a/src/set.h b/src/set.h index 4b403bc..5ad147e 100644 --- a/src/set.h +++ b/src/set.h @@ -67,11 +67,8 @@ extern "C" { #endif /** - * Represents a set of data. Created using the set_new function and destroyed - * using the set_free function. - * - * @see set_new - * @see set_free + * Represents a set of values. Created using the @ref set_new function and + * destroyed using the @ref set_free function. */ typedef struct _Set Set; @@ -113,29 +110,29 @@ struct _SetIterator { #define SET_NULL ((void *) 0) /** - * Hash function. Generates a hash key for data to be stored in a set. + * Hash function. Generates a hash key for values to be stored in a set. */ -typedef unsigned long (*SetHashFunc)(SetValue data); +typedef unsigned long (*SetHashFunc)(SetValue value); /** * Equality function. Compares two values to determine if they are * equivalent. */ -typedef int (*SetEqualFunc)(SetValue data1, SetValue data2); +typedef int (*SetEqualFunc)(SetValue value1, SetValue value2); /** * Function used to free values stored in a set. See * @ref set_register_free_function. */ -typedef void (*SetFreeFunc)(SetValue data); +typedef void (*SetFreeFunc)(SetValue value); /** * Create a new set. * - * @param hash_func Hash function used on data in the set . + * @param hash_func Hash function used on values in the set. * @param equal_func Compares two values in the set to determine * if they are equal. * @return A new set, or NULL if it was not possible to @@ -167,7 +164,7 @@ void set_register_free_function(Set *set, SetFreeFunc free_func); * Add a value to a set. * * @param set The set. - * @param data The data to add to the set . + * @param data The value to add to the set. * @return Non-zero (true) if the value was added to the set, * zero (false) if it already exists in the set, or * if it was not possible to allocate memory for the @@ -180,9 +177,9 @@ int set_insert(Set *set, SetValue data); * Remove a value from a set. * * @param set The set. - * @param data The data to remove from the set. - * @return Non-zero (true) if the data was found and removed - * from the set, zero (false) if the data was not + * @param data The value to remove from the set. + * @return Non-zero (true) if the value was found and removed + * from the set, zero (false) if the value was not * found in the set. */ @@ -192,9 +189,9 @@ int set_remove(Set *set, SetValue data); * Query if a particular value is in a set. * * @param set The set. - * @param data The data to query for. - * @return Zero if the data is not in the set, non-zero if the - * data is in the set. + * @param data The value to query for. + * @return Zero if the value is not in the set, non-zero if the + * value is in the set. */ int set_query(Set *set, SetValue data); @@ -212,7 +209,9 @@ int set_num_entries(Set *set); * Create an array containing all entries in a set. * * @param set The set. - * @return An array containing all entries in the set. + * @return An array containing all entries in the set, + * or NULL if it was not possible to allocate + * memory for the array. */ SetValue *set_to_array(Set *set); @@ -268,7 +267,7 @@ int set_iter_has_more(SetIterator *iterator); * Using a set iterator, retrieve the next value from the set. * * @param iterator The set iterator. - * @return The next value from the set, or SET_NULL if no + * @return The next value from the set, or @ref SET_NULL if no * more values are available. */ diff --git a/src/slist.h b/src/slist.h index 699c983..2f923b0 100644 --- a/src/slist.h +++ b/src/slist.h @@ -49,15 +49,15 @@ POSSIBILITY OF SUCH DAMAGE. * * To destroy a singly linked list, use @ref slist_free. * - * To add new data at the start of a list, use @ref slist_prepend. - * To add new data at the end of a list, use @ref slist_append. + * To add a new value at the start of a list, use @ref slist_prepend. + * To add a new value at the end of a list, use @ref slist_append. * * To find the length of a list, use @ref slist_length. * - * To access data in a list by its index in the list, use + * To access a value in a list by its index in the list, use * @ref slist_nth_data. * - * To search a list for data, use @ref slist_find_data. + * To search a list for a value, use @ref slist_find_data. * * To sort a list into an order, use @ref slist_sort. * @@ -73,7 +73,7 @@ POSSIBILITY OF SUCH DAMAGE. * Given a particular entry in a list (@ref SListEntry): * * @li To find the next entry, use @ref slist_next. - * @li To access the data stored at the entry, use @ref slist_data. + * @li To access the value stored at the entry, use @ref slist_data. * @li To remove the entry, use @ref slist_remove_entry. * */ @@ -120,22 +120,22 @@ struct _SListIterator { /** * Callback function used to compare values in a list when sorting. * - * @return A negative value if data1 should be sorted before data2, - * a positive value if data1 should be sorted after data2, - * zero if data1 and data2 are equal. + * @return A negative value if value1 should be sorted before value2, + * a positive value if value1 should be sorted after value2, + * zero if value1 and value2 are equal. */ -typedef int (*SListCompareFunc)(SListValue data1, SListValue data2); +typedef int (*SListCompareFunc)(SListValue value1, SListValue value2); /** * Callback function used to determine of two values in a list are * equal. * - * @return A non-zero value if data1 and data2 are equal, zero if they + * @return A non-zero value if value1 and value2 are equal, zero if they * are not equal. */ -typedef int (*SListEqualFunc)(SListValue data1, SListValue data2); +typedef int (*SListEqualFunc)(SListValue value1, SListValue value2); /** * Free an entire list. @@ -146,10 +146,10 @@ typedef int (*SListEqualFunc)(SListValue data1, SListValue data2); void slist_free(SListEntry *list); /** - * Prepend data to the start of a list. + * Prepend a value to the start of a list. * * @param list Pointer to the list to prepend to. - * @param data Data to prepend. + * @param data The value to prepend. * @return The new entry in the list, or NULL if it was not possible * to allocate a new entry. */ @@ -157,10 +157,10 @@ void slist_free(SListEntry *list); SListEntry *slist_prepend(SListEntry **list, SListValue data); /** - * Append data to the end of a list. + * Append a value to the end of a list. * * @param list Pointer to the list to append to. - * @param data Data to append. + * @param data The value to append. * @return The new entry in the list, or NULL if it was not possible * to allocate a new entry. */ @@ -177,10 +177,10 @@ SListEntry *slist_append(SListEntry **list, SListValue data); SListEntry *slist_next(SListEntry *listentry); /** - * Retrieve the data at a list entry. + * Retrieve the value stored at a list entry. * * @param listentry Pointer to the list entry. - * @return The data at the list entry. + * @return The value at the list entry. */ SListValue slist_data(SListEntry *listentry); @@ -196,12 +196,12 @@ SListValue slist_data(SListEntry *listentry); SListEntry *slist_nth_entry(SListEntry *list, int n); /** - * Retrieve the data at a specified entry in the list. + * Retrieve the value stored at a specified index in the list. * * @param list The list. - * @param n The index into the list . - * @return The data at the specified index, or @ref SLIST_NULL if - * unsuccessful. + * @param n The index into the list. + * @return The value stored at the specified index, or + * @ref SLIST_NULL if unsuccessful. */ SListValue slist_nth_data(SListEntry *list, int n); @@ -239,16 +239,18 @@ SListValue *slist_to_array(SListEntry *list); int slist_remove_entry(SListEntry **list, SListEntry *entry); /** - * Remove all occurrences of a particular piece of data from a list. + * Remove all occurrences of a particular value from a list. * * @param list Pointer to the list. - * @param callback Callback function to invoke to compare data in the - * list with the data to remove. - * @param data The data to remove from the list. + * @param callback Callback function to invoke to compare values in the + * list with the value to remove. + * @param data The value to remove from the list. * @return The number of entries removed from the list. */ -int slist_remove_data(SListEntry **list, SListEqualFunc callback, SListValue data); +int slist_remove_data(SListEntry **list, + SListEqualFunc callback, + SListValue data); /** * Sort a list. @@ -260,13 +262,14 @@ int slist_remove_data(SListEntry **list, SListEqualFunc callback, SListValue dat void slist_sort(SListEntry **list, SListCompareFunc compare_func); /** - * Find the entry for a particular data item in a list. + * Find the entry for a particular value in a list. * * @param list The list to search. * @param callback Callback function to be invoked to determine if - * values are equal to the data to search for. - * @param data The data to search for. - * @return The list entry of the item being searched for, or + * values in the list are equal to the value to be + * searched for. + * @param data The value to search for. + * @return The list entry of the value being searched for, or * NULL if not found. */ diff --git a/src/trie.h b/src/trie.h index 5fb03ad..2f8432a 100644 --- a/src/trie.h +++ b/src/trie.h @@ -110,7 +110,7 @@ int trie_insert(Trie *trie, char *key, TrieValue value); * @param trie The trie. * @param key The key. * @return The value associated with the key, or - * TRIE_NULL if not found in the trie. + * @ref TRIE_NULL if not found in the trie. */ TrieValue trie_lookup(Trie *trie, char *key); From 563b9c0fbaaaaefc141bc44f855e7d1de72ff86b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 19:27:02 +0000 Subject: [PATCH 066/250] Smart indent headers. --- src/arraylist.h | 2 +- src/binary-heap.h | 4 ++-- src/binomial-heap.h | 2 +- src/list.h | 4 ++-- src/set.h | 4 ++-- src/slist.h | 10 +++++----- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/arraylist.h b/src/arraylist.h index 92aa155..1704aa0 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -107,7 +107,7 @@ typedef int (*ArrayListEqualFunc)(ArrayListValue value1, ArrayListValue value2); */ typedef int (*ArrayListCompareFunc)(ArrayListValue value1, - ArrayListValue value2); + ArrayListValue value2); /** * Allocate a new ArrayList for use. diff --git a/src/binary-heap.h b/src/binary-heap.h index 7c2d008..5ef60cf 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -93,7 +93,7 @@ typedef void *BinaryHeapValue; */ typedef int (*BinaryHeapCompareFunc)(BinaryHeapValue value1, - BinaryHeapValue value2); + BinaryHeapValue value2); /** * A binary heap data structure. @@ -139,7 +139,7 @@ int binary_heap_insert(BinaryHeap *heap, BinaryHeapValue value); * * @param heap The heap. * @return The first value in the heap, or - * @ref BINARY_HEAP_NULL if the heap is empty. + * @ref BINARY_HEAP_NULL if the heap is empty. */ BinaryHeapValue binary_heap_pop(BinaryHeap *heap); diff --git a/src/binomial-heap.h b/src/binomial-heap.h index 94abe48..8cd47da 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -139,7 +139,7 @@ int binomial_heap_insert(BinomialHeap *heap, BinomialHeapValue value); * * @param heap The heap. * @return The first value in the heap, or - * @ref BINOMIAL_HEAP_NULL if the heap is empty. + * @ref BINOMIAL_HEAP_NULL if the heap is empty. */ BinomialHeapValue binomial_heap_pop(BinomialHeap *heap); diff --git a/src/list.h b/src/list.h index 6c95c02..9b18c7f 100644 --- a/src/list.h +++ b/src/list.h @@ -153,7 +153,7 @@ ListEntry *list_prepend(ListEntry **list, ListValue data); * @param list Pointer to the list to append to. * @param value The value to append. * @return The new entry in the list, or NULL if it was not - * possible to allocate the memory for the new entry. + * possible to allocate the memory for the new entry. */ ListEntry *list_append(ListEntry **list, ListValue data); @@ -303,7 +303,7 @@ int list_iter_has_more(ListIterator *iterator); * @return The next value from the list, or @ref LIST_NULL if * there are no more values in the list. */ - + ListValue list_iter_next(ListIterator *iterator); /** diff --git a/src/set.h b/src/set.h index 5ad147e..013afdf 100644 --- a/src/set.h +++ b/src/set.h @@ -210,8 +210,8 @@ int set_num_entries(Set *set); * * @param set The set. * @return An array containing all entries in the set, - * or NULL if it was not possible to allocate - * memory for the array. + * or NULL if it was not possible to allocate + * memory for the array. */ SetValue *set_to_array(Set *set); diff --git a/src/slist.h b/src/slist.h index 2f923b0..bde7f7f 100644 --- a/src/slist.h +++ b/src/slist.h @@ -201,7 +201,7 @@ SListEntry *slist_nth_entry(SListEntry *list, int n); * @param list The list. * @param n The index into the list. * @return The value stored at the specified index, or - * @ref SLIST_NULL if unsuccessful. + * @ref SLIST_NULL if unsuccessful. */ SListValue slist_nth_data(SListEntry *list, int n); @@ -249,8 +249,8 @@ int slist_remove_entry(SListEntry **list, SListEntry *entry); */ int slist_remove_data(SListEntry **list, - SListEqualFunc callback, - SListValue data); + SListEqualFunc callback, + SListValue data); /** * Sort a list. @@ -267,7 +267,7 @@ void slist_sort(SListEntry **list, SListCompareFunc compare_func); * @param list The list to search. * @param callback Callback function to be invoked to determine if * values in the list are equal to the value to be - * searched for. + * searched for. * @param data The value to search for. * @return The list entry of the value being searched for, or * NULL if not found. @@ -305,7 +305,7 @@ int slist_iter_has_more(SListIterator *iterator); * @return The next value from the list, or SLIST_NULL if * there are no more values in the list. */ - + SListValue slist_iter_next(SListIterator *iterator); /** From 0a8ff8e0e83de9ab42efd352c5204f030f945a17 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 19:27:48 +0000 Subject: [PATCH 067/250] Fix smart-indent to expand tabs to the next tab point rather than doing a simple replace. --- tools/smart-indent | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/smart-indent b/tools/smart-indent index 3e6079b..ca99537 100755 --- a/tools/smart-indent +++ b/tools/smart-indent @@ -29,7 +29,12 @@ def fix_file(filename) # expand tabs - s = s.gsub(/\t/, " " * TAB_SIZE) + while s =~ /\t/ + lead_text = $` + lead_len = lead_text.length + replace_len = TAB_SIZE - (lead_len % TAB_SIZE) + s[0, lead_len + 1] = lead_text + " " * replace_len + end # replace leading spaces with the appropriate combination # of tabs and spaces From e729935aa94f44829f58e7fd6a03444b02a3f3a4 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 1 Jun 2008 19:31:06 +0000 Subject: [PATCH 068/250] Update ChangeLog, bump to v1.1.0. --- ChangeLog | 482 +++++++++++++++++++++++++++++++++++++++++---------- NEWS | 19 ++ configure.ac | 2 +- 3 files changed, 407 insertions(+), 96 deletions(-) diff --git a/ChangeLog b/ChangeLog index 03484b0..af7dc81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,364 +1,656 @@ -Fri Dec 23 23:19:01 2005 fraggle +2008-06-01 20:27:48 fraggle + + Fix smart-indent to expand tabs to the next tab point rather than + doing a simple replace. + +2008-06-01 20:27:02 fraggle + + Smart indent headers. + +2008-06-01 20:08:47 fraggle + + Documentation fixes: "data"->"value". + +2008-06-01 19:39:28 fraggle + + Fix documentation error. + +2008-06-01 19:36:05 fraggle + + Documentation fixes. + +2008-06-01 19:16:21 fraggle + + Initialise new trie nodes with TRIE_NULL. + +2008-06-01 19:15:49 fraggle + + Use 8 space tabs, replace cvshistory with svnhistory. + +2008-06-01 19:14:30 fraggle + + Remove coverage testing CFLAGS. + +2008-06-01 17:49:12 fraggle + + Add tests for some uncovered code. + +2008-06-01 16:41:54 fraggle + + Use string keys for test cases to ensure hash collisions occur and are + tested. + +2008-06-01 15:41:25 fraggle + + Indentation fixes. + +2008-05-30 21:26:07 fraggle + + Fix tabs/spaces. + +2008-05-30 21:23:33 fraggle + + Make list iterators cope with the current element being removed + independent of the iterator remove function. Add test cases for this. + +2008-05-30 01:51:18 fraggle + + Simplify linked list iterators and reduce iterator structure size. + +2008-04-16 21:41:46 fraggle + + Make the doubly-linked list type take a pointer to a structure to + initialise rather than allocating an iterator. + +2008-04-16 21:25:12 fraggle + + Make the singly-linked list type take a pointer to a structure to + initialise rather than allocating an iterator. + +2008-04-16 21:08:05 fraggle + + Make the set type take a pointer to a structure to initialise rather + than allocating an iterator. + +2008-04-16 20:57:09 fraggle + + Don't allocate hash table iterators; take a pointer to a structure to + initialise. + +2007-10-02 01:13:07 fraggle + + Return the value from the hash table iterator, not the key. + +2007-09-09 22:02:42 fraggle + + Add missing copyright notice. + +2007-06-10 04:22:20 fraggle + + Rename hashtable.[ch] -> hash-table.[ch] for consistency. Rename all + instances of hashtable to hash_table. + +2007-06-10 03:57:45 fraggle + + Test hash_table_register_free_functions. + +2007-06-10 03:56:57 fraggle + + Test set_register_free_function. + +2007-06-10 03:55:59 fraggle + + Test bloom_filter_free. + +2007-06-10 03:17:05 fraggle + + Rename avltree_* -> avl_tree_*, avltree.[ch] -> avl-tree.[ch] for + consistency with other files. + +2007-06-10 03:07:20 fraggle + + Set svn:ignore property on all directories. + +2006-11-22 00:41:28 fraggle + + Set reference count when allocating new trees. + +2006-11-22 00:31:34 fraggle + + Add new headers to libcalg.h. + +2006-11-22 00:15:27 fraggle + + Fix bug in set_to_array. + +2006-11-22 00:06:44 fraggle + + Separate out set value type to a separate type. + +2006-11-22 00:04:55 fraggle + + Abstract key/values into separate types, so that these can be changed + from "void *" if desired. + +2006-11-20 17:58:58 fraggle + + Test formatting cleanups. + +2006-11-20 17:55:53 fraggle + + Add binomial heap. + +2006-11-20 17:54:29 fraggle + + Fix bloom filter. + +2006-11-20 17:54:07 fraggle + + Add bloom filter test case. + +2006-11-15 23:35:18 fraggle + + Add bloom filter to front page in documentation. Fix documentation + warnings. + +2006-11-15 23:34:14 fraggle + + Rename bloom_filter_lookup to bloom_filter_query to be consistent with + the set data structure. + +2006-11-15 19:56:21 fraggle + + Add bloom filter union/intersection functions. + +2006-11-15 19:43:25 fraggle + + Add bloom filter read/load functions. + +2006-11-15 19:32:53 fraggle + + Make salts unsigned. + +2006-11-15 19:32:01 fraggle + + Add bloom filter. + +2006-10-30 20:15:18 fraggle + + Fix indentation. + +2006-10-30 20:13:10 fraggle + + Improved trie test cases. + +2006-10-30 20:12:29 fraggle + + Indentation fixes. + +2006-10-30 20:11:34 fraggle + + Trie fixes: recover properly from failed mallocs. Fix insert that + replaces an existing value. + +2006-10-30 20:09:29 fraggle + + Fix allocation size on reallocs. + +2006-10-28 13:21:26 fraggle + + Fix up indentation. + +2006-10-28 13:18:05 fraggle + + Reword comments. + +2006-10-28 13:17:45 fraggle + + Improve list iterate test case. + +2006-10-28 13:10:43 fraggle + + Convert slist_foreach to iterators. + +2006-10-27 20:57:06 fraggle + + Smart indent all source code. + +2006-10-27 20:50:36 fraggle + + Check the return value from malloc() and return error conditions if it + fails. + +2006-10-27 19:34:18 fraggle + + Replace list_foreach with iterator objects. + +2006-10-27 18:23:14 fraggle + + Improve the set_remove test function. + +2006-10-27 18:16:26 fraggle + + Fix lockup when removing entries from sets. + +2006-10-26 19:39:38 fraggle + + Use "good hash table primes" from + http://planetmath.org/encyclopedia/GoodHashTablePrimes.html + +2006-10-22 02:49:08 fraggle + + Add test suite for binary heap. + +2006-10-22 02:45:15 fraggle + + Fix errors: (i - 1) / 2 to get parent index, do not use child 2 when + it does not exist. + +2006-10-22 01:04:59 fraggle + + Add binary_heap_free. + +2006-10-21 23:27:40 fraggle + + Use calloc/malloc more appropriately (don't clear memory + unnecessarily), don't use memset where it isn't needed. + +2006-10-21 00:34:08 fraggle + + Add a binary heap implementation. + +2006-06-19 18:50:38 fraggle + + Remove the double-pointer usage (breaks remove while iterating). + +2006-06-19 18:32:33 fraggle + + Add test cases for set iterator functions. + +2006-06-19 18:22:21 fraggle + + Convert spaces to tabs. + +2006-06-19 18:18:14 fraggle + + Rename functions with _iterator_ to _iter_ for shorter names. + +2006-06-19 18:11:03 fraggle + + Convert hash table structure to use iterator objects instead of + foreach with callback functions. + +2006-06-17 20:23:11 fraggle + + Change set iteration to use iterator objects rather than foreach with + callback functions. + +2006-01-30 18:52:43 fraggle + + v1.0.0 + +2005-12-23 23:19:02 fraggle Make compare/hash functions take void pointers, removing the need to cast the functions to the appropriate type when used. -Fri Dec 23 22:39:38 2005 fraggle +2005-12-23 22:39:39 fraggle Fix bug in list iterator, add test cases for iterator -Fri Dec 23 19:08:17 2005 fraggle +2005-12-23 19:08:17 fraggle Do not include complete path in Doxygen documentation -Fri Dec 23 19:07:57 2005 fraggle +2005-12-23 19:07:57 fraggle Add AVL tree to main documentation list; split data structures into categories -Fri Dec 23 18:57:38 2005 fraggle +2005-12-23 18:57:38 fraggle List to array conversion functions -Fri Dec 23 18:44:15 2005 fraggle +2005-12-23 18:44:15 fraggle to_array conversion function. -Fri Dec 23 18:25:36 2005 fraggle +2005-12-23 18:25:36 fraggle Turn on warnings; remove unneeded variables. Add more test cases. -Fri Dec 23 18:24:43 2005 fraggle +2005-12-23 18:24:43 fraggle avltree_remove, avltree_free functions. -Fri Dec 23 16:07:37 2005 fraggle +2005-12-23 16:07:38 fraggle AVL tree: Remove debugging functions, fix bug with parent references not updated on rotate. Add "remove" function and test cases. -Fri Dec 23 02:11:27 2005 fraggle +2005-12-23 02:11:27 fraggle More AVL tree documentation. -Fri Dec 23 01:51:34 2005 fraggle +2005-12-23 01:51:34 fraggle Update NEWS, ChangeLog -Fri Dec 23 01:49:54 2005 fraggle +2005-12-23 01:49:54 fraggle CVS history script -Wed Dec 21 21:39:17 2005 fraggle +2005-12-21 21:39:17 fraggle Add missing function declarations and some documentation. -Tue Dec 20 23:21:36 2005 fraggle +2005-12-20 23:21:36 fraggle Style cleanups: always use {} blocks for if statements. -Tue Dec 20 23:20:23 2005 fraggle +2005-12-20 23:20:23 fraggle Main header -Sat Dec 17 13:45:52 2005 fraggle +2005-12-17 13:45:52 fraggle Add trie -Tue Dec 13 22:02:22 2005 fraggle +2005-12-13 22:02:22 fraggle Smart indent all source code -Tue Dec 13 21:54:51 2005 fraggle +2005-12-13 21:54:51 fraggle Maintenance scripts -Tue Dec 13 20:16:30 2005 fraggle +2005-12-13 20:16:30 fraggle hash_table_foreach_remove function -Tue Dec 13 19:57:56 2005 fraggle +2005-12-13 19:57:56 fraggle Use unsigned int for prime arrays -Tue Dec 13 19:54:03 2005 fraggle +2005-12-13 19:54:03 fraggle - Hash table iterator function; add missing num_entries function to header. + Hash table iterator function; add missing num_entries function to + header. -Tue Dec 13 19:29:57 2005 fraggle +2005-12-13 19:29:57 fraggle Install header files, pkgconfig .pc file -Tue Dec 13 19:28:19 2005 fraggle +2005-12-13 19:28:19 fraggle Sort function -Tue Dec 13 19:27:15 2005 fraggle +2005-12-13 19:27:15 fraggle SLIST -> LIST (prevent conflict with the real slist.h) -Sun Dec 11 01:58:51 2005 fraggle +2005-12-11 01:58:51 fraggle Act as a mapping. Add a lookup function and accessor functions for the nodes. -Sat Dec 10 23:44:26 2005 fraggle +2005-12-10 23:44:26 fraggle Set to array convertor function -Sat Dec 10 23:17:40 2005 fraggle +2005-12-10 23:17:40 fraggle Trie documentation -Sat Dec 10 22:43:02 2005 fraggle +2005-12-10 22:43:02 fraggle Trie testcase -Sat Dec 10 22:42:18 2005 fraggle +2005-12-10 22:42:18 fraggle Add remove, free functions, entries count -Sat Dec 10 21:47:39 2005 fraggle +2005-12-10 21:47:39 fraggle terminology: "duplicate" -> "copy" -Thu Dec 1 17:47:42 2005 fraggle +2005-12-01 17:47:42 fraggle Fix error in documentation -Thu Dec 1 17:46:24 2005 fraggle +2005-12-01 17:46:25 fraggle Move Doxyfile to the doc/ directory, only generate HTML documentation. Include docs in dist. -Wed Nov 30 00:58:02 2005 fraggle +2005-11-30 00:58:02 fraggle First implementation of a trie -Tue Nov 29 23:30:51 2005 fraggle +2005-11-29 23:30:51 fraggle Algorithms -> data structures -Tue Nov 29 23:25:59 2005 fraggle +2005-11-29 23:25:59 fraggle - When overwriting an existing value in a hashtable, use the new key - and not the old one. + When overwriting an existing value in a hashtable, use the new key and + not the old one. -Tue Nov 29 23:24:01 2005 fraggle +2005-11-29 23:24:01 fraggle Return results for set_remove and set_insert. Add free function registration to free values. -Tue Nov 29 23:03:06 2005 fraggle +2005-11-29 23:03:07 fraggle Test cases for hash functions -Tue Nov 29 22:49:17 2005 fraggle +2005-11-29 22:49:17 fraggle Add test cases for case insensitive string compare functions -Tue Nov 29 22:47:07 2005 fraggle +2005-11-29 22:47:07 fraggle Fix case insensitive string compare -Tue Nov 29 00:00:12 2005 fraggle +2005-11-29 00:00:12 fraggle Key/value free functions -Mon Nov 28 18:25:45 2005 fraggle +2005-11-28 18:25:45 fraggle Case insensitive string hash and comparison functions -Mon Nov 28 18:23:43 2005 fraggle +2005-11-28 18:23:43 fraggle Duplicator functions for union and intersection calls to copy values. -Mon Nov 28 18:20:59 2005 fraggle +2005-11-28 18:20:59 fraggle Hashtable -> HashTable, hashtable_ -> hash_table_ - consistent naming scheme and consistent with glib -Sat Nov 26 23:27:57 2005 fraggle +2005-11-26 23:27:57 fraggle First implementation of an AVL Tree -Sat Nov 26 20:13:18 2005 fraggle +2005-11-26 20:13:18 fraggle Exit with an error code of 0 if completed successfully -Sat Nov 26 19:04:40 2005 fraggle +2005-11-26 19:04:40 fraggle Set unit tests -Sat Nov 26 19:03:18 2005 fraggle +2005-11-26 19:03:18 fraggle Add union and intersection functions, fix bug in set_query -Sat Nov 26 18:20:16 2005 fraggle +2005-11-26 18:20:16 fraggle Rename set functions to be consistent with hashtable function names -Sat Nov 26 18:11:26 2005 fraggle +2005-11-26 18:11:26 fraggle Hash table test suite -Sat Nov 26 18:11:01 2005 fraggle +2005-11-26 18:11:01 fraggle - Keep track of the number of entries in a hash table correctly. - Add num_entries function to retrieve the number of entries. + Keep track of the number of entries in a hash table correctly. Add + num_entries function to retrieve the number of entries. -Sat Nov 26 17:46:54 2005 fraggle +2005-11-26 17:46:54 fraggle Test cases for the compare functions -Sat Nov 26 16:59:07 2005 fraggle +2005-11-26 16:59:07 fraggle Include the doc directory in distributions -Sat Nov 26 16:13:08 2005 fraggle +2005-11-26 16:13:08 fraggle Improve documentation, add an introduction page -Sat Nov 26 15:21:53 2005 fraggle +2005-11-26 15:21:53 fraggle Always show all warnings -Sat Nov 26 15:21:40 2005 fraggle +2005-11-26 15:21:40 fraggle Generate a configuration file so that the compiler command line is not so cluttered. -Sat Nov 26 15:18:40 2005 fraggle +2005-11-26 15:18:40 fraggle Include the autotools directory in distribution -Sat Nov 26 15:14:53 2005 fraggle +2005-11-26 15:14:53 fraggle Use comparison functions from the library instead of duplicating declarations -Sat Nov 26 15:12:31 2005 fraggle +2005-11-26 15:12:32 fraggle Add build system -Sat Nov 26 15:11:30 2005 fraggle +2005-11-26 15:11:30 fraggle AUTHORS file -Sat Nov 26 14:42:55 2005 fraggle +2005-11-26 14:42:55 fraggle Include manpage links for function names -Sat Nov 26 14:38:07 2005 fraggle +2005-11-26 14:38:07 fraggle Documentation improvements -Sat Nov 26 14:27:30 2005 fraggle +2005-11-26 14:27:30 fraggle Use prime numbered table sizes -Sat Nov 26 13:34:42 2005 fraggle +2005-11-26 13:34:42 fraggle Restructure directories -Mon Nov 21 16:09:37 2005 fraggle +2005-11-21 16:09:37 fraggle Implementation of a set -Mon Nov 21 16:09:16 2005 fraggle +2005-11-21 16:09:16 fraggle Function to retrieve a count of the number of entries -Sun Nov 20 12:11:59 2005 fraggle +2005-11-20 12:11:59 fraggle A set of values -Sun Nov 20 02:47:04 2005 fraggle +2005-11-20 02:47:04 fraggle Wording fix -Sun Nov 20 02:43:46 2005 fraggle +2005-11-20 02:43:46 fraggle Generate brief descriptions automatically -Sun Nov 20 02:43:33 2005 fraggle +2005-11-20 02:43:33 fraggle Documentation wording fixes -Sun Nov 20 02:40:07 2005 fraggle +2005-11-20 02:40:07 fraggle - Do not display directories. Remove my local build dirs from the file and - use relative paths. + Do not display directories. Remove my local build dirs from the file + and use relative paths. -Sun Nov 20 02:27:22 2005 fraggle +2005-11-20 02:27:22 fraggle Documentation improvements; generate documentation through Doxygen -Sun Nov 20 01:21:34 2005 fraggle +2005-11-20 01:21:34 fraggle Hash table implementation -Sat Nov 19 19:29:00 2005 fraggle +2005-11-19 19:29:00 fraggle rm -f -Sat Nov 19 19:28:24 2005 fraggle +2005-11-19 19:28:24 fraggle Shut up compiler warnings -Sat Nov 19 19:25:01 2005 fraggle +2005-11-19 19:25:01 fraggle Turn on warnings on all makefiles -Sat Nov 19 19:24:10 2005 fraggle +2005-11-19 19:24:10 fraggle Use callback to determine data to remove with slist_remove_data -Sat Nov 19 19:14:32 2005 fraggle +2005-11-19 19:14:32 fraggle Split hash functions into a separate hash-functions directory -Sat Nov 19 19:07:52 2005 fraggle +2005-11-19 19:07:52 fraggle Doubly-linked list implementation -Sat Nov 19 13:21:42 2005 fraggle +2005-11-19 13:21:42 fraggle Add README -Sat Nov 19 13:18:34 2005 fraggle +2005-11-19 13:18:34 fraggle Add new test functions -Sat Nov 19 13:18:23 2005 fraggle +2005-11-19 13:18:23 fraggle Use callback functions when searching -Sat Nov 19 13:10:54 2005 fraggle +2005-11-19 13:10:54 fraggle Add a search function -Sat Nov 19 12:47:34 2005 fraggle +2005-11-19 12:47:34 fraggle Queue test cases -Sat Nov 19 12:36:25 2005 fraggle +2005-11-19 12:36:25 fraggle queue_empty -> queue_is_empty -Sat Nov 19 12:28:34 2005 fraggle +2005-11-19 12:28:35 fraggle Rename files, add headers and documentation -Fri Nov 18 16:41:20 2005 fraggle +2005-11-18 16:41:20 fraggle Update license to match source files -Fri Nov 18 16:40:27 2005 fraggle +2005-11-18 16:40:27 fraggle Compare functions for different types -Fri Nov 18 16:37:23 2005 fraggle +2005-11-18 16:37:23 fraggle Initial revision diff --git a/NEWS b/NEWS index 49291c2..e129db2 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,23 @@ +v1.1.0 (1st June 2008) + + * Added data structures: + - Binary Heap + - Binomial Heap + - Bloom Filter + * Iterator functions changed to a model based around an iterator structure + rather than callback functions. + * Void pointers used for keys/values replaced by typedefs to void pointers. + This allows the type to be changed to something else if desired. + * Hash table sizes changed to use a set of recommended prime numbers + that are mathematically good for use in hash tables: + http://planetmath.org/encyclopedia/GoodHashTablePrimes.html + * Tests added for some code that was not covered by the test suite. + * Failed malloc() calls are now checked for. + * Bugs fixed: + - Lockup with set_remove function. + - set_to_array did not include all values. + v1.0.0 (30th January 2006) First release. diff --git a/configure.ac b/configure.ac index 89e5d90..3a7a949 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(C Algorithms, 1.0.0, fraggle@users.sourceforge.net, c-algorithms) +AC_INIT(C Algorithms, 1.1.0, fraggle@users.sourceforge.net, c-algorithms) AC_CONFIG_AUX_DIR(autotools) AM_INIT_AUTOMAKE($PACKAGE_TARNAME, $PACKAGE_VERSION, no-define) From d74fafaf82f38ab45310fb0b14c5becd5a0b3a46 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 2 Jun 2008 19:45:14 +0000 Subject: [PATCH 069/250] Fix memory leak in hash table. --- src/hash-table.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hash-table.c b/src/hash-table.c index c29fa86..229147f 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -241,6 +241,10 @@ static int hash_table_enlarge(HashTable *hash_table) rover = next; } } + + /* Free the old table */ + + free(old_table); return 1; } From e3dad2374e9fea85bea0552efecd62df2521d266 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 2 Jun 2008 20:04:01 +0000 Subject: [PATCH 070/250] Fix memory leaks in unit tests. --- test/test-arraylist.c | 52 ++++++++++++---- test/test-avl-tree.c | 27 +++++---- test/test-binary-heap.c | 19 +++--- test/test-binomial-heap.c | 18 +++--- test/test-bloom-filter.c | 18 +++++- test/test-hash-table.c | 30 +++++---- test/test-list.c | 27 +++++++++ test/test-queue.c | 42 ++++++++----- test/test-set.c | 35 ++++++++--- test/test-slist.c | 27 +++++++++ test/test-trie.c | 124 +++++++++++++++++++++++++++----------- 11 files changed, 302 insertions(+), 117 deletions(-) diff --git a/test/test-arraylist.c b/test/test-arraylist.c index 8f264eb..9bf0b1d 100644 --- a/test/test-arraylist.c +++ b/test/test-arraylist.c @@ -61,21 +61,29 @@ ArrayList *generate_arraylist(void) return arraylist; } -void test_arraylist_new(void) -{ - arraylist_new(0); - arraylist_new(-1); - arraylist_new(10); -} - -void test_arraylist_free(void) +void test_arraylist_new_free(void) { ArrayList *arraylist; - + + /* Use a default size when given zero */ + arraylist = arraylist_new(0); + assert(arraylist != NULL); + arraylist_free(arraylist); + + /* Negative size also gives default */ + + arraylist = arraylist_new(-1); + assert(arraylist != NULL); arraylist_free(arraylist); - /* Test freeing a NULL ArrayList */ + /* Normal allocated */ + + arraylist = arraylist_new(10); + assert(arraylist != NULL); + arraylist_free(arraylist); + + /* Freeing a null arraylist works */ arraylist_free(NULL); } @@ -113,6 +121,8 @@ void test_arraylist_append(void) for (i=0; i<10000; ++i) { arraylist_append(arraylist, NULL); } + + arraylist_free(arraylist); } @@ -149,6 +159,8 @@ void test_arraylist_prepend(void) for (i=0; i<10000; ++i) { arraylist_prepend(arraylist, NULL); } + + arraylist_free(arraylist); } void test_arraylist_insert(void) @@ -213,6 +225,8 @@ void test_arraylist_insert(void) for (i=0; i<10000; ++i) { arraylist_insert(arraylist, 10, &variable1); } + + arraylist_free(arraylist); } void test_arraylist_remove_range(void) @@ -243,6 +257,8 @@ void test_arraylist_remove_range(void) arraylist_remove_range(arraylist, 0, -1); assert(arraylist->length == 13); + + arraylist_free(arraylist); } void test_arraylist_remove(void) @@ -271,6 +287,8 @@ void test_arraylist_remove(void) arraylist_remove(arraylist, 15); assert(arraylist->length == 15); + + arraylist_free(arraylist); } void test_arraylist_index_of(void) @@ -308,6 +326,8 @@ void test_arraylist_index_of(void) assert(arraylist_index_of(arraylist, int_equal, &val) < 0); val = 57; assert(arraylist_index_of(arraylist, int_equal, &val) < 0); + + arraylist_free(arraylist); } void test_arraylist_clear(void) @@ -331,6 +351,8 @@ void test_arraylist_clear(void) arraylist_clear(arraylist); assert(arraylist->length == 0); + + arraylist_free(arraylist); } void test_arraylist_sort(void) @@ -362,6 +384,8 @@ void test_arraylist_sort(void) assert(*value == sorted[i]); } + arraylist_free(arraylist); + /* Check sorting an empty list */ arraylist = arraylist_new(5); @@ -370,6 +394,8 @@ void test_arraylist_sort(void) assert(arraylist->length == 0); + arraylist_free(arraylist); + /* Check sorting a list with 1 entry */ arraylist = arraylist_new(5); @@ -379,13 +405,13 @@ void test_arraylist_sort(void) assert(arraylist->length == 1); assert(arraylist->data[0] == &entries[0]); -} + arraylist_free(arraylist); +} int main(int argc, char *argv[]) { - test_arraylist_new(); - test_arraylist_free(); + test_arraylist_new_free(); test_arraylist_append(); test_arraylist_prepend(); test_arraylist_insert(); diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index 096f809..fc7b13b 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -40,6 +40,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "avl-tree.h" #include "compare-int.h" +int test_array[1000]; + int find_subtree_height(AVLTreeNode *node) { int left_height, right_height; @@ -136,6 +138,8 @@ void test_avl_tree_new(void) assert(tree != NULL); assert(avl_tree_root_node(tree) == NULL); assert(avl_tree_num_entries(tree) == 0); + + avl_tree_free(tree); } void test_avl_tree_insert_lookup(void) @@ -143,7 +147,6 @@ void test_avl_tree_insert_lookup(void) AVLTree *tree; AVLTreeNode *node; int i; - int *key; /* Create a tree containing some values. Validate the * tree is consistent at all stages. */ @@ -151,10 +154,8 @@ void test_avl_tree_insert_lookup(void) tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<1000; ++i) { - key = (int *) malloc(sizeof(int)); - *key = i; - - avl_tree_insert(tree, key, NULL); + test_array[i] = i; + avl_tree_insert(tree, &test_array[i], NULL); assert(avl_tree_num_entries(tree) == i+1); validate_tree(tree); @@ -175,12 +176,13 @@ void test_avl_tree_insert_lookup(void) assert(avl_tree_lookup_node(tree, &i) == NULL); i = 100000; assert(avl_tree_lookup_node(tree, &i) == NULL); + + avl_tree_free(tree); } AVLTree *create_tree(void) { AVLTree *tree; - int *key; int i; /* Create a tree and fill with nodes */ @@ -188,10 +190,8 @@ AVLTree *create_tree(void) tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<1000; ++i) { - key = (int *) malloc(sizeof(int)); - *key = i; - - avl_tree_insert(tree, key, NULL); + test_array[i] = i; + avl_tree_insert(tree, &test_array[i], NULL); } return tree; @@ -241,7 +241,8 @@ void test_avl_tree_remove(void) /* All entries removed, should be empty now */ assert(avl_tree_root_node(tree) == NULL); - + + avl_tree_free(tree); } void test_avl_tree_to_array(void) @@ -270,6 +271,10 @@ void test_avl_tree_to_array(void) for (i=0; i Date: Tue, 3 Jun 2008 19:47:03 +0000 Subject: [PATCH 071/250] Add configure for compiling with profiling (gcov) and valgrind. --- configure.ac | 32 ++++++++++++++++++++++++++++++++ src/Makefile.am | 4 ++++ test/Makefile.am | 13 +++++++------ test/valgrind-wrapper | 23 +++++++++++++++++++++++ 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100755 test/valgrind-wrapper diff --git a/configure.ac b/configure.ac index 3a7a949..ec9b25b 100644 --- a/configure.ac +++ b/configure.ac @@ -8,6 +8,38 @@ AC_PROG_LIBTOOL AC_PROG_INSTALL AC_PROG_MAKE_SET +# Support for coverage analysis via gcov: + +coverage=no +AC_ARG_ENABLE(coverage, +[ --enable-coverage Enable coverage testing. ], +[ coverage=yes ]) + +if [[ "$coverage" = "yes" ]]; then + if [[ "$GCC" = "yes" ]]; then + CFLAGS="-fprofile-arcs -ftest-coverage $CFLAGS" + else + AC_MSG_ERROR([Can only enable coverage when using gcc.]) + fi +fi + +# Support for running test cases using valgrind: + +use_valgrind=false +AC_ARG_ENABLE(valgrind, +[ --enable-valgrind Use valgrind when running unit tests. ], +[ use_valgrind=true ]) + +if [[ "$use_valgrind" = "true" ]]; then + AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no) + + if [[ "$HAVE_VALGRIND" = "no" ]]; then + AC_MSG_ERROR([Valgrind not found in PATH. ]) + fi +fi + +AM_CONDITIONAL(USE_VALGRIND, $use_valgrind) + AM_CONFIG_HEADER(config.h:config.h.in) AC_SUBST(ac_aux_dir) diff --git a/src/Makefile.am b/src/Makefile.am index d5f23c7..e0fc7f0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,7 @@ AM_CFLAGS = -Wall +check_LIBRARIES=libcalgtest.a lib_LTLIBRARIES=libcalg.la MAIN_HEADERFILES = libcalg.h @@ -17,6 +18,9 @@ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c +libcalgtest_a_CFLAGS=-DCALG_TEST +libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) + libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) headerfilesdir=$(includedir)/libcalg-1.0 diff --git a/test/Makefile.am b/test/Makefile.am index ae833a1..6138ac4 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,4 +1,8 @@ +if USE_VALGRIND +TESTS_ENVIRONMENT=./valgrind-wrapper +endif + TESTS = \ test-arraylist \ test-avl-tree \ @@ -14,13 +18,10 @@ TESTS = \ test-set \ test-trie -noinst_PROGRAMS = $(TESTS) +check_PROGRAMS = $(TESTS) AM_CFLAGS = -I../src -Wall -LDADD = $(top_builddir)/src/libcalg.la +LDADD = $(top_builddir)/src/libcalgtest.a -test_arraylist_SOURCES = test-arraylist.c -test_list_SOURCES = test-list.c -test_slist_SOURCES = test-slist.c -test_queue_SOURCES = test-queue.c +EXTRA_DIST=valgrind-wrapper diff --git a/test/valgrind-wrapper b/test/valgrind-wrapper new file mode 100755 index 0000000..745f107 --- /dev/null +++ b/test/valgrind-wrapper @@ -0,0 +1,23 @@ +#!/bin/sh + +# Run in valgrind, with leak checking enabled + +valgrind -q --leak-check=full "$@" 2> .valgrind-log + +# Save the test result + +result="$?" + +# Valgrind should generate no error messages + +log_contents="`cat .valgrind-log`" + +if [ "$log_contents" != "" ]; then + cat .valgrind-log >&2 + result=1 +fi + +rm -f .valgrind-log + +exit $result + From ce7435d60428765595ccfad01ceaa43d1969427d Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 11 Jun 2008 22:09:22 +0000 Subject: [PATCH 072/250] Prepend x to work with empty strings on old shell interpreters. --- test/valgrind-wrapper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/valgrind-wrapper b/test/valgrind-wrapper index 745f107..030a77c 100755 --- a/test/valgrind-wrapper +++ b/test/valgrind-wrapper @@ -12,7 +12,7 @@ result="$?" log_contents="`cat .valgrind-log`" -if [ "$log_contents" != "" ]; then +if [ "x$log_contents" != "x" ]; then cat .valgrind-log >&2 result=1 fi From d362da2bc00734b26f28a40bc289024beaf73e07 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 11 Jun 2008 22:18:35 +0000 Subject: [PATCH 073/250] Add initial test framework for testing memory allocation/free. --- src/Makefile.am | 7 +- src/alloc-testing.c | 271 ++++++++++++++++++++++++++++++++++ src/alloc-testing.h | 120 +++++++++++++++ src/arraylist.c | 6 + src/avl-tree.c | 6 + src/binary-heap.c | 6 + src/binomial-heap.c | 6 + src/bloom-filter.c | 6 + src/hash-table.c | 6 + src/list.c | 6 + src/queue.c | 6 + src/set.c | 6 + src/slist.c | 6 + src/trie.c | 6 + test/test-arraylist.c | 2 + test/test-avl-tree.c | 2 + test/test-binary-heap.c | 2 + test/test-binomial-heap.c | 2 + test/test-bloom-filter.c | 2 + test/test-compare-functions.c | 2 + test/test-hash-functions.c | 2 + test/test-hash-table.c | 2 + test/test-list.c | 2 + test/test-queue.c | 2 + test/test-set.c | 2 + test/test-slist.c | 2 + test/test-trie.c | 2 + 27 files changed, 488 insertions(+), 2 deletions(-) create mode 100644 src/alloc-testing.c create mode 100644 src/alloc-testing.h diff --git a/src/Makefile.am b/src/Makefile.am index e0fc7f0..dd79e7e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,14 +12,17 @@ avl-tree.h compare-pointer.h hash-pointer.h list.h slist.h \ queue.h compare-string.h hash-string.h trie.h binary-heap.h \ bloom-filter.h binomial-heap.h +ALLOC_TESTING_FILES=\ +alloc-testing.c alloc-testing.h + SRC=\ arraylist.c compare-pointer.c hash-pointer.c list.c slist.c \ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c -libcalgtest_a_CFLAGS=-DCALG_TEST -libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) +libcalgtest_a_CFLAGS=-DALLOC_TESTING +libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(ALLOC_TESTING_FILES) libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) diff --git a/src/alloc-testing.c b/src/alloc-testing.c new file mode 100644 index 0000000..3189083 --- /dev/null +++ b/src/alloc-testing.c @@ -0,0 +1,271 @@ + +/* + +Copyright (c) 2005, Simon Howard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include +#include + +#include + +#define ALLOC_TESTING_C + +#include "alloc-testing.h" + +/* All allocated blocks are given this magic number */ + +#define ALLOC_TEST_MAGIC 0x72ec82d2 + +/* This value is written to memory after it is freshly allocated, to ensure + * that code under test does not rely on memory being initialised by + * malloc(). */ + +#define MALLOC_PATTERN 0xBAADF00D + +/* This value is written to memory after it is freed, to ensure that code + * does not rely on memory that has been freed. */ + +#define FREE_PATTERN 0xDEADBEEF + +/** + * All blocks allocated by the testing framework are preceded by a structure + * of this type. + */ + +typedef struct _BlockHeader BlockHeader; + +struct _BlockHeader { + unsigned int magic_number; + size_t bytes; + BlockHeader *prev, *next; +}; + +/* Head of a linked list of allocated blocks */ + +static BlockHeader *allocated_blocks = NULL; + +/* Count of the current number of allocated bytes */ + +static size_t allocated_bytes = 0; + +/* Get the block header for an allocated pointer */ + +static BlockHeader *alloc_test_get_header(void *ptr) +{ + BlockHeader *result; + + /* Go back from the start of the memory block to get the header. */ + + result = ((BlockHeader *) ptr) - 1; + + assert(result->magic_number == ALLOC_TEST_MAGIC); + + return result; +} + +/* Overwrite a block of memory with a repeated pattern. */ + +void alloc_test_overwrite(void *ptr, size_t length, unsigned int pattern) +{ + unsigned char *byte_ptr; + unsigned int pattern_seq; + unsigned char pattern_byte; + size_t i; + + byte_ptr = ptr; + + for (i=0; i> (8 * pattern_seq)) & 0xff; + byte_ptr[i] = pattern_byte; + } +} + +void *alloc_test_malloc(size_t bytes) +{ + BlockHeader *header; + void *result; + + /* Allocate the requested block with enough room for the block header + * as well. */ + + header = (malloc)(sizeof(BlockHeader) + bytes); + + if (header == NULL) { + return NULL; + } + + header->magic_number = ALLOC_TEST_MAGIC; + header->bytes = bytes; + + /* Hook the new block into the linked list. */ + + header->prev = NULL; + header->next = allocated_blocks; + allocated_blocks = header; + + if (header->next != NULL) { + header->next->prev = header; + } + + /* Update counter */ + + allocated_bytes += bytes; + result = header + 1; + + /* Fill memory with MALLOC_PATTERN, to ensure that code under test + * does not rely on memory being initialised to zero. */ + + alloc_test_overwrite(result, bytes, MALLOC_PATTERN); + + /* Skip past the header and return the block itself */ + + return result; +} + +void alloc_test_free(void *ptr) +{ + BlockHeader *header; + + /* Must accept NULL as a valid pointer to free. */ + + if (ptr == NULL) { + return; + } + + header = alloc_test_get_header(ptr); + + /* Unlink from the linked list. */ + + if (header->prev != NULL) { + header->prev->next = header->next; + } else { + allocated_blocks = header->next; + } + + if (header->next != NULL) { + header->next->prev = header->prev; + } + + /* Update counter */ + + assert(allocated_bytes >= header->bytes); + allocated_bytes -= header->bytes; + + /* Trash the allocated block to foil any code that relies on memory + * that has been freed. */ + + alloc_test_overwrite(ptr, header->bytes, FREE_PATTERN); + + /* Trash the magic number in the block header to stop the same block + * from being freed again. */ + + header->magic_number = 0; + + /* Free the allocated memory. */ + + (free)(header); +} + +void *alloc_test_realloc(void *ptr, size_t bytes) +{ + BlockHeader *header; + void *new_ptr; + size_t bytes_to_copy; + + header = alloc_test_get_header(ptr); + + /* Always allocate a new block, to ensure that code does not rely + * on reallocated blocks having the same memory location. */ + + new_ptr = alloc_test_malloc(bytes); + + if (new_ptr == NULL) { + return NULL; + } + + /* Work out how many bytes to copy. */ + + if (bytes < header->bytes) { + bytes_to_copy = bytes; + } else { + bytes_to_copy = header->bytes; + } + + /* Copy the old block to the new block. */ + + memcpy(new_ptr, ptr, bytes_to_copy); + + /* Free the old block. */ + + alloc_test_free(ptr); + + return new_ptr; +} + +void *alloc_test_calloc(size_t nmemb, size_t bytes) +{ + void *result; + size_t total_bytes = nmemb * bytes; + + /* Allocate the block. */ + + result = alloc_test_malloc(total_bytes); + + if (result == NULL) { + return NULL; + } + + /* Initialise to zero. */ + + memset(result, 0, total_bytes); + + return result; +} + +char *alloc_test_strdup(const char *string) +{ + char *result; + + result = alloc_test_malloc(strlen(string) + 1); + + if (result == NULL) { + return NULL; + } + + strcpy(result, string); + + return result; +} + diff --git a/src/alloc-testing.h b/src/alloc-testing.h new file mode 100644 index 0000000..8118616 --- /dev/null +++ b/src/alloc-testing.h @@ -0,0 +1,120 @@ + +/* + +Copyright (c) 2008, Simon Howard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the C Algorithms project nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +/* + * Memory allocation testing framework. + * + * This file uses the preprocessor to redefine the standard C dynamic memory + * allocation functions for testing purposes. This allows checking that + * code under test correctly frees back all memory allocated, as well as + * the ability to impose artificial limits on allocation, to test that + * code correctly handles out-of-memory scenarios. + */ + +#ifndef ALLOC_TESTING_H +#define ALLOC_TESTING_H + +/* Don't redefine the functions in the alloc-testing.c, as we need the + * standard malloc/free functions. */ + +#ifndef ALLOC_TESTING_C +#undef malloc +#define malloc alloc_test_malloc +#undef free +#define free alloc_test_free +#undef realloc +#define realloc alloc_test_realloc +#undef calloc +#define calloc alloc_test_calloc +#undef strdup +#define strdup alloc_test_strdup +#endif + +/** + * Allocate a block of memory. + * + * @param bytes Number of bytes to allocate. + * @return Pointer to the new block, or NULL if it was not + * possible to allocate the new block. + */ + +void *alloc_test_malloc(size_t bytes); + +/** + * Free a block of memory. + * + * @param ptr Pointer to the block to free. + */ + +void alloc_test_free(void *ptr); + +/** + * Reallocate a previously-allocated block to a new size, preserving + * contents. + * + * @param ptr Pointer to the existing block. + * @param bytes Size of the new block, in bytes. + * @return Pointer to the new block, or NULL if it was not + * possible to allocate the new block. + */ + +void *alloc_test_realloc(void *ptr, size_t bytes); + +/** + * Allocate a block of memory for an array of structures, initialising + * the contents to zero. + * + * @param nmemb Number of structures to allocate for. + * @param bytes Size of each structure, in bytes. + * @return Pointer to the new memory block for the array, + * or NULL if it was not possible to allocate the + * new block. + */ + +void *alloc_test_calloc(size_t nmemb, size_t bytes); + +/** + * Allocate a block of memory containing a copy of a string. + * + * @param string The string to copy. + * @return Pointer to the new memory block containing the + * copied string, or NULL if it was not possible + * to allocate the new block. + */ + +char *alloc_test_strdup(const char *string); + +#endif /* #ifndef ALLOC_TESTING_H */ + diff --git a/src/arraylist.c b/src/arraylist.c index d2f332e..b29af7b 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -38,6 +38,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "arraylist.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + /* Automatically resizing array */ ArrayList *arraylist_new(int length) diff --git a/src/avl-tree.c b/src/avl-tree.c index 2511987..b969f20 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -37,6 +37,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "avl-tree.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + /* AVL Tree (balanced binary search tree) */ struct _AVLTreeNode { diff --git a/src/binary-heap.c b/src/binary-heap.c index 59745f0..dfcca24 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -37,6 +37,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "binary-heap.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + struct _BinaryHeap { BinaryHeapType heap_type; BinaryHeapValue *values; diff --git a/src/binomial-heap.c b/src/binomial-heap.c index 3406c47..5373c8b 100644 --- a/src/binomial-heap.c +++ b/src/binomial-heap.c @@ -38,6 +38,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "binomial-heap.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + typedef struct _BinomialTree BinomialTree; struct _BinomialTree diff --git a/src/bloom-filter.c b/src/bloom-filter.c index bb66f2a..ed1cb55 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -38,6 +38,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "bloom-filter.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + struct _BloomFilter { BloomFilterHashFunc hash_func; unsigned char *table; diff --git a/src/hash-table.c b/src/hash-table.c index 229147f..8782640 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -40,6 +40,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "hash-table.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + struct _HashTableEntry { HashTableKey key; HashTableValue value; diff --git a/src/list.c b/src/list.c index 6b64c99..c05c654 100644 --- a/src/list.c +++ b/src/list.c @@ -37,6 +37,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "list.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + /* A doubly-linked list */ struct _ListEntry { diff --git a/src/queue.c b/src/queue.c index e67159d..ce6b069 100644 --- a/src/queue.c +++ b/src/queue.c @@ -37,6 +37,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "queue.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + /* A double-ended queue */ typedef struct _QueueEntry QueueEntry; diff --git a/src/set.c b/src/set.c index 9d44083..6523ba7 100644 --- a/src/set.c +++ b/src/set.c @@ -37,6 +37,12 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "set.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + /* A set */ struct _SetEntry { diff --git a/src/slist.c b/src/slist.c index dc5b1f2..5b6c4e8 100644 --- a/src/slist.c +++ b/src/slist.c @@ -37,6 +37,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "slist.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + /* A singly-linked list */ struct _SListEntry { diff --git a/src/trie.c b/src/trie.c index 9b9b57b..7493dd8 100644 --- a/src/trie.c +++ b/src/trie.c @@ -40,6 +40,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "trie.h" +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + typedef struct _TrieNode TrieNode; struct _TrieNode { diff --git a/test/test-arraylist.c b/test/test-arraylist.c index 9bf0b1d..cb14e82 100644 --- a/test/test-arraylist.c +++ b/test/test-arraylist.c @@ -39,6 +39,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "arraylist.h" #include "compare-int.h" diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index fc7b13b..d7181d9 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "avl-tree.h" #include "compare-int.h" diff --git a/test/test-binary-heap.c b/test/test-binary-heap.c index 0bd5b5f..1ae4896 100644 --- a/test/test-binary-heap.c +++ b/test/test-binary-heap.c @@ -36,6 +36,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "binary-heap.h" #include "compare-int.h" diff --git a/test/test-binomial-heap.c b/test/test-binomial-heap.c index 5fc5d87..76acd26 100644 --- a/test/test-binomial-heap.c +++ b/test/test-binomial-heap.c @@ -36,6 +36,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "binomial-heap.h" #include "compare-int.h" diff --git a/test/test-bloom-filter.c b/test/test-bloom-filter.c index 5d47093..3c883d8 100644 --- a/test/test-bloom-filter.c +++ b/test/test-bloom-filter.c @@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "bloom-filter.h" #include "hash-string.h" diff --git a/test/test-compare-functions.c b/test/test-compare-functions.c index a9a92cd..6a1a6c8 100644 --- a/test/test-compare-functions.c +++ b/test/test-compare-functions.c @@ -39,6 +39,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "compare-int.h" #include "compare-pointer.h" #include "compare-string.h" diff --git a/test/test-hash-functions.c b/test/test-hash-functions.c index 6d80ced..c5bbbbe 100644 --- a/test/test-hash-functions.c +++ b/test/test-hash-functions.c @@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "hash-pointer.h" #include "hash-int.h" #include "hash-string.h" diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 1477953..bb07b60 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -38,6 +38,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "hash-table.h" #include "hash-int.h" #include "compare-int.h" diff --git a/test/test-list.c b/test/test-list.c index 00cae97..0630a5f 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "list.h" #include "compare-int.h" diff --git a/test/test-queue.c b/test/test-queue.c index f4785e4..50c1717 100644 --- a/test/test-queue.c +++ b/test/test-queue.c @@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "queue.h" int variable1, variable2, variable3, variable4; diff --git a/test/test-set.c b/test/test-set.c index 83c4263..c84e2c6 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -38,6 +38,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "set.h" #include "compare-int.h" #include "hash-int.h" diff --git a/test/test-slist.c b/test/test-slist.c index a03b38d..fe57bbb 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "slist.h" #include "compare-int.h" diff --git a/test/test-trie.c b/test/test-trie.c index 23e58de..f6906e1 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -38,6 +38,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include "alloc-testing.h" + #include "trie.h" int test_array[100000]; From 8823589a036e85d361689b216c1c35e726a6a77c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 11 Jun 2008 22:34:05 +0000 Subject: [PATCH 074/250] Move alloc-testing.[ch] to test/ --- src/Makefile.am | 7 ++----- test/Makefile.am | 6 +++++- {src => test}/alloc-testing.c | 0 {src => test}/alloc-testing.h | 6 ++++-- 4 files changed, 11 insertions(+), 8 deletions(-) rename {src => test}/alloc-testing.c (100%) rename {src => test}/alloc-testing.h (98%) diff --git a/src/Makefile.am b/src/Makefile.am index dd79e7e..732d07c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,17 +12,14 @@ avl-tree.h compare-pointer.h hash-pointer.h list.h slist.h \ queue.h compare-string.h hash-string.h trie.h binary-heap.h \ bloom-filter.h binomial-heap.h -ALLOC_TESTING_FILES=\ -alloc-testing.c alloc-testing.h - SRC=\ arraylist.c compare-pointer.c hash-pointer.c list.c slist.c \ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c -libcalgtest_a_CFLAGS=-DALLOC_TESTING -libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(ALLOC_TESTING_FILES) +libcalgtest_a_CFLAGS=-DALLOC_TESTING -I../test +libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) diff --git a/test/Makefile.am b/test/Makefile.am index 6138ac4..8dced05 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -19,9 +19,13 @@ TESTS = \ test-trie check_PROGRAMS = $(TESTS) +check_LIBRARIES = libtestframework.a + +libtestframework_a_SOURCES=\ + alloc-testing.c alloc-testing.h AM_CFLAGS = -I../src -Wall -LDADD = $(top_builddir)/src/libcalgtest.a +LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a EXTRA_DIST=valgrind-wrapper diff --git a/src/alloc-testing.c b/test/alloc-testing.c similarity index 100% rename from src/alloc-testing.c rename to test/alloc-testing.c diff --git a/src/alloc-testing.h b/test/alloc-testing.h similarity index 98% rename from src/alloc-testing.h rename to test/alloc-testing.h index 8118616..dc45fbf 100644 --- a/src/alloc-testing.h +++ b/test/alloc-testing.h @@ -33,8 +33,10 @@ POSSIBILITY OF SUCH DAMAGE. */ -/* - * Memory allocation testing framework. +/** + * @file alloc-testing.h + * + * @brief Memory allocation testing framework. * * This file uses the preprocessor to redefine the standard C dynamic memory * allocation functions for testing purposes. This allows checking that From 7230de48eb1136fcc92129ebc709af30c8f07a9e Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 11 Jun 2008 22:42:59 +0000 Subject: [PATCH 075/250] Fix Doxygen errors. --- src/arraylist.h | 10 ++++++++-- src/avl-tree.h | 2 +- src/binary-heap.h | 7 ++++++- src/binomial-heap.h | 7 ++++++- src/hash-table.h | 1 - src/list.h | 6 +++--- src/set.h | 2 -- src/slist.h | 2 +- src/trie.h | 4 ++++ 9 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/arraylist.h b/src/arraylist.h index 1704aa0..5e3f52d 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -71,7 +71,13 @@ typedef void *ArrayListValue; * @see arraylist_new */ -typedef struct _ArrayList { +typedef struct _ArrayList ArrayList; + +/** + * Definition of an @ref ArrayList. + */ + +struct _ArrayList { /** Entries in the array */ @@ -84,7 +90,7 @@ typedef struct _ArrayList { /** Private data and should not be accessed */ int _alloced; -} ArrayList; +}; /** * Compare two values in an arraylist to determine if they are equal. diff --git a/src/avl-tree.h b/src/avl-tree.h index b482f30..774e55c 100644 --- a/src/avl-tree.h +++ b/src/avl-tree.h @@ -199,7 +199,7 @@ AVLTreeNode *avl_tree_lookup_node(AVLTree *tree, AVLTreeKey key); * @param tree The AVL tree to search. * @param key The key to search for. * @return The value associated with the given key, or - * @ref AVLTREE_NULL if no entry with the given key is + * @ref AVL_TREE_NULL if no entry with the given key is * found. */ diff --git a/src/binary-heap.h b/src/binary-heap.h index 5ef60cf..b10e363 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -66,8 +66,13 @@ extern "C" { */ typedef enum { + /** A minimum heap. */ + BINARY_HEAP_TYPE_MIN, - BINARY_HEAP_TYPE_MAX, + + /** A maximum heap. */ + + BINARY_HEAP_TYPE_MAX } BinaryHeapType; /** diff --git a/src/binomial-heap.h b/src/binomial-heap.h index 8cd47da..d499bda 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -66,8 +66,13 @@ extern "C" { */ typedef enum { + /** A minimum heap. */ + BINOMIAL_HEAP_TYPE_MIN, - BINOMIAL_HEAP_TYPE_MAX, + + /** A maximum heap. */ + + BINOMIAL_HEAP_TYPE_MAX } BinomialHeapType; /** diff --git a/src/hash-table.h b/src/hash-table.h index e1870a0..1fa3c5e 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -233,7 +233,6 @@ int hash_table_num_entries(HashTable *hash_table); * @param hash_table The hash table. * @param iter Pointer to an iterator structure to * initialise. - * @param */ void hash_table_iterate(HashTable *hash_table, HashTableIterator *iter); diff --git a/src/list.h b/src/list.h index 9b18c7f..b13413f 100644 --- a/src/list.h +++ b/src/list.h @@ -56,7 +56,7 @@ POSSIBILITY OF SUCH DAMAGE. * To iterate over entries in a list, use @ref list_iterate to initialise * a @ref ListIterator structure, with @ref list_iter_next and * @ref list_iter_has_more to retrieve each value in turn. - * @list_iter_remove can be used to remove the current entry. + * @ref list_iter_remove can be used to remove the current entry. * * To access an entry in the list by index, use @ref list_nth_entry or * @ref list_nth_data. @@ -84,7 +84,7 @@ typedef struct _ListEntry ListEntry; typedef struct _ListIterator ListIterator; /** - * A value stored in a @ref List. + * A value stored in a list. */ typedef void *ListValue; @@ -151,7 +151,7 @@ ListEntry *list_prepend(ListEntry **list, ListValue data); * Append a value to the end of a list. * * @param list Pointer to the list to append to. - * @param value The value to append. + * @param data The value to append. * @return The new entry in the list, or NULL if it was not * possible to allocate the memory for the new entry. */ diff --git a/src/set.h b/src/set.h index 013afdf..b266508 100644 --- a/src/set.h +++ b/src/set.h @@ -252,8 +252,6 @@ void set_iterate(Set *set, SetIterator *iter); /** * Determine if there are more values in the set to iterate over. - * It should be noted that a set iterator is not freed when iterating - * has finished. This should be done using @ref set_iter_free. * * @param iterator The set iterator object. * @return Zero if there are no more values in the set diff --git a/src/slist.h b/src/slist.h index bde7f7f..9b0b9e7 100644 --- a/src/slist.h +++ b/src/slist.h @@ -97,7 +97,7 @@ typedef struct _SListEntry SListEntry; typedef struct _SListIterator SListIterator; /** - * Value stored in a @ref SList. + * Value stored in a list. */ typedef void *SListValue; diff --git a/src/trie.h b/src/trie.h index 2f8432a..38c90a5 100644 --- a/src/trie.h +++ b/src/trie.h @@ -59,6 +59,10 @@ POSSIBILITY OF SUCH DAMAGE. extern "C" { #endif +/** + * A trie structure. + */ + typedef struct _Trie Trie; /** From 0737bf1c65acaea777283cf97d59f2fa1100bc8f Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 12 Jun 2008 19:40:48 +0000 Subject: [PATCH 076/250] Add the ability to limit memory allocation for testing malloc() out of memory conditions and a basic test framework for checking that memory is correctly freed. Add malloc test cases for the queue, binary heap, and arraylist. --- test/Makefile.am | 3 +- test/alloc-testing.c | 176 ++++++++++++++++++++++++++-------- test/alloc-testing.h | 22 +++++ test/test-arraylist.c | 86 +++++++++++++---- test/test-avl-tree.c | 17 ++-- test/test-binary-heap.c | 72 ++++++++++++-- test/test-binomial-heap.c | 14 ++- test/test-bloom-filter.c | 16 +++- test/test-compare-functions.c | 21 ++-- test/test-hash-functions.c | 14 ++- test/test-hash-table.c | 18 ++-- test/test-list.c | 33 ++++--- test/test-queue.c | 46 +++++++-- test/test-set.c | 26 +++-- test/test-slist.c | 34 ++++--- test/test-trie.c | 16 +++- 16 files changed, 464 insertions(+), 150 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index 8dced05..f757ddb 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -22,7 +22,8 @@ check_PROGRAMS = $(TESTS) check_LIBRARIES = libtestframework.a libtestframework_a_SOURCES=\ - alloc-testing.c alloc-testing.h +alloc-testing.c alloc-testing.h \ +framework.c framework.h AM_CFLAGS = -I../src -Wall LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a diff --git a/test/alloc-testing.c b/test/alloc-testing.c index 3189083..f8ac378 100644 --- a/test/alloc-testing.c +++ b/test/alloc-testing.c @@ -71,15 +71,19 @@ struct _BlockHeader { BlockHeader *prev, *next; }; -/* Head of a linked list of allocated blocks */ +/* Head of a linked list of allocated blocks. */ static BlockHeader *allocated_blocks = NULL; -/* Count of the current number of allocated bytes */ +/* Count of the current number of allocated bytes. */ static size_t allocated_bytes = 0; -/* Get the block header for an allocated pointer */ +/* Allocation limit, negative value means no limit. */ + +signed int allocation_limit = -1; + +/* Get the block header for an allocated pointer. */ static BlockHeader *alloc_test_get_header(void *ptr) { @@ -94,9 +98,17 @@ static BlockHeader *alloc_test_get_header(void *ptr) return result; } +/* Test whether a new value of allocated_bytes would be valid. */ + +static int alloc_test_new_size_allowed(size_t new_size) +{ + return allocation_limit < 0 + || new_size < allocation_limit; +} + /* Overwrite a block of memory with a repeated pattern. */ -void alloc_test_overwrite(void *ptr, size_t length, unsigned int pattern) +static void alloc_test_overwrite(void *ptr, size_t length, unsigned int pattern) { unsigned char *byte_ptr; unsigned int pattern_seq; @@ -112,15 +124,17 @@ void alloc_test_overwrite(void *ptr, size_t length, unsigned int pattern) } } -void *alloc_test_malloc(size_t bytes) +/* Base malloc function used by other functions. */ + +BlockHeader *alloc_test_base_malloc(size_t bytes) { BlockHeader *header; - void *result; + void *ptr; /* Allocate the requested block with enough room for the block header * as well. */ - header = (malloc)(sizeof(BlockHeader) + bytes); + header = malloc(sizeof(BlockHeader) + bytes); if (header == NULL) { return NULL; @@ -139,32 +153,20 @@ void *alloc_test_malloc(size_t bytes) header->next->prev = header; } - /* Update counter */ - - allocated_bytes += bytes; - result = header + 1; - /* Fill memory with MALLOC_PATTERN, to ensure that code under test * does not rely on memory being initialised to zero. */ - alloc_test_overwrite(result, bytes, MALLOC_PATTERN); - - /* Skip past the header and return the block itself */ + ptr = header + 1; + alloc_test_overwrite(ptr, bytes, MALLOC_PATTERN); - return result; + return header; } -void alloc_test_free(void *ptr) -{ - BlockHeader *header; - - /* Must accept NULL as a valid pointer to free. */ +/* Base free function */ - if (ptr == NULL) { - return; - } - - header = alloc_test_get_header(ptr); +void alloc_test_base_free(BlockHeader *header) +{ + void *ptr; /* Unlink from the linked list. */ @@ -178,14 +180,10 @@ void alloc_test_free(void *ptr) header->next->prev = header->prev; } - /* Update counter */ - - assert(allocated_bytes >= header->bytes); - allocated_bytes -= header->bytes; - /* Trash the allocated block to foil any code that relies on memory * that has been freed. */ + ptr = header + 1; alloc_test_overwrite(ptr, header->bytes, FREE_PATTERN); /* Trash the magic number in the block header to stop the same block @@ -195,41 +193,127 @@ void alloc_test_free(void *ptr) /* Free the allocated memory. */ - (free)(header); + free(header); } -void *alloc_test_realloc(void *ptr, size_t bytes) +/* Main malloc function */ + +void *alloc_test_malloc(size_t bytes) +{ + BlockHeader *header; + void *result; + + /* Check if we have reached the allocation limit. */ + + if (!alloc_test_new_size_allowed(allocated_bytes + bytes)) { + return NULL; + } + + /* Do the allocation */ + + header = alloc_test_base_malloc(bytes); + + if (header == NULL) { + return NULL; + } + + /* Update counter */ + + allocated_bytes += bytes; + + /* Skip past the header and return the block itself */ + + result = header + 1; + return result; +} + +void alloc_test_free(void *ptr) { BlockHeader *header; + size_t block_size; + + /* Must accept NULL as a valid pointer to free. */ + + if (ptr == NULL) { + return; + } + + /* Free the block */ + + header = alloc_test_get_header(ptr); + block_size = header->bytes; + assert(allocated_bytes >= block_size); + + alloc_test_base_free(header); + + /* Update counter */ + + allocated_bytes -= block_size; +} + +void *alloc_test_realloc(void *ptr, size_t bytes) +{ + BlockHeader *old_block, *new_block; void *new_ptr; + size_t old_bytes; + size_t new_allocated_bytes; size_t bytes_to_copy; - header = alloc_test_get_header(ptr); + /* A NULL value can be passed to ptr to make realloc behave + * like malloc(). */ + + if (ptr != NULL) { + old_block = alloc_test_get_header(ptr); + old_bytes = old_block->bytes; + } else { + old_block = NULL; + old_bytes = 0; + } + + /* Sanity check the new allocated_bytes value */ + + assert(allocated_bytes + bytes >= old_bytes); + + /* Check the new value for allocated bytes is within the + * allocation limit. */ + + new_allocated_bytes = allocated_bytes + bytes - old_bytes; + + if (!alloc_test_new_size_allowed(new_allocated_bytes)) { + return NULL; + } /* Always allocate a new block, to ensure that code does not rely * on reallocated blocks having the same memory location. */ - new_ptr = alloc_test_malloc(bytes); + new_block = alloc_test_base_malloc(bytes); - if (new_ptr == NULL) { + if (new_block == NULL) { return NULL; } /* Work out how many bytes to copy. */ - if (bytes < header->bytes) { + if (bytes < old_bytes) { bytes_to_copy = bytes; } else { - bytes_to_copy = header->bytes; + bytes_to_copy = old_bytes; } /* Copy the old block to the new block. */ + new_ptr = new_block + 1; memcpy(new_ptr, ptr, bytes_to_copy); /* Free the old block. */ - alloc_test_free(ptr); + if (old_block != NULL) { + alloc_test_base_free(old_block); + } + + /* Update allocated_bytes counter. */ + + allocated_bytes = new_allocated_bytes; return new_ptr; } @@ -269,3 +353,17 @@ char *alloc_test_strdup(const char *string) return result; } +void alloc_test_set_limit(signed int bytes) +{ + if (bytes < 0) { + allocation_limit = -1; + } else { + allocation_limit = allocated_bytes + bytes; + } +} + +size_t alloc_test_get_allocated(void) +{ + return allocated_bytes; +} + diff --git a/test/alloc-testing.h b/test/alloc-testing.h index dc45fbf..57223e1 100644 --- a/test/alloc-testing.h +++ b/test/alloc-testing.h @@ -118,5 +118,27 @@ void *alloc_test_calloc(size_t nmemb, size_t bytes); char *alloc_test_strdup(const char *string); +/** + * Set an artificial limit on the amount of memory that can be + * allocated. + * + * @param bytes The maximum number of bytes that may be allocated, + * relative to the currently allocated number of bytes. + * For example, if this has a value of 100, 100 more + * bytes may be allocated. If this has a negative + * value, any current limit is disabled. + */ + +void alloc_test_set_limit(signed int bytes); + +/** + * Get a count of the number of bytes currently allocated. + * + * @return The number of bytes currently allocated by + * the allocation system. + */ + +size_t alloc_test_get_allocated(void); + #endif /* #ifndef ALLOC_TESTING_H */ diff --git a/test/test-arraylist.c b/test/test-arraylist.c index cb14e82..e96d43b 100644 --- a/test/test-arraylist.c +++ b/test/test-arraylist.c @@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "arraylist.h" #include "compare-int.h" @@ -88,6 +89,16 @@ void test_arraylist_new_free(void) /* Freeing a null arraylist works */ arraylist_free(NULL); + + /* Test low memory scenarios (failed malloc) */ + + alloc_test_set_limit(0); + arraylist = arraylist_new(0); + assert(arraylist == NULL); + + alloc_test_set_limit(100 * sizeof(void *)); + arraylist = arraylist_new(100); + assert(arraylist == NULL); } void test_arraylist_append(void) @@ -101,16 +112,16 @@ void test_arraylist_append(void) /* Append some entries */ - arraylist_append(arraylist, &variable1); + assert(arraylist_append(arraylist, &variable1) != 0); assert(arraylist->length == 1); - arraylist_append(arraylist, &variable2); + assert(arraylist_append(arraylist, &variable2) != 0); assert(arraylist->length == 2); - arraylist_append(arraylist, &variable3); + assert(arraylist_append(arraylist, &variable3) != 0); assert(arraylist->length == 3); - arraylist_append(arraylist, &variable4); + assert(arraylist_append(arraylist, &variable4) != 0); assert(arraylist->length == 4); assert(arraylist->data[0] == &variable1); @@ -121,10 +132,26 @@ void test_arraylist_append(void) /* Test appending many entries */ for (i=0; i<10000; ++i) { - arraylist_append(arraylist, NULL); + assert(arraylist_append(arraylist, NULL) != 0); } arraylist_free(arraylist); + + /* Test low memory scenario */ + + arraylist = arraylist_new(100); + + alloc_test_set_limit(0); + + for (i=0; i<100; ++i) { + assert(arraylist_append(arraylist, NULL) != 0); + } + + assert(arraylist->length == 100); + assert(arraylist_append(arraylist, NULL) == 0); + assert(arraylist->length == 100); + + arraylist_free(arraylist); } @@ -139,16 +166,16 @@ void test_arraylist_prepend(void) /* Append some entries */ - arraylist_prepend(arraylist, &variable1); + assert(arraylist_prepend(arraylist, &variable1) != 0); assert(arraylist->length == 1); - arraylist_prepend(arraylist, &variable2); + assert(arraylist_prepend(arraylist, &variable2) != 0); assert(arraylist->length == 2); - arraylist_prepend(arraylist, &variable3); + assert(arraylist_prepend(arraylist, &variable3) != 0); assert(arraylist->length == 3); - arraylist_prepend(arraylist, &variable4); + assert(arraylist_prepend(arraylist, &variable4) != 0); assert(arraylist->length == 4); assert(arraylist->data[0] == &variable4); @@ -159,9 +186,25 @@ void test_arraylist_prepend(void) /* Test prepending many entries */ for (i=0; i<10000; ++i) { - arraylist_prepend(arraylist, NULL); + assert(arraylist_prepend(arraylist, NULL) != 0); + } + + arraylist_free(arraylist); + + /* Test low memory scenario */ + + arraylist = arraylist_new(100); + + alloc_test_set_limit(0); + + for (i=0; i<100; ++i) { + assert(arraylist_prepend(arraylist, NULL) != 0); } + assert(arraylist->length == 100); + assert(arraylist_prepend(arraylist, NULL) == 0); + assert(arraylist->length == 100); + arraylist_free(arraylist); } @@ -411,17 +454,22 @@ void test_arraylist_sort(void) arraylist_free(arraylist); } +static UnitTestFunction tests[] = { + test_arraylist_new_free, + test_arraylist_append, + test_arraylist_prepend, + test_arraylist_insert, + test_arraylist_remove, + test_arraylist_remove_range, + test_arraylist_index_of, + test_arraylist_clear, + test_arraylist_sort, + NULL +}; + int main(int argc, char *argv[]) { - test_arraylist_new_free(); - test_arraylist_append(); - test_arraylist_prepend(); - test_arraylist_insert(); - test_arraylist_remove(); - test_arraylist_remove_range(); - test_arraylist_index_of(); - test_arraylist_clear(); - test_arraylist_sort(); + run_tests(tests); return 0; } diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index d7181d9..c955291 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "avl-tree.h" #include "compare-int.h" @@ -279,14 +280,18 @@ void test_avl_tree_to_array(void) avl_tree_free(tree); } +static UnitTestFunction tests[] = { + test_avl_tree_new, + test_avl_tree_free, + test_avl_tree_insert_lookup, + test_avl_tree_remove, + test_avl_tree_to_array, + NULL +}; + int main(int argc, char *argv[]) { - test_avl_tree_new(); - test_avl_tree_free(); - test_avl_tree_insert_lookup(); - test_avl_tree_remove(); - test_avl_tree_to_array(); - + run_tests(tests); return 0; } diff --git a/test/test-binary-heap.c b/test/test-binary-heap.c index 1ae4896..de062d5 100644 --- a/test/test-binary-heap.c +++ b/test/test-binary-heap.c @@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "binary-heap.h" #include "compare-int.h" @@ -52,6 +53,16 @@ void test_binary_heap_new_free(void) heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); binary_heap_free(heap); } + + /* Test low memory scenario */ + + alloc_test_set_limit(0); + heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); + assert(heap == NULL); + + alloc_test_set_limit(16 * sizeof(void *)); + heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); + assert(heap == NULL); } void test_binary_heap_insert(void) @@ -63,7 +74,7 @@ void test_binary_heap_insert(void) for (i=0; i<1000; ++i) { test_array[i] = i; - binary_heap_insert(heap, &test_array[i]); + assert(binary_heap_insert(heap, &test_array[i]) != 0); } assert(binary_heap_num_entries(heap) == 1000); @@ -83,7 +94,7 @@ void test_min_heap(void) for (i=0; i<1000; ++i) { test_array[i] = i; - binary_heap_insert(heap, &test_array[i]); + assert(binary_heap_insert(heap, &test_array[i]) != 0); } /* Pop values off the heap and check they are in order */ @@ -116,7 +127,7 @@ void test_max_heap(void) for (i=0; i<1000; ++i) { test_array[i] = i; - binary_heap_insert(heap, &test_array[i]); + assert(binary_heap_insert(heap, &test_array[i]) != 0); } /* Pop values off the heap and check they are in order */ @@ -132,12 +143,59 @@ void test_max_heap(void) binary_heap_free(heap); } +/* Test out of memory scenario when adding items */ + +void test_out_of_memory(void) +{ + BinaryHeap *heap; + int *value; + int values[] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + int i; + + /* Allocate a heap and fill to the default limit */ + + heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); + + alloc_test_set_limit(0); + + for (i=0; i<16; ++i) { + assert(binary_heap_insert(heap, &values[i]) != 0); + } + + assert(binary_heap_num_entries(heap) == 16); + + /* Check that we cannot add new values */ + + for (i=0; i<16; ++i) { + assert(binary_heap_insert(heap, &values[i]) == 0); + assert(binary_heap_num_entries(heap) == 16); + } + + /* Check that we can read the values back out again and they + * are in the right order. */ + + for (i=0; i<16; ++i) { + value = binary_heap_pop(heap); + assert(*value == i); + } + + assert(binary_heap_num_entries(heap) == 0); + + binary_heap_free(heap); +} + +static UnitTestFunction tests[] = { + test_binary_heap_new_free, + test_binary_heap_insert, + test_min_heap, + test_max_heap, + test_out_of_memory, + NULL +}; + int main(int argc, char *argv[]) { - test_binary_heap_new_free(); - test_binary_heap_insert(); - test_min_heap(); - test_max_heap(); + run_tests(tests); return 0; } diff --git a/test/test-binomial-heap.c b/test/test-binomial-heap.c index 76acd26..1e4d2b5 100644 --- a/test/test-binomial-heap.c +++ b/test/test-binomial-heap.c @@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "binomial-heap.h" #include "compare-int.h" @@ -126,12 +127,17 @@ void test_max_heap(void) binomial_heap_free(heap); } +static UnitTestFunction tests[] = { + test_binomial_heap_new_free, + test_binomial_heap_insert, + test_min_heap, + test_max_heap, + NULL +}; + int main(int argc, char *argv[]) { - test_binomial_heap_new_free(); - test_binomial_heap_insert(); - test_min_heap(); - test_max_heap(); + run_tests(tests); return 0; } diff --git a/test/test-bloom-filter.c b/test/test-bloom-filter.c index 3c883d8..87a8633 100644 --- a/test/test-bloom-filter.c +++ b/test/test-bloom-filter.c @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "bloom-filter.h" #include "hash-string.h" @@ -190,13 +191,18 @@ void test_bloom_filter_union(void) bloom_filter_free(result); } +static UnitTestFunction tests[] = { + test_bloom_filter_new_free, + test_bloom_filter_insert_query, + test_bloom_filter_read_load, + test_bloom_filter_intersection, + test_bloom_filter_union, + NULL +}; + int main(int argc, char *argv[]) { - test_bloom_filter_new_free(); - test_bloom_filter_insert_query(); - test_bloom_filter_read_load(); - test_bloom_filter_intersection(); - test_bloom_filter_union(); + run_tests(tests); return 0; } diff --git a/test/test-compare-functions.c b/test/test-compare-functions.c index 6a1a6c8..563426c 100644 --- a/test/test-compare-functions.c +++ b/test/test-compare-functions.c @@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "compare-int.h" #include "compare-pointer.h" @@ -201,17 +202,21 @@ void test_string_nocase_equal(void) assert(string_nocase_equal(test1, test4) != 0); } +static UnitTestFunction tests[] = { + test_int_compare, + test_int_equal, + test_pointer_compare, + test_pointer_equal, + test_string_compare, + test_string_equal, + test_string_nocase_compare, + test_string_nocase_equal, + NULL +}; int main(int argc, char *argv[]) { - test_int_compare(); - test_int_equal(); - test_pointer_compare(); - test_pointer_equal(); - test_string_compare(); - test_string_equal(); - test_string_nocase_compare(); - test_string_nocase_equal(); + run_tests(tests); return 0; } diff --git a/test/test-hash-functions.c b/test/test-hash-functions.c index c5bbbbe..44ce7f0 100644 --- a/test/test-hash-functions.c +++ b/test/test-hash-functions.c @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "hash-pointer.h" #include "hash-int.h" @@ -140,12 +141,17 @@ void test_string_nocase_hash(void) assert(string_nocase_hash(test1) == string_nocase_hash(test4)); } +static UnitTestFunction tests[] = { + test_pointer_hash, + test_int_hash, + test_string_hash, + test_string_nocase_hash, + NULL +}; + int main(int argc, char *argv[]) { - test_pointer_hash(); - test_int_hash(); - test_string_hash(); - test_string_nocase_hash(); + run_tests(tests); return 0; } diff --git a/test/test-hash-table.c b/test/test-hash-table.c index bb07b60..b7a4466 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "hash-table.h" #include "hash-int.h" @@ -381,14 +382,19 @@ void test_hash_table_free_functions(void) assert(allocated_values == 0); } +static UnitTestFunction tests[] = { + test_hash_table_new_free, + test_hash_table_insert_lookup, + test_hash_table_remove, + test_hash_table_iterating, + test_hash_table_iterating_remove, + test_hash_table_free_functions, + NULL +}; + int main(int argc, char *argv[]) { - test_hash_table_new_free(); - test_hash_table_insert_lookup(); - test_hash_table_remove(); - test_hash_table_iterating(); - test_hash_table_iterating_remove(); - test_hash_table_free_functions(); + run_tests(tests); return 0; } diff --git a/test/test-list.c b/test/test-list.c index 0630a5f..963106d 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "list.h" #include "compare-int.h" @@ -525,23 +526,27 @@ void test_list_iterate_bad_remove(void) list_free(list); } +static UnitTestFunction tests[] = { + test_list_append, + test_list_prepend, + test_list_free, + test_list_next, + test_list_nth_entry, + test_list_nth_data, + test_list_length, + test_list_remove_entry, + test_list_remove_data, + test_list_sort, + test_list_find_data, + test_list_to_array, + test_list_iterate, + test_list_iterate_bad_remove, + NULL +}; int main(int argc, char *argv[]) { - test_list_append(); - test_list_prepend(); - test_list_free(); - test_list_next(); - test_list_nth_entry(); - test_list_nth_data(); - test_list_length(); - test_list_remove_entry(); - test_list_remove_data(); - test_list_sort(); - test_list_find_data(); - test_list_to_array(); - test_list_iterate(); - test_list_iterate_bad_remove(); + run_tests(tests); return 0; } diff --git a/test/test-queue.c b/test/test-queue.c index 50c1717..9cbbd2a 100644 --- a/test/test-queue.c +++ b/test/test-queue.c @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "queue.h" @@ -84,6 +85,12 @@ void test_queue_new_free(void) } queue_free(queue); + + /* Test allocation when there is no free memory */ + + alloc_test_set_limit(0); + queue = queue_new(); + assert(queue == NULL); } void test_queue_push_head(void) @@ -119,6 +126,15 @@ void test_queue_push_head(void) assert(queue_pop_head(queue) == &variable1); queue_free(queue); + + /* Test behavior when running out of memory. */ + + queue = queue_new(); + + alloc_test_set_limit(0); + assert(!queue_push_head(queue, &variable1)); + + queue_free(queue); } void test_queue_pop_head(void) @@ -215,6 +231,15 @@ void test_queue_push_tail(void) assert(queue_pop_tail(queue) == &variable1); queue_free(queue); + + /* Test behavior when running out of memory. */ + + queue = queue_new(); + + alloc_test_set_limit(0); + assert(!queue_push_tail(queue, &variable1)); + + queue_free(queue); } void test_queue_pop_tail(void) @@ -305,16 +330,21 @@ void test_queue_is_empty(void) queue_free(queue); } +static UnitTestFunction tests[] = { + test_queue_new_free, + test_queue_push_head, + test_queue_pop_head, + test_queue_peek_head, + test_queue_push_tail, + test_queue_pop_tail, + test_queue_peek_tail, + test_queue_is_empty, + NULL +}; + int main(int argc, char *argv[]) { - test_queue_new_free(); - test_queue_push_head(); - test_queue_pop_head(); - test_queue_peek_head(); - test_queue_push_tail(); - test_queue_pop_tail(); - test_queue_peek_tail(); - test_queue_is_empty(); + run_tests(tests); return 0; } diff --git a/test/test-set.c b/test/test-set.c index c84e2c6..31de6ff 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "set.h" #include "compare-int.h" @@ -460,18 +461,23 @@ void test_set_free_function(void) assert(allocated_values == 0); } +static UnitTestFunction tests[] = { + test_set_new_free, + test_set_insert, + test_set_query, + test_set_remove, + test_set_intersection, + test_set_union, + test_set_iterating, + test_set_iterating_remove, + test_set_to_array, + test_set_free_function, + NULL +}; + int main(int argc, char *argv[]) { - test_set_new_free(); - test_set_insert(); - test_set_query(); - test_set_remove(); - test_set_intersection(); - test_set_union(); - test_set_iterating(); - test_set_iterating_remove(); - test_set_to_array(); - test_set_free_function(); + run_tests(tests); return 0; } diff --git a/test/test-slist.c b/test/test-slist.c index fe57bbb..7502cf3 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "slist.h" #include "compare-int.h" @@ -510,22 +511,27 @@ void test_slist_iterate_bad_remove(void) slist_free(list); } +static UnitTestFunction tests[] = { + test_slist_append, + test_slist_prepend, + test_slist_free, + test_slist_next, + test_slist_nth_entry, + test_slist_nth_data, + test_slist_length, + test_slist_remove_entry, + test_slist_remove_data, + test_slist_sort, + test_slist_find_data, + test_slist_to_array, + test_slist_iterate, + test_slist_iterate_bad_remove, + NULL +}; + int main(int argc, char *argv[]) { - test_slist_append(); - test_slist_prepend(); - test_slist_free(); - test_slist_next(); - test_slist_nth_entry(); - test_slist_nth_data(); - test_slist_length(); - test_slist_remove_entry(); - test_slist_remove_data(); - test_slist_sort(); - test_slist_find_data(); - test_slist_to_array(); - test_slist_iterate(); - test_slist_iterate_bad_remove(); + run_tests(tests); return 0; } diff --git a/test/test-trie.c b/test/test-trie.c index f6906e1..68f45ab 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "alloc-testing.h" +#include "framework.h" #include "trie.h" @@ -207,13 +208,18 @@ void test_insert_empty(void) trie_free(trie); } +static UnitTestFunction tests[] = { + test_trie_new_free, + test_lookup, + test_remove, + test_replace, + test_insert_empty, + NULL +}; + int main(int argc, char *argv[]) { - test_trie_new_free(); - test_lookup(); - test_remove(); - test_replace(); - test_insert_empty(); + run_tests(tests); return 0; } From 6c4ed135c8bb06f4a91d00ac4e884ab97354f9f6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 12 Jun 2008 19:58:31 +0000 Subject: [PATCH 077/250] Add assertations for [s]list_{prepend,append}, out of memory test cases. --- test/test-list.c | 62 +++++++++++++++++++++++++++++++++-------------- test/test-slist.c | 47 ++++++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 30 deletions(-) diff --git a/test/test-list.c b/test/test-list.c index 963106d..c9d38a4 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -51,10 +51,10 @@ ListEntry *generate_list(void) { ListEntry *list = NULL; - list_append(&list, &variable1); - list_append(&list, &variable2); - list_append(&list, &variable3); - list_append(&list, &variable4); + assert(list_append(&list, &variable1) != NULL); + assert(list_append(&list, &variable2) != NULL); + assert(list_append(&list, &variable3) != NULL); + assert(list_append(&list, &variable4) != NULL); return list; } @@ -78,20 +78,30 @@ void test_list_append(void) { ListEntry *list = NULL; - list_append(&list, &variable1); + assert(list_append(&list, &variable1) != NULL); check_list_integrity(list); - list_append(&list, &variable2); + assert(list_append(&list, &variable2) != NULL); check_list_integrity(list); - list_append(&list, &variable3); + assert(list_append(&list, &variable3) != NULL); check_list_integrity(list); - list_append(&list, &variable4); + assert(list_append(&list, &variable4) != NULL); check_list_integrity(list); + assert(list_length(list) == 4); + assert(list_nth_data(list, 0) == &variable1); assert(list_nth_data(list, 1) == &variable2); assert(list_nth_data(list, 2) == &variable3); assert(list_nth_data(list, 3) == &variable4); + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + assert(list_length(list) == 4); + assert(list_append(&list, &variable1) == NULL); + assert(list_length(list) == 4); + check_list_integrity(list); + list_free(list); } @@ -99,13 +109,13 @@ void test_list_prepend(void) { ListEntry *list = NULL; - list_prepend(&list, &variable1); + assert(list_prepend(&list, &variable1) != NULL); check_list_integrity(list); - list_prepend(&list, &variable2); + assert(list_prepend(&list, &variable2) != NULL); check_list_integrity(list); - list_prepend(&list, &variable3); + assert(list_prepend(&list, &variable3) != NULL); check_list_integrity(list); - list_prepend(&list, &variable4); + assert(list_prepend(&list, &variable4) != NULL); check_list_integrity(list); assert(list_nth_data(list, 0) == &variable4); @@ -113,6 +123,14 @@ void test_list_prepend(void) assert(list_nth_data(list, 2) == &variable2); assert(list_nth_data(list, 3) == &variable1); + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + assert(list_length(list) == 4); + assert(list_prepend(&list, &variable1) == NULL); + assert(list_length(list) == 4); + check_list_integrity(list); + list_free(list); } @@ -219,7 +237,7 @@ void test_list_length(void) /* Add an entry and check that it still works properly */ - list_prepend(&list, &variable1); + assert(list_prepend(&list, &variable1) != NULL); assert(list_length(list) == 5); @@ -278,7 +296,7 @@ void test_list_remove_data(void) list = NULL; for (i=0; i Date: Fri, 13 Jun 2008 00:00:21 +0000 Subject: [PATCH 078/250] Switch to ISC license, update copyright to 2005-2008. --- COPYING | 39 +++++++++----------------- README | 5 ++-- doc/intro.h | 47 ++++++++++++------------------- src/arraylist.c | 51 ++++++++++++---------------------- src/arraylist.h | 51 ++++++++++++---------------------- src/avl-tree.c | 51 ++++++++++++---------------------- src/avl-tree.h | 49 ++++++++++++--------------------- src/binary-heap.c | 49 ++++++++++++--------------------- src/binary-heap.h | 49 ++++++++++++--------------------- src/binomial-heap.c | 49 ++++++++++++--------------------- src/binomial-heap.h | 49 ++++++++++++--------------------- src/bloom-filter.c | 51 ++++++++++++---------------------- src/bloom-filter.h | 49 ++++++++++++--------------------- src/compare-int.c | 43 ++++++++++------------------- src/compare-int.h | 43 ++++++++++------------------- src/compare-pointer.c | 52 ++++++++++++----------------------- src/compare-pointer.h | 43 ++++++++++------------------- src/compare-string.c | 51 ++++++++++++---------------------- src/compare-string.h | 49 ++++++++++++--------------------- src/hash-int.c | 51 ++++++++++++---------------------- src/hash-int.h | 43 ++++++++++------------------- src/hash-pointer.c | 51 ++++++++++++---------------------- src/hash-pointer.h | 43 ++++++++++------------------- src/hash-string.c | 51 ++++++++++++---------------------- src/hash-string.h | 43 ++++++++++------------------- src/hash-table.c | 51 ++++++++++++---------------------- src/hash-table.h | 49 ++++++++++++--------------------- src/libcalg.h | 52 ++++++++++++----------------------- src/list.c | 51 ++++++++++++---------------------- src/list.h | 51 ++++++++++++---------------------- src/queue.c | 51 ++++++++++++---------------------- src/queue.h | 52 ++++++++++++----------------------- src/set.c | 51 ++++++++++++---------------------- src/set.h | 49 ++++++++++++--------------------- src/slist.c | 51 ++++++++++++---------------------- src/slist.h | 51 ++++++++++++---------------------- src/trie.c | 49 ++++++++++++--------------------- src/trie.h | 49 ++++++++++++--------------------- test/alloc-testing.c | 51 ++++++++++++---------------------- test/alloc-testing.h | 51 ++++++++++++---------------------- test/test-arraylist.c | 51 ++++++++++++---------------------- test/test-avl-tree.c | 51 ++++++++++++---------------------- test/test-binary-heap.c | 51 ++++++++++++---------------------- test/test-binomial-heap.c | 51 ++++++++++++---------------------- test/test-bloom-filter.c | 51 ++++++++++++---------------------- test/test-compare-functions.c | 51 ++++++++++++---------------------- test/test-hash-functions.c | 51 ++++++++++++---------------------- test/test-hash-table.c | 51 ++++++++++++---------------------- test/test-list.c | 51 ++++++++++++---------------------- test/test-queue.c | 51 ++++++++++++---------------------- test/test-set.c | 51 ++++++++++++---------------------- test/test-slist.c | 51 ++++++++++++---------------------- test/test-trie.c | 51 ++++++++++++---------------------- 53 files changed, 898 insertions(+), 1676 deletions(-) diff --git a/COPYING b/COPYING index 67e1d3d..5136703 100644 --- a/COPYING +++ b/COPYING @@ -1,30 +1,17 @@ -Copyright (c) 2005, Simon Howard -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: +Copyright (c) 2005-2008, Simon Howard - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README b/README index b4a4fbb..65aa54b 100644 --- a/README +++ b/README @@ -5,6 +5,7 @@ The C programming language includes a very limited standard library in comparison to other modern programming languages. This is a collection of common Computer Science algorithms which may be used in C projects. -The code is licensed under the Modified BSD license, and as a result -may be reused in any project, whether Proprietary or Open Source. +The code is licensed under the ISC license (a simplified version of the +Modified BSD license). As such, it may legitimately be reused in any +project, whether Proprietary or Open Source. diff --git a/doc/intro.h b/doc/intro.h index 415d737..95fbb82 100644 --- a/doc/intro.h +++ b/doc/intro.h @@ -1,36 +1,22 @@ /* - -Copyright (c) 2005, Simon Howard -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: +Copyright (c) 2005-2008, Simon Howard - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ + */ /* This file is a dummy header which is used to generate the * introduction in Doxygen. */ @@ -45,8 +31,9 @@ POSSIBILITY OF SUCH DAMAGE. * of common Computer Science data structures and algorithms which may be * used in C projects. * - * The code is licensed under the Modified BSD license, and as a result - * may be reused in any project, whether Proprietary or Open Source. + * The code is licensed under the ISC license (a simplified version + * of the Modified BSD license). As such, it may be reused in any + * project, whether Proprietary or Open Source. * * @section Data_structures Data structures * diff --git a/src/arraylist.c b/src/arraylist.c index b29af7b..3616f57 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/src/arraylist.h b/src/arraylist.h index 5e3f52d..b0ce8a1 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file arraylist.h diff --git a/src/avl-tree.c b/src/avl-tree.c index b969f20..6d1e8c8 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include diff --git a/src/avl-tree.h b/src/avl-tree.h index 774e55c..7dcc531 100644 --- a/src/avl-tree.h +++ b/src/avl-tree.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** @file avl-tree.h * diff --git a/src/binary-heap.c b/src/binary-heap.c index dfcca24..351480f 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include diff --git a/src/binary-heap.h b/src/binary-heap.h index b10e363..36718aa 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file binary-heap.h diff --git a/src/binomial-heap.c b/src/binomial-heap.c index 5373c8b..d12649a 100644 --- a/src/binomial-heap.c +++ b/src/binomial-heap.c @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/src/binomial-heap.h b/src/binomial-heap.h index d499bda..24c9fa4 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file binomial-heap.h diff --git a/src/bloom-filter.c b/src/bloom-filter.c index ed1cb55..1a1604a 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/src/bloom-filter.h b/src/bloom-filter.h index 24833d3..ae20a3d 100644 --- a/src/bloom-filter.h +++ b/src/bloom-filter.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file bloom-filter.h diff --git a/src/compare-int.c b/src/compare-int.c index 4d2b075..38805e5 100644 --- a/src/compare-int.c +++ b/src/compare-int.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: +Copyright (c) 2005-2008, Simon Howard - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ + */ #include "compare-int.h" diff --git a/src/compare-int.h b/src/compare-int.h index abfac06..22269df 100644 --- a/src/compare-int.h +++ b/src/compare-int.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: +Copyright (c) 2005-2008, Simon Howard - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ + */ /** * @file compare-int.h diff --git a/src/compare-pointer.c b/src/compare-pointer.c index 3850530..94e1b28 100644 --- a/src/compare-pointer.c +++ b/src/compare-pointer.c @@ -1,38 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include "compare-pointer.h" diff --git a/src/compare-pointer.h b/src/compare-pointer.h index 005f3b0..28a4009 100644 --- a/src/compare-pointer.h +++ b/src/compare-pointer.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: +Copyright (c) 2005-2008, Simon Howard - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ + */ /** * @file compare-pointer.h diff --git a/src/compare-string.c b/src/compare-string.c index 4a2fa52..5d0e66c 100644 --- a/src/compare-string.c +++ b/src/compare-string.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/src/compare-string.h b/src/compare-string.h index 2cfbf1f..51826a4 100644 --- a/src/compare-string.h +++ b/src/compare-string.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file compare-string.h diff --git a/src/hash-int.c b/src/hash-int.c index 58f533e..1cfd660 100644 --- a/src/hash-int.c +++ b/src/hash-int.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include "hash-int.h" diff --git a/src/hash-int.h b/src/hash-int.h index 2873c63..3babc81 100644 --- a/src/hash-int.h +++ b/src/hash-int.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: +Copyright (c) 2005-2008, Simon Howard - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ + */ /** * @file hash-int.h diff --git a/src/hash-pointer.c b/src/hash-pointer.c index 44f8305..3585ccc 100644 --- a/src/hash-pointer.c +++ b/src/hash-pointer.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include "hash-pointer.h" diff --git a/src/hash-pointer.h b/src/hash-pointer.h index 515540c..82660b0 100644 --- a/src/hash-pointer.h +++ b/src/hash-pointer.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: +Copyright (c) 2005-2008, Simon Howard - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ + */ /** * @file hash-pointer.h diff --git a/src/hash-string.c b/src/hash-string.c index 4a8d109..b524098 100644 --- a/src/hash-string.c +++ b/src/hash-string.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include diff --git a/src/hash-string.h b/src/hash-string.h index 6d37e1d..12f3de1 100644 --- a/src/hash-string.h +++ b/src/hash-string.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: +Copyright (c) 2005-2008, Simon Howard - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ + */ /** * @file hash-string.h diff --git a/src/hash-table.c b/src/hash-table.c index 8782640..cc0b8b7 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /* Hash table implementation */ diff --git a/src/hash-table.h b/src/hash-table.h index 1fa3c5e..e4f6e35 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file hash-table.h diff --git a/src/libcalg.h b/src/libcalg.h index 02af015..e1c22d4 100644 --- a/src/libcalg.h +++ b/src/libcalg.h @@ -1,38 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #ifndef LIBCALG_H #define LIBCALG_H diff --git a/src/list.c b/src/list.c index c05c654..8fb4cd1 100644 --- a/src/list.c +++ b/src/list.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include diff --git a/src/list.h b/src/list.h index b13413f..7530405 100644 --- a/src/list.h +++ b/src/list.h @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file list.h diff --git a/src/queue.c b/src/queue.c index ce6b069..4a94b6e 100644 --- a/src/queue.c +++ b/src/queue.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include diff --git a/src/queue.h b/src/queue.h index 3c9f6da..5dbcad8 100644 --- a/src/queue.h +++ b/src/queue.h @@ -1,38 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file queue.h diff --git a/src/set.c b/src/set.c index 6523ba7..fe7430d 100644 --- a/src/set.c +++ b/src/set.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/src/set.h b/src/set.h index b266508..5a90d7d 100644 --- a/src/set.h +++ b/src/set.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file set.h diff --git a/src/slist.c b/src/slist.c index 5b6c4e8..f588ebc 100644 --- a/src/slist.c +++ b/src/slist.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include diff --git a/src/slist.h b/src/slist.h index 9b0b9e7..c66c126 100644 --- a/src/slist.h +++ b/src/slist.h @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file slist.h diff --git a/src/trie.c b/src/trie.c index 7493dd8..51a7801 100644 --- a/src/trie.c +++ b/src/trie.c @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /* Trie: fast mapping of strings to values */ diff --git a/src/trie.h b/src/trie.h index 38c90a5..7b0525e 100644 --- a/src/trie.h +++ b/src/trie.h @@ -1,37 +1,22 @@ - /* -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file trie.h diff --git a/test/alloc-testing.c b/test/alloc-testing.c index f8ac378..df75ec7 100644 --- a/test/alloc-testing.c +++ b/test/alloc-testing.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/alloc-testing.h b/test/alloc-testing.h index 57223e1..57eddf5 100644 --- a/test/alloc-testing.h +++ b/test/alloc-testing.h @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2008, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /** * @file alloc-testing.h diff --git a/test/test-arraylist.c b/test/test-arraylist.c index e96d43b..a2b407f 100644 --- a/test/test-arraylist.c +++ b/test/test-arraylist.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /* ArrayList test cases */ diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index c955291..1a571af 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-binary-heap.c b/test/test-binary-heap.c index de062d5..d8bec3d 100644 --- a/test/test-binary-heap.c +++ b/test/test-binary-heap.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-binomial-heap.c b/test/test-binomial-heap.c index 1e4d2b5..7199bc6 100644 --- a/test/test-binomial-heap.c +++ b/test/test-binomial-heap.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binomial forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binomial form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-bloom-filter.c b/test/test-bloom-filter.c index 87a8633..8d74949 100644 --- a/test/test-bloom-filter.c +++ b/test/test-bloom-filter.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2006, Simon Howard -All rights reserved. - -Redistribution and use in source and binomial forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binomial form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-compare-functions.c b/test/test-compare-functions.c index 563426c..e95f0f8 100644 --- a/test/test-compare-functions.c +++ b/test/test-compare-functions.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ /* Test cases for compare functions */ diff --git a/test/test-hash-functions.c b/test/test-hash-functions.c index 44ce7f0..a8c90af 100644 --- a/test/test-hash-functions.c +++ b/test/test-hash-functions.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-hash-table.c b/test/test-hash-table.c index b7a4466..98a4b52 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-list.c b/test/test-list.c index c9d38a4..a50a72d 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-queue.c b/test/test-queue.c index 9cbbd2a..a2063a6 100644 --- a/test/test-queue.c +++ b/test/test-queue.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-set.c b/test/test-set.c index 31de6ff..ddd0beb 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-slist.c b/test/test-slist.c index 1f15457..adfe403 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include diff --git a/test/test-trie.c b/test/test-trie.c index 68f45ab..7079ffa 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -1,37 +1,22 @@ - /* - -Copyright (c) 2005, Simon Howard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the C Algorithms project nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ #include #include From 714419a20aea2846d29ec2cc7183fb62ce0086ac Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 13 Jun 2008 16:47:20 +0000 Subject: [PATCH 079/250] Add check for failed malloc(). --- src/binomial-heap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/binomial-heap.c b/src/binomial-heap.c index d12649a..ee8b090 100644 --- a/src/binomial-heap.c +++ b/src/binomial-heap.c @@ -131,6 +131,12 @@ static BinomialTree *binomial_tree_merge(BinomialHeap *heap, * array is the larger tree */ new_tree->subtrees = malloc(sizeof(BinomialTree *) * new_tree->order); + + if (new_tree->subtrees == NULL) { + free(new_tree); + return NULL; + } + memcpy(new_tree->subtrees, tree1->subtrees, sizeof(BinomialTree *) * tree1->order); new_tree->subtrees[new_tree->order - 1] = tree2; From 0daa32d9470ed59be92b9ca084f4cf5d8fffc1df Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 13 Jun 2008 17:59:14 +0000 Subject: [PATCH 080/250] Add missing test framework files. --- test/framework.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ test/framework.h | 47 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 test/framework.c create mode 100644 test/framework.h diff --git a/test/framework.c b/test/framework.c new file mode 100644 index 0000000..469f388 --- /dev/null +++ b/test/framework.c @@ -0,0 +1,56 @@ +/* + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +#include +#include + +#include + +#include "alloc-testing.h" +#include "framework.h" + +/* Run a single test. */ + +static void run_test(UnitTestFunction test) +{ + /* Turn off any allocation limits that may have been set + * by a previous test. */ + + alloc_test_set_limit(-1); + + /* Run the test */ + + test(); + + /* Check that all memory was correctly freed back during + * the test. */ + + assert(alloc_test_get_allocated() == 0); +} + +void run_tests(UnitTestFunction *tests) +{ + int i; + + for (i=0; tests[i] != NULL; ++i) { + run_test(tests[i]); + } +} + diff --git a/test/framework.h b/test/framework.h new file mode 100644 index 0000000..5901e22 --- /dev/null +++ b/test/framework.h @@ -0,0 +1,47 @@ +/* + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +#ifndef TEST_FRAMEWORK_H +#define TEST_FRAMEWORK_H + +/** + * @file framework.h + * + * @brief Framework for running unit tests. + */ + +/** + * A unit test. + */ + +typedef void (*UnitTestFunction)(void); + +/** + * Run a list of unit tests. The provided array contains a list of + * pointers to test functions to invoke; the last entry is denoted + * by a NULL pointer. + * + * @param tests List of tests to invoke. + */ + +void run_tests(UnitTestFunction *tests); + +#endif /* #ifndef TEST_FRAMEWORK_H */ + From f75decbb225abba45fc9242dd81390e50409231d Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 13 Jun 2008 18:39:49 +0000 Subject: [PATCH 081/250] Add copyright header to valgrind wrapper script. --- test/valgrind-wrapper | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/valgrind-wrapper b/test/valgrind-wrapper index 030a77c..7b98324 100755 --- a/test/valgrind-wrapper +++ b/test/valgrind-wrapper @@ -1,4 +1,21 @@ #!/bin/sh +# +# Copyright (c) 2008, Simon Howard +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# # Run in valgrind, with leak checking enabled From a2d6518c60b78d849478d7988c22c917e7e0030d Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 13 Jun 2008 18:49:53 +0000 Subject: [PATCH 082/250] Fix bugs in AVL tree. --- src/avl-tree.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/avl-tree.c b/src/avl-tree.c index 6d1e8c8..fdfd838 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -274,7 +274,7 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) /* Biased toward the right side too much. */ if (avl_tree_subtree_height(node->right_child->right_child) - <= avl_tree_subtree_height(node->right_child->left_child)) { + < avl_tree_subtree_height(node->right_child->left_child)) { /* If the right child is biased toward the left * side, it must be rotated right first (double @@ -298,7 +298,7 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) /* Biased toward the left side too much. */ if (avl_tree_subtree_height(node->left_child->left_child) - <= avl_tree_subtree_height(node->left_child->right_child)) { + < avl_tree_subtree_height(node->left_child->right_child)) { /* If the left child is biased toward the right * side, it must be rotated right left (double @@ -455,7 +455,7 @@ void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) /* This is a leaf node and has no children, therefore * it can be immediately removed. */ - /* Unlink this node from its parent */ + /* Unlink this node from its parent and update tree height */ if (node->parent != NULL) { if (node->parent->left_child == node) { @@ -463,6 +463,8 @@ void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) } else { node->parent->right_child = NULL; } + + avl_tree_update_height(node->parent); } else { /* Root node */ @@ -472,22 +474,38 @@ void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) /* "swap" stage is skipped. */ swap_node = NULL; + } - /* Start balancing from the node's parent */ + /* Calculate where we will need to start rebalancing the tree. + * If it was a leaf node, start from the parent of the node + * we are removing. Otherwise, use the old parent of the node we + * swapped out. In some cases this is the node we are swapping + * back in again. */ + if (swap_node == NULL) { balance_startpoint = node->parent; + } else if (swap_node->parent == node) { + balance_startpoint = swap_node; + } else { + balance_startpoint = swap_node->parent; } /* Link the "swap" node into the tree, at the position where * "node" previously was. */ if (swap_node != NULL) { - + + /* Update the subtree height for the swap node's old + * parent. */ + + avl_tree_update_height(swap_node->parent); + /* Copy references in the node into the swap node */ swap_node->left_child = node->left_child; swap_node->right_child = node->right_child; swap_node->parent = node->parent; + swap_node->height = node->height; /* Link the parent's reference to this node */ @@ -512,10 +530,6 @@ void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) if (node->right_child != NULL) { node->right_child->parent = swap_node; } - - /* Start balancing from the swap node's former parent */ - - balance_startpoint = swap_node->parent; } /* Destroy the node */ From e7ab76ddf19204746584641de166f9ee7f555e48 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 13 Jun 2008 18:53:23 +0000 Subject: [PATCH 083/250] Improve avl_tree_remove_node testing function. --- test/test-avl-tree.c | 60 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index 1a571af..93b2cff 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -30,6 +30,31 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. int test_array[1000]; +#if 0 +/* Tree print function - useful for debugging. */ + +static void print_tree(AVLTreeNode *node, int depth) +{ + int *value; + int i; + + if (node == NULL) { + return; + } + + print_tree(avl_tree_node_left_child(node), depth + 1); + + for (i=0; i Date: Fri, 13 Jun 2008 19:13:12 +0000 Subject: [PATCH 084/250] Add more AVL tree tests. --- test/test-avl-tree.c | 172 +++++++++++++++++++++++++++++++------------ 1 file changed, 125 insertions(+), 47 deletions(-) diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index 93b2cff..5f80e04 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -35,23 +35,23 @@ int test_array[1000]; static void print_tree(AVLTreeNode *node, int depth) { - int *value; - int i; + int *value; + int i; - if (node == NULL) { - return; - } + if (node == NULL) { + return; + } - print_tree(avl_tree_node_left_child(node), depth + 1); + print_tree(avl_tree_node_left_child(node), depth + 1); - for (i=0; i Date: Fri, 13 Jun 2008 19:53:19 +0000 Subject: [PATCH 085/250] Allow allocations to reach the limit, but not exceed it. --- test/alloc-testing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/alloc-testing.c b/test/alloc-testing.c index df75ec7..158d245 100644 --- a/test/alloc-testing.c +++ b/test/alloc-testing.c @@ -88,7 +88,7 @@ static BlockHeader *alloc_test_get_header(void *ptr) static int alloc_test_new_size_allowed(size_t new_size) { return allocation_limit < 0 - || new_size < allocation_limit; + || new_size <= allocation_limit; } /* Overwrite a block of memory with a repeated pattern. */ From 4085783905410cfe6bdd2bffe1b786b635eefa1e Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 13 Jun 2008 19:54:17 +0000 Subject: [PATCH 086/250] More bloom filter and linked list tests. --- test/test-bloom-filter.c | 78 ++++++++++++++++++++++++++++++++++++++-- test/test-list.c | 18 +++++++++- 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/test/test-bloom-filter.c b/test/test-bloom-filter.c index 8d74949..4d41a14 100644 --- a/test/test-bloom-filter.c +++ b/test/test-bloom-filter.c @@ -32,17 +32,41 @@ void test_bloom_filter_new_free(void) { BloomFilter *filter; + /* One salt */ + filter = bloom_filter_new(128, string_hash, 1); assert(filter != NULL); bloom_filter_free(filter); + /* Maximum number of salts */ + filter = bloom_filter_new(128, string_hash, 64); assert(filter != NULL); bloom_filter_free(filter); + + /* Test creation with too many salts */ + + filter = bloom_filter_new(128, string_hash, 50000); + + assert(filter == NULL); + + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + + filter = bloom_filter_new(128, string_hash, 1); + + assert(filter == NULL); + + alloc_test_set_limit(sizeof(void *) * 4); + + filter = bloom_filter_new(128, string_hash, 1); + + assert(filter == NULL); } void test_bloom_filter_insert_query(void) @@ -139,9 +163,16 @@ void test_bloom_filter_intersection(void) assert(bloom_filter_query(result, "test 1") != 0); assert(bloom_filter_query(result, "test 2") == 0); + bloom_filter_free(result); + + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + result = bloom_filter_intersection(filter1, filter2); + assert(result == NULL); + bloom_filter_free(filter1); bloom_filter_free(filter2); - bloom_filter_free(result); } void test_bloom_filter_union(void) @@ -171,9 +202,51 @@ void test_bloom_filter_union(void) assert(bloom_filter_query(result, "test 1") != 0); assert(bloom_filter_query(result, "test 2") != 0); + bloom_filter_free(result); + + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + result = bloom_filter_union(filter1, filter2); + assert(result == NULL); + bloom_filter_free(filter1); bloom_filter_free(filter2); - bloom_filter_free(result); +} + +/* Test attempts to do union/intersection of mismatched filters */ + +void test_bloom_filter_mismatch(void) +{ + BloomFilter *filter1; + BloomFilter *filter2; + + /* Create one filter with both values set */ + + filter1 = bloom_filter_new(128, string_hash, 4); + + /* Different buffer size. */ + + filter2 = bloom_filter_new(64, string_hash, 4); + assert(bloom_filter_intersection(filter1, filter2) == NULL); + assert(bloom_filter_union(filter1, filter2) == NULL); + bloom_filter_free(filter2); + + /* Different hash function */ + + filter2 = bloom_filter_new(128, string_nocase_hash, 4); + assert(bloom_filter_intersection(filter1, filter2) == NULL); + assert(bloom_filter_union(filter1, filter2) == NULL); + bloom_filter_free(filter2); + + /* Different number of salts */ + + filter2 = bloom_filter_new(128, string_hash, 32); + assert(bloom_filter_intersection(filter1, filter2) == NULL); + assert(bloom_filter_union(filter1, filter2) == NULL); + bloom_filter_free(filter2); + + bloom_filter_free(filter1); } static UnitTestFunction tests[] = { @@ -182,6 +255,7 @@ static UnitTestFunction tests[] = { test_bloom_filter_read_load, test_bloom_filter_intersection, test_bloom_filter_union, + test_bloom_filter_mismatch, NULL }; diff --git a/test/test-list.c b/test/test-list.c index a50a72d..8548acb 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -254,7 +254,7 @@ void test_list_remove_entry(void) assert(list_remove_entry(&list, entry) != 0); assert(list_length(list) == 2); check_list_integrity(list); - + /* Try some invalid removes */ /* NULL */ @@ -266,6 +266,22 @@ void test_list_remove_entry(void) assert(list_remove_entry(&empty_list, NULL) == 0); list_free(list); + + /* Test removing an entry when it is the only entry. */ + + list = NULL; + assert(list_append(&list, &variable1) != NULL); + assert(list != NULL); + assert(list_remove_entry(&list, list) != 0); + assert(list == NULL); + + /* Test removing the last entry */ + + list = generate_list(); + entry = list_nth_entry(list, 3); + assert(list_remove_entry(&list, entry) != 0); + check_list_integrity(list); + list_free(list); } void test_list_remove_data(void) From 52b8960f40a08ba18bb828d715684fd0ffcd3a28 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 16 Jun 2008 19:20:52 +0000 Subject: [PATCH 087/250] Remove alloc testing linked list, as it is unused. --- test/alloc-testing.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/test/alloc-testing.c b/test/alloc-testing.c index 158d245..d3c9da8 100644 --- a/test/alloc-testing.c +++ b/test/alloc-testing.c @@ -53,13 +53,8 @@ typedef struct _BlockHeader BlockHeader; struct _BlockHeader { unsigned int magic_number; size_t bytes; - BlockHeader *prev, *next; }; -/* Head of a linked list of allocated blocks. */ - -static BlockHeader *allocated_blocks = NULL; - /* Count of the current number of allocated bytes. */ static size_t allocated_bytes = 0; @@ -128,16 +123,6 @@ BlockHeader *alloc_test_base_malloc(size_t bytes) header->magic_number = ALLOC_TEST_MAGIC; header->bytes = bytes; - /* Hook the new block into the linked list. */ - - header->prev = NULL; - header->next = allocated_blocks; - allocated_blocks = header; - - if (header->next != NULL) { - header->next->prev = header; - } - /* Fill memory with MALLOC_PATTERN, to ensure that code under test * does not rely on memory being initialised to zero. */ @@ -153,18 +138,6 @@ void alloc_test_base_free(BlockHeader *header) { void *ptr; - /* Unlink from the linked list. */ - - if (header->prev != NULL) { - header->prev->next = header->next; - } else { - allocated_blocks = header->next; - } - - if (header->next != NULL) { - header->next->prev = header->prev; - } - /* Trash the allocated block to foil any code that relies on memory * that has been freed. */ From 4d108b4fb4d1b7bcbf67c6eaa23b7bbddeb689ec Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 16 Jun 2008 19:24:09 +0000 Subject: [PATCH 088/250] Replace AVL tree node left/right child pointers with a two element array. Restructure remove_node function to be more obviously correct. --- src/avl-tree.c | 366 ++++++++++++++++++++----------------------- src/avl-tree.h | 28 ++-- test/test-avl-tree.c | 62 +++++++- 3 files changed, 241 insertions(+), 215 deletions(-) diff --git a/src/avl-tree.c b/src/avl-tree.c index fdfd838..b12d3d7 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -31,8 +31,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* AVL Tree (balanced binary search tree) */ struct _AVLTreeNode { - AVLTreeNode *left_child; - AVLTreeNode *right_child; + AVLTreeNode *children[2]; AVLTreeNode *parent; AVLTreeKey key; AVLTreeValue value; @@ -68,8 +67,8 @@ static void avl_tree_free_subtree(AVLTree *tree, AVLTreeNode *node) return; } - avl_tree_free_subtree(tree, node->left_child); - avl_tree_free_subtree(tree, node->right_child); + avl_tree_free_subtree(tree, node->children[AVL_TREE_NODE_LEFT]); + avl_tree_free_subtree(tree, node->children[AVL_TREE_NODE_RIGHT]); free(node); } @@ -100,10 +99,14 @@ int avl_tree_subtree_height(AVLTreeNode *node) static void avl_tree_update_height(AVLTreeNode *node) { + AVLTreeNode *left_subtree; + AVLTreeNode *right_subtree; int left_height, right_height; - left_height = avl_tree_subtree_height(node->left_child); - right_height = avl_tree_subtree_height(node->right_child); + left_subtree = node->children[AVL_TREE_NODE_LEFT]; + right_subtree = node->children[AVL_TREE_NODE_RIGHT]; + left_height = avl_tree_subtree_height(left_subtree); + right_height = avl_tree_subtree_height(right_subtree); if (left_height > right_height) { node->height = left_height + 1; @@ -112,6 +115,42 @@ static void avl_tree_update_height(AVLTreeNode *node) } } +/* Find what side a node is relative to its parent */ + +AVLTreeNodeSide avl_tree_node_parent_side(AVLTreeNode *node) +{ + if (node->parent->children[AVL_TREE_NODE_LEFT] == node) { + return AVL_TREE_NODE_LEFT; + } else { + return AVL_TREE_NODE_RIGHT; + } +} + +/* Replace node1 with node2 at its parent. */ + +static void avl_tree_node_replace(AVLTree *tree, AVLTreeNode *node1, + AVLTreeNode *node2) +{ + int side; + + /* Set the node's parent pointer. */ + + if (node2 != NULL) { + node2->parent = node1->parent; + } + + /* The root node? */ + + if (node1->parent == NULL) { + tree->root_node = node2; + } else { + side = avl_tree_node_parent_side(node1); + node1->parent->children[side] = node2; + + avl_tree_update_height(node1->parent); + } +} + /* Rotate a section of the tree left. 'node' is the node at the top * of the section to be rotated. * @@ -132,48 +171,27 @@ static void avl_tree_update_height(AVLTreeNode *node) static void avl_tree_rotate_left(AVLTree *tree, AVLTreeNode *node) { - AVLTreeNode *parent; AVLTreeNode *new_root; - parent = node->parent; - /* The right child will take the place of this node */ - new_root = node->right_child; + new_root = node->children[AVL_TREE_NODE_RIGHT]; - /* Make new_root the root */ + /* Make new_root the root, update parent pointers. */ - new_root->parent = parent; - - if (parent == NULL) { - - /* No parent means this is the root of the entire tree */ - - tree->root_node = new_root; - - } else { - - /* Either the left or right child pointer points into this - * section */ - - if (parent->left_child == node) { - parent->left_child = new_root; - } else { - parent->right_child = new_root; - } - } + avl_tree_node_replace(tree, node, new_root); /* Rearrange pointers */ - node->right_child = new_root->left_child; - new_root->left_child = node; + node->children[AVL_TREE_NODE_RIGHT] = new_root->children[AVL_TREE_NODE_LEFT]; + new_root->children[AVL_TREE_NODE_LEFT] = node; /* Update parent references */ node->parent = new_root; - if (node->right_child != NULL) { - node->right_child->parent = node; + if (node->children[AVL_TREE_NODE_RIGHT] != NULL) { + node->children[AVL_TREE_NODE_RIGHT]->parent = node; } /* Update heights of the affected nodes */ @@ -202,48 +220,27 @@ static void avl_tree_rotate_left(AVLTree *tree, AVLTreeNode *node) static void avl_tree_rotate_right(AVLTree *tree, AVLTreeNode *node) { - AVLTreeNode *parent; AVLTreeNode *new_root; - parent = node->parent; - /* The left child will now take the place of this node */ - new_root = node->left_child; + new_root = node->children[AVL_TREE_NODE_LEFT]; - /* Make new_root the root */ + /* Make new_root the root, update parent pointers. */ - new_root->parent = parent; - - if (parent == NULL) { - - /* No parent means this is the root of the entire tree */ - - tree->root_node = new_root; - - } else { - - /* Either the left or right child pointer points into this - * section */ - - if (parent->left_child == node) { - parent->left_child = new_root; - } else { - parent->right_child = new_root; - } - } + avl_tree_node_replace(tree, node, new_root); /* Rearrange pointers */ - node->left_child = new_root->right_child; - new_root->right_child = node; + node->children[AVL_TREE_NODE_LEFT] = new_root->children[AVL_TREE_NODE_RIGHT]; + new_root->children[AVL_TREE_NODE_RIGHT] = node; /* Update parent references */ node->parent = new_root; - if (node->left_child != NULL) { - node->left_child->parent = node; + if (node->children[AVL_TREE_NODE_LEFT] != NULL) { + node->children[AVL_TREE_NODE_LEFT]->parent = node; } /* Update heights of the affected nodes */ @@ -259,35 +256,43 @@ static void avl_tree_rotate_right(AVLTree *tree, AVLTreeNode *node) static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) { + AVLTreeNode *left_subtree; + AVLTreeNode *right_subtree; AVLTreeNode *new_root; + AVLTreeNode *child; int diff; + left_subtree = node->children[AVL_TREE_NODE_LEFT]; + right_subtree = node->children[AVL_TREE_NODE_RIGHT]; + /* Check the heights of the child trees. If there is an unbalance * (difference between left and right > 2), then rotate nodes * around to fix it */ - diff = avl_tree_subtree_height(node->right_child) - - avl_tree_subtree_height(node->left_child); + diff = avl_tree_subtree_height(right_subtree) + - avl_tree_subtree_height(left_subtree); if (diff >= 2) { /* Biased toward the right side too much. */ - if (avl_tree_subtree_height(node->right_child->right_child) - < avl_tree_subtree_height(node->right_child->left_child)) { + child = right_subtree; + + if (avl_tree_subtree_height(child->children[AVL_TREE_NODE_RIGHT]) + < avl_tree_subtree_height(child->children[AVL_TREE_NODE_LEFT])) { /* If the right child is biased toward the left * side, it must be rotated right first (double * rotation) */ - avl_tree_rotate_right(tree, node->right_child); + avl_tree_rotate_right(tree, right_subtree); } /* Perform a left rotation. After this, the right child will * take the place of this node. Store a pointer to the right * child so that we can continue where we left off. */ - new_root = node->right_child; + new_root = node->children[AVL_TREE_NODE_RIGHT]; avl_tree_rotate_left(tree, node); @@ -297,21 +302,23 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) /* Biased toward the left side too much. */ - if (avl_tree_subtree_height(node->left_child->left_child) - < avl_tree_subtree_height(node->left_child->right_child)) { + child = node->children[AVL_TREE_NODE_LEFT]; + + if (avl_tree_subtree_height(child->children[AVL_TREE_NODE_LEFT]) + < avl_tree_subtree_height(child->children[AVL_TREE_NODE_RIGHT])) { /* If the left child is biased toward the right * side, it must be rotated right left (double * rotation) */ - avl_tree_rotate_left(tree, node->left_child); + avl_tree_rotate_left(tree, left_subtree); } /* Perform a right rotation. After this, the left child * will take the place of this node. Store a pointer to the * left child so that we can continue where we left off. */ - new_root = node->left_child; + new_root = node->children[AVL_TREE_NODE_LEFT]; avl_tree_rotate_right(tree, node); @@ -340,9 +347,9 @@ AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) while (*rover != NULL) { previous_node = *rover; if (tree->compare_func(key, (*rover)->key) < 0) { - rover = &((*rover)->left_child); + rover = &((*rover)->children[AVL_TREE_NODE_LEFT]); } else { - rover = &((*rover)->right_child); + rover = &((*rover)->children[AVL_TREE_NODE_RIGHT]); } } @@ -354,8 +361,8 @@ AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) return NULL; } - new_node->left_child = NULL; - new_node->right_child = NULL; + new_node->children[AVL_TREE_NODE_LEFT] = NULL; + new_node->children[AVL_TREE_NODE_RIGHT] = NULL; new_node->parent = previous_node; new_node->key = key; new_node->value = value; @@ -387,149 +394,117 @@ AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) return new_node; } -/* Remove a node from a tree */ +/* Find the nearest node to the given node, to replace it. + * The node returned is unlinked from the tree. + * Returns NULL if the node has no children. */ -void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) +static AVLTreeNode *avl_tree_node_get_replacement(AVLTree *tree, + AVLTreeNode *node) { - AVLTreeNode *swap_node; - AVLTreeNode *rover; - AVLTreeNode *balance_startpoint; - - /* The node to be removed must be swapped with an "adjacent" - * node, ie. one which has the closest key to this one. Find - * a node to swap with. */ + AVLTreeNode *left_subtree; + AVLTreeNode *right_subtree; + AVLTreeNode *result; + AVLTreeNode *child; + int left_height, right_height; + int side; - if (node->left_child != NULL) { + left_subtree = node->children[AVL_TREE_NODE_LEFT]; + right_subtree = node->children[AVL_TREE_NODE_RIGHT]; - /* Search for the right-most node in the left subtree, ie. - * the greatest value. */ + /* No children? */ - swap_node = node->left_child; + if (left_subtree == NULL && right_subtree == NULL) { + return NULL; + } - while (swap_node->right_child != NULL) { - swap_node = swap_node->right_child; - } + /* Pick a node from whichever subtree is taller. This helps to + * keep the tree balanced. */ - /* Unlink the swap node, move the swap node's left - * child tree in to replace it */ + left_height = avl_tree_subtree_height(left_subtree); + right_height = avl_tree_subtree_height(right_subtree); - if (swap_node->parent->right_child == swap_node) { - swap_node->parent->right_child - = swap_node->left_child; - } else { - swap_node->parent->left_child - = swap_node->left_child; - } + if (left_height < right_height) { + side = AVL_TREE_NODE_RIGHT; + } else { + side = AVL_TREE_NODE_LEFT; + } + + /* Search down the tree, back towards the center. */ - if (swap_node->left_child != NULL) { - swap_node->left_child->parent = swap_node->parent; - } + result = node->children[side]; - } else if (node->right_child != NULL) { + while (result->children[1-side] != NULL) { + result = result->children[1-side]; + } - /* Search for the left-most node in the right subtree, ie. - * the least value. */ + /* Unlink the result node, and hook in its remaining child + * (if it has one) to replace it. */ + + child = result->children[side]; + avl_tree_node_replace(tree, result, child); - swap_node = node->right_child; + /* Update the subtree height for the result node's old parent. */ - while (swap_node->left_child != NULL) { - swap_node = swap_node->left_child; - } + avl_tree_update_height(result->parent); - /* Unlink the swap node, move the swap node's right - * child tree in to replace it */ + return result; +} - if (swap_node->parent->left_child == swap_node) { - swap_node->parent->left_child - = swap_node->right_child; - } else { - swap_node->parent->right_child - = swap_node->right_child; - } +/* Remove a node from a tree */ - if (swap_node->right_child != NULL) { - swap_node->right_child->parent = swap_node->parent; - } +void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) +{ + AVLTreeNode *swap_node; + AVLTreeNode *rover; + AVLTreeNode *balance_startpoint; + int i; - } else { - /* This is a leaf node and has no children, therefore - * it can be immediately removed. */ + /* The node to be removed must be swapped with an "adjacent" + * node, ie. one which has the closest key to this one. Find + * a node to swap with. */ - /* Unlink this node from its parent and update tree height */ + swap_node = avl_tree_node_get_replacement(tree, node); - if (node->parent != NULL) { - if (node->parent->left_child == node) { - node->parent->left_child = NULL; - } else { - node->parent->right_child = NULL; - } + if (swap_node == NULL) { - avl_tree_update_height(node->parent); - } else { - /* Root node */ + /* This is a leaf node and has no children, therefore + * it can be immediately removed. */ - tree->root_node = NULL; - } - - /* "swap" stage is skipped. */ + /* Unlink this node from its parent. */ - swap_node = NULL; - } + avl_tree_node_replace(tree, node, NULL); - /* Calculate where we will need to start rebalancing the tree. - * If it was a leaf node, start from the parent of the node - * we are removing. Otherwise, use the old parent of the node we - * swapped out. In some cases this is the node we are swapping - * back in again. */ + /* Start rebalancing from the parent of the original node */ - if (swap_node == NULL) { balance_startpoint = node->parent; - } else if (swap_node->parent == node) { - balance_startpoint = swap_node; - } else { - balance_startpoint = swap_node->parent; - } - - /* Link the "swap" node into the tree, at the position where - * "node" previously was. */ - if (swap_node != NULL) { - - /* Update the subtree height for the swap node's old - * parent. */ + } else { + /* We will start rebalancing from the old parent of the + * swap node. Sometimes, the old parent is the node we + * are removing, in which case we must start rebalancing + * from the swap node. */ - avl_tree_update_height(swap_node->parent); + if (swap_node->parent == node) { + balance_startpoint = swap_node; + } else { + balance_startpoint = swap_node->parent; + } /* Copy references in the node into the swap node */ - swap_node->left_child = node->left_child; - swap_node->right_child = node->right_child; - swap_node->parent = node->parent; - swap_node->height = node->height; - - /* Link the parent's reference to this node */ + for (i=0; i<2; ++i) { + swap_node->children[i] = node->children[i]; - if (node->parent != NULL) { - if (node->parent->left_child == node) { - node->parent->left_child = swap_node; - } else { - node->parent->right_child = swap_node; + if (swap_node->children[i] != NULL) { + swap_node->children[i]->parent = swap_node; } - } else { - /* Root of the tree */ - - tree->root_node = swap_node; } - /* Fix the "parent" references of child nodes */ + swap_node->height = node->height; - if (node->left_child != NULL) { - node->left_child->parent = swap_node; - } - - if (node->right_child != NULL) { - node->right_child->parent = swap_node; - } + /* Link the parent's reference to this node */ + + avl_tree_node_replace(tree, node, swap_node); } /* Destroy the node */ @@ -600,9 +575,9 @@ AVLTreeNode *avl_tree_lookup_node(AVLTree *tree, AVLTreeKey key) return node; } else if (diff < 0) { - node = node->left_child; + node = node->children[AVL_TREE_NODE_LEFT]; } else { - node = node->right_child; + node = node->children[AVL_TREE_NODE_RIGHT]; } } @@ -641,14 +616,13 @@ AVLTreeValue avl_tree_node_value(AVLTreeNode *node) return node->value; } -AVLTreeNode *avl_tree_node_left_child(AVLTreeNode *node) -{ - return node->left_child; -} - -AVLTreeNode *avl_tree_node_right_child(AVLTreeNode *node) +AVLTreeNode *avl_tree_node_child(AVLTreeNode *node, AVLTreeNodeSide side) { - return node->right_child; + if (side == AVL_TREE_NODE_LEFT || side == AVL_TREE_NODE_RIGHT) { + return node->children[side]; + } else { + return NULL; + } } AVLTreeNode *avl_tree_node_parent(AVLTreeNode *node) @@ -671,7 +645,8 @@ static void avl_tree_to_array_add_subtree(AVLTreeNode *subtree, /* Add left subtree first */ - avl_tree_to_array_add_subtree(subtree->left_child, array, index); + avl_tree_to_array_add_subtree(subtree->children[AVL_TREE_NODE_LEFT], + array, index); /* Add this node */ @@ -680,7 +655,8 @@ static void avl_tree_to_array_add_subtree(AVLTreeNode *subtree, /* Finally add right subtree */ - avl_tree_to_array_add_subtree(subtree->right_child, array, index); + avl_tree_to_array_add_subtree(subtree->children[AVL_TREE_NODE_RIGHT], + array, index); } AVLTreeValue *avl_tree_to_array(AVLTree *tree) diff --git a/src/avl-tree.h b/src/avl-tree.h index 7dcc531..853ed1b 100644 --- a/src/avl-tree.h +++ b/src/avl-tree.h @@ -97,6 +97,15 @@ typedef void *AVLTreeValue; typedef struct _AVLTreeNode AVLTreeNode; +/** + * An @ref AVLTreeNode can have left and right children. + */ + +typedef enum { + AVL_TREE_NODE_LEFT = 0, + AVL_TREE_NODE_RIGHT = 1 +} AVLTreeNodeSide; + /** * Type of function used to compare keys in an AVL tree. * @@ -219,24 +228,15 @@ AVLTreeKey avl_tree_node_key(AVLTreeNode *node); AVLTreeValue avl_tree_node_value(AVLTreeNode *node); /** - * Find the left child of a given tree node. - * - * @param node The tree node. - * @return The left child of the tree node, or NULL if the - * node has no left child. - */ - -AVLTreeNode *avl_tree_node_left_child(AVLTreeNode *node); - -/** - * Find the right child of a given tree node. + * Find the child of a given tree node. * * @param node The tree node. - * @return The right child of the tree node, or NULL if the - * node has no right child. + * @param side Which child node to get (left or right) + * @return The child of the tree node, or NULL if the + * node has no child on the given side. */ -AVLTreeNode *avl_tree_node_right_child(AVLTreeNode *node); +AVLTreeNode *avl_tree_node_child(AVLTreeNode *node, AVLTreeNodeSide); /** * Find the parent node of a given tree node. diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index 5f80e04..71a8477 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -42,7 +42,7 @@ static void print_tree(AVLTreeNode *node, int depth) return; } - print_tree(avl_tree_node_left_child(node), depth + 1); + print_tree(avl_tree_node_child(node, AVL_TREE_NODE_LEFT), depth + 1); for (i=0; i right_height) { return left_height + 1; @@ -87,8 +91,10 @@ int validate_subtree(AVLTreeNode *node) return 0; } - left_node = avl_tree_node_left_child(node); - right_node = avl_tree_node_right_child(node); + left_node = avl_tree_node_child(node, AVL_TREE_NODE_LEFT); + right_node = avl_tree_node_child(node, AVL_TREE_NODE_RIGHT); + left_height = find_subtree_height(left_node); + right_height = find_subtree_height(right_node); /* Check the parent references of the children */ @@ -230,6 +236,49 @@ void test_avl_tree_insert_lookup(void) avl_tree_free(tree); } +void test_avl_tree_child(void) +{ + AVLTree *tree; + AVLTreeNode *root; + AVLTreeNode *left; + AVLTreeNode *right; + int values[] = { 1, 2, 3 }; + int *p; + int i; + + /* Create a tree containing some values. Validate the + * tree is consistent at all stages. */ + + tree = avl_tree_new((AVLTreeCompareFunc) int_compare); + + for (i=0; i<3; ++i) { + avl_tree_insert(tree, &values[i], &values[i]); + } + + /* Check the tree */ + + root = avl_tree_root_node(tree); + p = avl_tree_node_value(root); + assert(*p == 2); + + left = avl_tree_node_child(root, AVL_TREE_NODE_LEFT); + p = avl_tree_node_value(left); + assert(*p == 1); + + right = avl_tree_node_child(root, AVL_TREE_NODE_RIGHT); + p = avl_tree_node_value(right); + assert(*p == 3); + + /* Check invalid values */ + + assert(avl_tree_node_child(root, -1) == NULL); + assert(avl_tree_node_child(root, 10000) == NULL); + assert(avl_tree_node_child(root, 2) == NULL); + assert(avl_tree_node_child(root, -100000) == NULL); + + avl_tree_free(tree); +} + void test_out_of_memory(void) { AVLTree *tree; @@ -386,6 +435,7 @@ void test_avl_tree_to_array(void) static UnitTestFunction tests[] = { test_avl_tree_new, test_avl_tree_free, + test_avl_tree_child, test_avl_tree_insert_lookup, test_avl_tree_lookup, test_avl_tree_remove, From 2f74a43ef68c045c8551a693e63f269b8182467f Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 16 Jun 2008 19:44:55 +0000 Subject: [PATCH 089/250] Combine rotate_left and rotate_right functions into a single rotate function. --- src/avl-tree.c | 117 +++++++++++++++---------------------------------- 1 file changed, 35 insertions(+), 82 deletions(-) diff --git a/src/avl-tree.c b/src/avl-tree.c index b12d3d7..23a3294 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -151,80 +151,37 @@ static void avl_tree_node_replace(AVLTree *tree, AVLTreeNode *node1, } } -/* Rotate a section of the tree left. 'node' is the node at the top - * of the section to be rotated. - * - * B - * / \ - * A D - * / \ - * C E +/* Rotate a section of the tree. 'node' is the node at the top + * of the section to be rotated. 'direction' is the direction in + * which to rotate the tree: left or right, as shown in the following + * diagram: * - * is rotated to: + * Left rotation: Right rotation: * - * D - * / \ - * B E - * / \ - * A C - */ - -static void avl_tree_rotate_left(AVLTree *tree, AVLTreeNode *node) -{ - AVLTreeNode *new_root; - - /* The right child will take the place of this node */ - - new_root = node->children[AVL_TREE_NODE_RIGHT]; - - /* Make new_root the root, update parent pointers. */ - - avl_tree_node_replace(tree, node, new_root); - - /* Rearrange pointers */ - - node->children[AVL_TREE_NODE_RIGHT] = new_root->children[AVL_TREE_NODE_LEFT]; - new_root->children[AVL_TREE_NODE_LEFT] = node; - - /* Update parent references */ - - node->parent = new_root; - - if (node->children[AVL_TREE_NODE_RIGHT] != NULL) { - node->children[AVL_TREE_NODE_RIGHT]->parent = node; - } - - /* Update heights of the affected nodes */ - - avl_tree_update_height(new_root); - avl_tree_update_height(node); -} - -/* Rotate a section of the tree right. 'node' is the node at the top - * of the section to be rotated. - * - * D - * / \ - * B E - * / \ - * A C - * - * is rotated to: + * B D + * / \ / \ + * A D B E + * / \ / \ + * C E A C + + * is rotated to: is rotated to: * - * B - * / \ - * A D - * / \ - * C E + * D B + * / \ / \ + * B E A D + * / \ / \ + * A C C E */ -static void avl_tree_rotate_right(AVLTree *tree, AVLTreeNode *node) +static AVLTreeNode *avl_tree_rotate(AVLTree *tree, AVLTreeNode *node, + AVLTreeNodeSide direction) { AVLTreeNode *new_root; - /* The left child will now take the place of this node */ + /* The child of this node will take its place: + for a left rotation, it is the right child, and vice versa. */ - new_root = node->children[AVL_TREE_NODE_LEFT]; + new_root = node->children[1-direction]; /* Make new_root the root, update parent pointers. */ @@ -232,23 +189,26 @@ static void avl_tree_rotate_right(AVLTree *tree, AVLTreeNode *node) /* Rearrange pointers */ - node->children[AVL_TREE_NODE_LEFT] = new_root->children[AVL_TREE_NODE_RIGHT]; - new_root->children[AVL_TREE_NODE_RIGHT] = node; + node->children[1-direction] = new_root->children[direction]; + new_root->children[direction] = node; /* Update parent references */ node->parent = new_root; - if (node->children[AVL_TREE_NODE_LEFT] != NULL) { - node->children[AVL_TREE_NODE_LEFT]->parent = node; + if (node->children[1-direction] != NULL) { + node->children[1-direction]->parent = node; } /* Update heights of the affected nodes */ avl_tree_update_height(new_root); avl_tree_update_height(node); + + return new_root; } + /* Balance a particular tree node. * * Returns the root node of the new subtree which is replacing the @@ -258,7 +218,6 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) { AVLTreeNode *left_subtree; AVLTreeNode *right_subtree; - AVLTreeNode *new_root; AVLTreeNode *child; int diff; @@ -285,18 +244,15 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) * side, it must be rotated right first (double * rotation) */ - avl_tree_rotate_right(tree, right_subtree); + avl_tree_rotate(tree, right_subtree, + AVL_TREE_NODE_RIGHT); } /* Perform a left rotation. After this, the right child will * take the place of this node. Store a pointer to the right * child so that we can continue where we left off. */ - new_root = node->children[AVL_TREE_NODE_RIGHT]; - - avl_tree_rotate_left(tree, node); - - node = new_root; + node = avl_tree_rotate(tree, node, AVL_TREE_NODE_LEFT); } else if (diff <= -2) { @@ -311,18 +267,15 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) * side, it must be rotated right left (double * rotation) */ - avl_tree_rotate_left(tree, left_subtree); + avl_tree_rotate(tree, left_subtree, + AVL_TREE_NODE_LEFT); } /* Perform a right rotation. After this, the left child * will take the place of this node. Store a pointer to the * left child so that we can continue where we left off. */ - new_root = node->children[AVL_TREE_NODE_LEFT]; - - avl_tree_rotate_right(tree, node); - - node = new_root; + node = avl_tree_rotate(tree, node, AVL_TREE_NODE_RIGHT); } /* Update the height of this node */ From 1288eb7951b32c89d2b1e60e3736c199311448fa Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 16 Jun 2008 20:37:27 +0000 Subject: [PATCH 090/250] Update comments, add rebalance to root function. --- src/avl-tree.c | 58 ++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/src/avl-tree.c b/src/avl-tree.c index 23a3294..695c031 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -249,8 +249,7 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) } /* Perform a left rotation. After this, the right child will - * take the place of this node. Store a pointer to the right - * child so that we can continue where we left off. */ + * take the place of this node. Update the node pointer. */ node = avl_tree_rotate(tree, node, AVL_TREE_NODE_LEFT); @@ -271,9 +270,8 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) AVL_TREE_NODE_LEFT); } - /* Perform a right rotation. After this, the left child - * will take the place of this node. Store a pointer to the - * left child so that we can continue where we left off. */ + /* Perform a right rotation. After this, the left child will + * take the place of this node. Update the node pointer. */ node = avl_tree_rotate(tree, node, AVL_TREE_NODE_RIGHT); } @@ -285,12 +283,31 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) return node; } +/* Walk up the tree from the given node, performing any needed rotations */ + +static void avl_tree_balance_to_root(AVLTree *tree, AVLTreeNode *node) +{ + AVLTreeNode *rover; + + rover = node; + + while (rover != NULL) { + + /* Balance this node if necessary */ + + rover = avl_tree_node_balance(tree, rover); + + /* Go to this node's parent */ + + rover = rover->parent; + } +} + AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) { AVLTreeNode **rover; AVLTreeNode *new_node; AVLTreeNode *previous_node; - AVLTreeNode *node; /* Walk down the tree until we reach a NULL pointer */ @@ -325,20 +342,9 @@ AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) *rover = new_node; - /* Walk up the tree performing any needed rotations */ + /* Rebalance the tree, starting from the previous node. */ - node = previous_node; - - while (node != NULL) { - - /* Balance this node if necessary */ - - node = avl_tree_node_balance(tree, node); - - /* Go to this node's parent */ - - node = node->parent; - } + avl_tree_balance_to_root(tree, previous_node); /* Keep track of the number of entries */ @@ -408,7 +414,6 @@ static AVLTreeNode *avl_tree_node_get_replacement(AVLTree *tree, void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) { AVLTreeNode *swap_node; - AVLTreeNode *rover; AVLTreeNode *balance_startpoint; int i; @@ -470,18 +475,7 @@ void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) /* Rebalance the tree */ - rover = balance_startpoint; - - while (rover != NULL) { - - /* Possibly rebalance this subtree */ - - rover = avl_tree_node_balance(tree, rover); - - /* Go to the node's parent */ - - rover = rover->parent; - } + avl_tree_balance_to_root(tree, balance_startpoint); } /* Remove a node by key */ From 7239adbb5d899bd6dbc12b658f6242eed717901b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 17 Jun 2008 21:10:58 +0000 Subject: [PATCH 091/250] Put coverage CFLAGS in COV_FLAGS rather than in main CFLAGS. --- configure.ac | 5 ++++- src/Makefile.am | 2 +- test/Makefile.am | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index ec9b25b..b1e2ce2 100644 --- a/configure.ac +++ b/configure.ac @@ -15,9 +15,11 @@ AC_ARG_ENABLE(coverage, [ --enable-coverage Enable coverage testing. ], [ coverage=yes ]) +COV_FLAGS="" + if [[ "$coverage" = "yes" ]]; then if [[ "$GCC" = "yes" ]]; then - CFLAGS="-fprofile-arcs -ftest-coverage $CFLAGS" + COV_FLAGS="-fprofile-arcs -ftest-coverage" else AC_MSG_ERROR([Can only enable coverage when using gcc.]) fi @@ -42,6 +44,7 @@ AM_CONDITIONAL(USE_VALGRIND, $use_valgrind) AM_CONFIG_HEADER(config.h:config.h.in) +AC_SUBST(COV_FLAGS) AC_SUBST(ac_aux_dir) AC_OUTPUT([ diff --git a/src/Makefile.am b/src/Makefile.am index 732d07c..bf83837 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c -libcalgtest_a_CFLAGS=-DALLOC_TESTING -I../test +libcalgtest_a_CFLAGS=$(COV_FLAGS) -DALLOC_TESTING -I../test libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) diff --git a/test/Makefile.am b/test/Makefile.am index f757ddb..38556d7 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -25,7 +25,7 @@ libtestframework_a_SOURCES=\ alloc-testing.c alloc-testing.h \ framework.c framework.h -AM_CFLAGS = -I../src -Wall +AM_CFLAGS = $(COV_FLAGS) -I../src -Wall LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a EXTRA_DIST=valgrind-wrapper From 8e31c3f9da93ebcbb20004661f56b4eee07a63f2 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 17 Jun 2008 21:11:48 +0000 Subject: [PATCH 092/250] Fix doxygen warnings. --- src/avl-tree.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/avl-tree.h b/src/avl-tree.h index 853ed1b..d5830ce 100644 --- a/src/avl-tree.h +++ b/src/avl-tree.h @@ -45,8 +45,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @ref avl_tree_lookup_node. * * Tree nodes can be queried using the - * @ref avl_tree_node_left_child, - * @ref avl_tree_node_right_child, + * @ref avl_tree_node_child, * @ref avl_tree_node_parent, * @ref avl_tree_node_key and * @ref avl_tree_node_value functions. @@ -236,7 +235,7 @@ AVLTreeValue avl_tree_node_value(AVLTreeNode *node); * node has no child on the given side. */ -AVLTreeNode *avl_tree_node_child(AVLTreeNode *node, AVLTreeNodeSide); +AVLTreeNode *avl_tree_node_child(AVLTreeNode *node, AVLTreeNodeSide side); /** * Find the parent node of a given tree node. From 88f9660452bf9db3b48b416ddec7a515b18db4c5 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 18 Jun 2008 00:36:26 +0000 Subject: [PATCH 093/250] Update Doxyfile to latest Doxygen. --- doc/Doxyfile | 1149 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1142 insertions(+), 7 deletions(-) diff --git a/doc/Doxyfile b/doc/Doxyfile index 0c35d27..26b6b85 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1,16 +1,91 @@ -# Doxyfile 1.4.4 +# Doxyfile 1.5.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + PROJECT_NAME = "C Algorithms" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# and Ukrainian. + OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ @@ -22,211 +97,1271 @@ ABBREVIATE_BRIEF = "The $name class" \ a \ an \ the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + STRIP_FROM_PATH = src/ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + INHERIT_DOCS = YES -DISTRIBUTE_GROUP_DOC = NO + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + FILE_VERSION_FILTER = + #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + WARN_LOGFILE = + #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -INPUT = intro.h ../src + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = intro.h \ + ../src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + FILE_PATTERNS = *.h -RECURSIVE = YES + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + FILTER_SOURCE_FILES = NO + #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + VERBATIM_HEADERS = NO + #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + IGNORE_PREFIX = + #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + GENERATE_HTMLHELP = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + TREEVIEW_WIDTH = 250 + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + LATEX_HIDE_INDICES = NO + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + RTF_EXTENSIONS_FILE = + #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + MAN_LINKS = YES + #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + XML_PROGRAMLISTING = YES + #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + GENERATE_AUTOGEN_DEF = NO + #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + PERLMOD_MAKEVAR_PREFIX = + #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + SKIP_FUNCTION_MACROS = YES + #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + PERL_PATH = /usr/bin/perl + #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + MAX_DOT_GRAPH_DEPTH = 1000 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is enabled by default, which results in a transparent +# background. Warning: Depending on the platform used, enabling this option +# may lead to badly anti-aliased labels on the edges of a graph (i.e. they +# become hard to read). + DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + DOT_CLEANUP = YES + #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + SEARCHENGINE = NO From 9c682615f6473c00e8999ff1a1b2869ccf92b6f4 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 19 Jun 2008 17:46:24 +0000 Subject: [PATCH 094/250] Add test cases for allocation testing framework. --- test/Makefile.am | 1 + test/test-alloc-testing.c | 276 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 277 insertions(+) create mode 100644 test/test-alloc-testing.c diff --git a/test/Makefile.am b/test/Makefile.am index 38556d7..b9b9157 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,6 +4,7 @@ TESTS_ENVIRONMENT=./valgrind-wrapper endif TESTS = \ + test-alloc-testing \ test-arraylist \ test-avl-tree \ test-binary-heap \ diff --git a/test/test-alloc-testing.c b/test/test-alloc-testing.c new file mode 100644 index 0000000..7b56054 --- /dev/null +++ b/test/test-alloc-testing.c @@ -0,0 +1,276 @@ + +/* + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +/* Tests for the allocation testing framework. */ + +#include +#include +#include + +#include "alloc-testing.h" +#include "framework.h" + +static void test_malloc_free(void) +{ + void *block; + unsigned char *ptr; + int i; + + /* Allocate a block and check that the counters increase */ + + assert(alloc_test_get_allocated() == 0); + + block = malloc(1024); + + assert(block != NULL); + assert(alloc_test_get_allocated() == 1024); + + /* Check that the block is initialised with garbage */ + + ptr = block; + + for (i=0; i<1024; ++i) { + assert(ptr[i] != 0); + } + + /* Free the block back and check the counters decrease */ + + free(block); + + assert(alloc_test_get_allocated() == 0); + + /* Try setting a limit */ + + alloc_test_set_limit(1024); + + block = malloc(1025); + assert(block == NULL); + block = malloc(1024); + assert(block != NULL); + free(block); +} + +static void test_realloc(void) +{ + void *block; + void *block2; + + /* This block will be allocated while the other tests are run */ + + block2 = malloc(1024); + + /* Allocate a block */ + + block = malloc(1024); + + assert(block != NULL); + assert(alloc_test_get_allocated() == 1024 + 1024); + + /* Reallocate the block larger */ + + block = realloc(block, 2048); + assert(block != NULL); + + assert(alloc_test_get_allocated() == 2048 + 1024); + + /* Reallocate the block smaller */ + + block = realloc(block, 1500); + assert(block != NULL); + + assert(alloc_test_get_allocated() == 1500 + 1024); + + free(block); + + assert(alloc_test_get_allocated() == 0 + 1024); + + /* Test passing a NULL pointer to make realloc behave as malloc() */ + + block = realloc(NULL, 1024); + + assert(block != NULL); + + assert(alloc_test_get_allocated() == 1024 + 1024); + + free(block); + free(block2); + + assert(alloc_test_get_allocated() == 0); + + /* Test realloc with a limit set */ + + alloc_test_set_limit(1024); + + block = malloc(512); + assert(block != NULL); + assert(alloc_test_get_allocated() == 512); + + block = realloc(block, 1024); + assert(block != NULL); + assert(alloc_test_get_allocated() == 1024); + + assert(realloc(block, 1025) == NULL); + assert(alloc_test_get_allocated() == 1024); + + free(block); + assert(alloc_test_get_allocated() == 0); + + /* Test NULL realloc with limit */ + + block = realloc(NULL, 1025); + assert(block == NULL); + assert(alloc_test_get_allocated() == 0); + + block = realloc(NULL, 1024); + assert(block != NULL); + assert(alloc_test_get_allocated() == 1024); + + free(block); +} + +static void test_calloc(void) +{ + unsigned char *block; + int i; + + assert(alloc_test_get_allocated() == 0); + + /* Allocate a block */ + + block = calloc(16, 64); + + assert(alloc_test_get_allocated() == 1024); + + assert(block != NULL); + + /* Check the block contents are initialised to zero */ + + for (i=0; i<1024; ++i) { + assert(block[i] == 0); + } + + free(block); + + assert(alloc_test_get_allocated() == 0); + + /* Test calloc with limit */ + + alloc_test_set_limit(1024); + + block = calloc(1025, 1); + assert(block == NULL); + assert(alloc_test_get_allocated() == 0); + + block = calloc(1024, 1); + assert(block != NULL); + assert(alloc_test_get_allocated() == 1024); + + free(block); +} + +static void test_strdup(void) +{ + char *str; + + assert(alloc_test_get_allocated() == 0); + + /* Test strdup */ + + str = strdup("hello world"); + + assert(str != NULL); + assert(strcmp(str, "hello world") == 0); + + assert(alloc_test_get_allocated() == 12); + + free(str); + + assert(alloc_test_get_allocated() == 0); + + /* Test strdup with limit */ + + alloc_test_set_limit(12); + + str = strdup("hello world1"); + assert(str == NULL); + assert(alloc_test_get_allocated() == 0); + + str = strdup("hello world"); + assert(str != NULL); + assert(alloc_test_get_allocated() == 12); + + free(str); +} + +static void test_limits(void) +{ + void *block; + void *block2; + + /* Test normal malloc */ + + block = malloc(2048); + assert(block != NULL); + free(block); + + /* Test malloc with limit */ + + alloc_test_set_limit(1024); + assert(malloc(2048) == NULL); + block = malloc(1024); + assert(block != NULL); + free(block); + + /* Check that it is possible to remove the limit */ + + alloc_test_set_limit(-1); + block = malloc(2048); + assert(block != NULL); + free(block); + + /* Check that limits are set _relative_ to the currently allocated + amount of memory */ + + block2 = malloc(1024); + assert(alloc_test_get_allocated() == 1024); + alloc_test_set_limit(2048); + block = malloc(2048); + assert(block != NULL); + free(block); + free(block2); +} + +static UnitTestFunction tests[] = { + test_malloc_free, + test_realloc, + test_calloc, + test_strdup, + test_limits, + NULL +}; + +int main(int argc, char *argv[]) +{ + run_tests(tests); + + return 0; +} + From e46dc2186f0d522b10c2d6eacc12402e4185b343 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 21 Jun 2008 19:05:45 +0000 Subject: [PATCH 095/250] Remove extra calls to find_subtree_height. --- test/test-avl-tree.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index 71a8477..40dccd1 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -93,8 +93,6 @@ int validate_subtree(AVLTreeNode *node) left_node = avl_tree_node_child(node, AVL_TREE_NODE_LEFT); right_node = avl_tree_node_child(node, AVL_TREE_NODE_RIGHT); - left_height = find_subtree_height(left_node); - right_height = find_subtree_height(right_node); /* Check the parent references of the children */ From e8882b54488eb32ead14f58152ac046f42d960be Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 21 Jun 2008 20:24:28 +0000 Subject: [PATCH 096/250] Add out of memory checks for set, hash table. --- test/test-hash-table.c | 59 ++++++++++++++++++++++++++++++++++++++++++ test/test-set.c | 58 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 98a4b52..ecdf649 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -89,6 +89,18 @@ void test_hash_table_new_free(void) /* Free the hash table */ hash_table_free(hash_table); + + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + hash_table = hash_table_new(int_hash, int_equal); + assert(hash_table == NULL); + assert(alloc_test_get_allocated() == 0); + + alloc_test_set_limit(8 * sizeof(void *)); + hash_table = hash_table_new(int_hash, int_equal); + assert(hash_table == NULL); + assert(alloc_test_get_allocated() == 0); } /* Test insert and lookup functions */ @@ -367,6 +379,52 @@ void test_hash_table_free_functions(void) assert(allocated_values == 0); } +/* Test for out of memory scenario */ + +void test_hash_table_out_of_memory(void) +{ + HashTable *hash_table; + int values[66]; + int i; + + hash_table = hash_table_new(int_hash, int_equal); + + /* Test normal failure */ + + alloc_test_set_limit(0); + values[0] = 0; + assert(hash_table_insert(hash_table, &values[0], &values[0]) == 0); + assert(hash_table_num_entries(hash_table) == 0); + + alloc_test_set_limit(-1); + + /* Test failure when increasing table size. + * The initial table size is 193 entries. The table increases in + * size when 1/3 full, so the 66th entry should cause the insert + * to fail. */ + + for (i=0; i<65; ++i) { + values[i] = i; + + assert(hash_table_insert(hash_table, + &values[i], &values[i]) != 0); + assert(hash_table_num_entries(hash_table) == i + 1); + } + + assert(hash_table_num_entries(hash_table) == 65); + + /* Test the 66th insert */ + + alloc_test_set_limit(0); + + values[65] = 65; + + assert(hash_table_insert(hash_table, &values[65], &values[65]) == 0); + assert(hash_table_num_entries(hash_table) == 65); + + hash_table_free(hash_table); +} + static UnitTestFunction tests[] = { test_hash_table_new_free, test_hash_table_insert_lookup, @@ -374,6 +432,7 @@ static UnitTestFunction tests[] = { test_hash_table_iterating, test_hash_table_iterating_remove, test_hash_table_free_functions, + test_hash_table_out_of_memory, NULL }; diff --git a/test/test-set.c b/test/test-set.c index ddd0beb..9566e6d 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -87,6 +87,17 @@ void test_set_new_free(void) /* Free the set */ set_free(set); + + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + set = set_new(int_hash, int_equal); + assert(set == NULL); + + alloc_test_set_limit(7 * sizeof(void *)); + set = set_new(int_hash, int_equal); + assert(set == NULL); + assert(alloc_test_get_allocated() == 0); } void test_set_insert(void) @@ -446,6 +457,52 @@ void test_set_free_function(void) assert(allocated_values == 0); } +/* Test for out of memory scenario */ + +void test_set_out_of_memory(void) +{ + Set *set; + int values[66]; + int i; + + set = set_new(int_hash, int_equal); + + /* Test normal failure */ + + alloc_test_set_limit(0); + values[0] = 0; + assert(set_insert(set, &values[0]) == 0); + assert(set_num_entries(set) == 0); + + alloc_test_set_limit(-1); + + /* Test failure when increasing table size. + * The initial table size is 193 entries. The table increases in + * size when 1/3 full, so the 66th entry should cause the insert + * to fail. */ + + for (i=0; i<65; ++i) { + values[i] = i; + + assert(set_insert(set, &values[i]) != 0); + assert(set_num_entries(set) == i + 1); + } + + assert(set_num_entries(set) == 65); + + /* Test the 66th insert */ + + alloc_test_set_limit(0); + + values[65] = 65; + + assert(set_insert(set, &values[65]) == 0); + assert(set_num_entries(set) == 65); + + set_free(set); +} + + static UnitTestFunction tests[] = { test_set_new_free, test_set_insert, @@ -457,6 +514,7 @@ static UnitTestFunction tests[] = { test_set_iterating_remove, test_set_to_array, test_set_free_function, + test_set_out_of_memory, NULL }; From e78f651d70b4311ac74281cdcff6da526151e162 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 23 Jun 2008 00:45:28 +0000 Subject: [PATCH 097/250] Make avl_tree_node_parent_side function static, as it is internal. --- src/avl-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/avl-tree.c b/src/avl-tree.c index 695c031..7d009ea 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -117,7 +117,7 @@ static void avl_tree_update_height(AVLTreeNode *node) /* Find what side a node is relative to its parent */ -AVLTreeNodeSide avl_tree_node_parent_side(AVLTreeNode *node) +static AVLTreeNodeSide avl_tree_node_parent_side(AVLTreeNode *node) { if (node->parent->children[AVL_TREE_NODE_LEFT] == node) { return AVL_TREE_NODE_LEFT; From 131ae6fd1ba4314998abcaaeb38327f68404190d Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 25 Aug 2008 21:28:20 +0000 Subject: [PATCH 098/250] Turn off optimisation for test library build. --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index bf83837..a23cc37 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c -libcalgtest_a_CFLAGS=$(COV_FLAGS) -DALLOC_TESTING -I../test +libcalgtest_a_CFLAGS=$(COV_FLAGS) -O0 -DALLOC_TESTING -I../test libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) From 2dbb044b610d1acbde51d29b765cbbff930ed10f Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 25 Aug 2008 21:29:58 +0000 Subject: [PATCH 099/250] Test out of memory scenario for trie, and fix rollback to work properly. --- src/trie.c | 37 ++++++++++++++++++++++++------------- test/test-trie.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/trie.c b/src/trie.c index 51a7801..ddf8581 100644 --- a/src/trie.c +++ b/src/trie.c @@ -120,8 +120,10 @@ static TrieNode *trie_find_end(Trie *trie, char *key) static void trie_insert_rollback(Trie *trie, char *key) { - TrieNode **rover; TrieNode *node; + TrieNode **prev_ptr; + TrieNode *next_node; + TrieNode **next_prev_ptr; char *p; /* Follow the chain along. We know that we will never reach the @@ -129,28 +131,37 @@ static void trie_insert_rollback(Trie *trie, char *key) * result, it is not necessary to check for the end of string * delimiter (NUL) */ - rover = &trie->root_node; + node = trie->root_node; + prev_ptr = &trie->root_node; p = key; - while (*rover != NULL) { + while (node != NULL) { - /* Advance to the next node in the chain. Do this now, - * before we potentially free this node. */ + /* Find the next node now. We might free this node. */ - node = *rover; - rover = &node->next[(int) *p]; + next_prev_ptr = &node->next[(int) *p]; + next_node = *next_prev_ptr; ++p; - - /* Decrement the use count at this node back to what it - * previously was. */ + + /* Decrease the use count and free the node if it + * reaches zero. */ --node->use_count; - if (node->use_count <= 0) { - /* This has just been allocated. Free it back. */ + if (node->use_count == 0) { + free(node); - free(node); + if (prev_ptr != NULL) { + *prev_ptr = NULL; + } + + next_prev_ptr = NULL; } + + /* Update pointers */ + + node = next_node; + prev_ptr = next_prev_ptr; } } diff --git a/test/test-trie.c b/test/test-trie.c index 7079ffa..9a843b0 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -50,7 +50,7 @@ Trie *generate_trie(void) test_array[i] = i; sprintf(test_strings[i], "%i", i); - trie_insert(trie, test_strings[i], &test_array[i]); + assert(trie_insert(trie, test_strings[i], &test_array[i]) != 0); ++entries; @@ -91,6 +91,43 @@ void test_trie_new_free(void) assert(trie_remove(trie, "hello") == 1); trie_free(trie); + + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + trie = trie_new(); + assert(trie == NULL); +} + +void test_insert(void) +{ + Trie *trie; + int entries; + int allocated; + + trie = generate_trie(); + + /* Test insert of NULL value has no effect */ + + entries = trie_num_entries(trie); + assert(trie_insert(trie, "hello world", NULL) == 0); + assert(trie_num_entries(trie) == entries); + + /* Test out of memory scenario */ + + allocated = alloc_test_get_allocated(); + alloc_test_set_limit(0); + assert(trie_insert(trie, "a", "test value") == 0); + assert(trie_num_entries(trie) == entries); + + /* Test rollback */ + + alloc_test_set_limit(5 * 258 * sizeof(void *)); + assert(trie_insert(trie, "hello world", "test value") == 0); + assert(alloc_test_get_allocated() == allocated); + assert(trie_num_entries(trie) == entries); + + trie_free(trie); } void test_lookup(void) @@ -195,6 +232,7 @@ void test_insert_empty(void) static UnitTestFunction tests[] = { test_trie_new_free, + test_insert, test_lookup, test_remove, test_replace, From 327e95cc745d45f47ca0591023c6f9d5e23bc194 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 25 Aug 2008 21:36:00 +0000 Subject: [PATCH 100/250] Check return value for trie_insert. --- test/test-trie.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/test-trie.c b/test/test-trie.c index 9a843b0..1be9d3b 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -76,10 +76,10 @@ void test_trie_new_free(void) trie = trie_new(); - trie_insert(trie, "hello", "there"); - trie_insert(trie, "hell", "testing"); - trie_insert(trie, "testing", "testing"); - trie_insert(trie, "", "asfasf"); + assert(trie_insert(trie, "hello", "there") != 0); + assert(trie_insert(trie, "hell", "testing") != 0); + assert(trie_insert(trie, "testing", "testing") != 0); + assert(trie_insert(trie, "", "asfasf") != 0); trie_free(trie); @@ -87,8 +87,8 @@ void test_trie_new_free(void) trie = trie_new(); - trie_insert(trie, "hello", "there"); - assert(trie_remove(trie, "hello") == 1); + assert(trie_insert(trie, "hello", "there") != 0); + assert(trie_remove(trie, "hello") != 0); trie_free(trie); @@ -203,7 +203,7 @@ void test_replace(void) val = malloc(sizeof(int)); *val = 999; - trie_insert(trie, "999", val); + assert(trie_insert(trie, "999", val) != 0); assert(trie_num_entries(trie) == 100000); assert(trie_lookup(trie, "999") == val); @@ -220,8 +220,8 @@ void test_insert_empty(void) /* Test insert on empty string */ - trie_insert(trie, "", buf); - assert(trie_num_entries(trie) == 1); + assert(trie_insert(trie, "", buf) != 0); + assert(trie_num_entries(trie) != 0); assert(trie_lookup(trie, "") == buf); assert(trie_remove(trie, "") != 0); From 4f78f770ab10c940556289277a9a4b72d98fd68d Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 25 Aug 2008 21:38:41 +0000 Subject: [PATCH 101/250] Rename test_ functions -> test_trie_. --- test/test-trie.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/test-trie.c b/test/test-trie.c index 1be9d3b..204c1c0 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -99,7 +99,7 @@ void test_trie_new_free(void) assert(trie == NULL); } -void test_insert(void) +void test_trie_insert(void) { Trie *trie; int entries; @@ -130,7 +130,7 @@ void test_insert(void) trie_free(trie); } -void test_lookup(void) +void test_trie_lookup(void) { Trie *trie; char buf[10]; @@ -158,7 +158,7 @@ void test_lookup(void) trie_free(trie); } -void test_remove(void) +void test_trie_remove(void) { Trie *trie; char buf[10]; @@ -192,7 +192,7 @@ void test_remove(void) trie_free(trie); } -void test_replace(void) +void test_trie_replace(void) { Trie *trie; int *val; @@ -211,7 +211,7 @@ void test_replace(void) trie_free(trie); } -void test_insert_empty(void) +void test_trie_insert_empty(void) { Trie *trie; char buf[10]; @@ -232,11 +232,11 @@ void test_insert_empty(void) static UnitTestFunction tests[] = { test_trie_new_free, - test_insert, - test_lookup, - test_remove, - test_replace, - test_insert_empty, + test_trie_insert, + test_trie_lookup, + test_trie_remove, + test_trie_replace, + test_trie_insert_empty, NULL }; From 155db7a33a0230c3ce4bb291f5e212bf85df976b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 25 Aug 2008 22:36:17 +0000 Subject: [PATCH 102/250] Improve coverage for set. --- test/test-set.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/test/test-set.c b/test/test-set.c index 9566e6d..8d961fd 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -212,6 +212,7 @@ void test_set_union(void) Set *set1; Set *set2; Set *result_set; + int allocated; /* Create the first set */ @@ -239,9 +240,30 @@ void test_set_union(void) assert(set_query(result_set, &result[i]) != 0); } + set_free(result_set); + + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + assert(set_union(set1, set2) == NULL); + + /* Can allocate set, can't copy all set1 values */ + + alloc_test_set_limit(sizeof(void *) * (7 + 193 + 6)); + allocated = alloc_test_get_allocated(); + assert(set_union(set1, set2) == NULL); + assert(alloc_test_get_allocated() == allocated); + + /* Can allocate set, can copy set1 values, + * can't copy all set2 values */ + + alloc_test_set_limit(sizeof(void *) * (7 + 193 + 15)); + allocated = alloc_test_get_allocated(); + assert(set_union(set1, set2) == NULL); + assert(alloc_test_get_allocated() == allocated); + set_free(set1); set_free(set2); - set_free(result_set); } void test_set_intersection(void) @@ -253,6 +275,7 @@ void test_set_intersection(void) Set *set1; Set *set2; Set *result_set; + int allocated; /* Create the first set */ @@ -280,6 +303,18 @@ void test_set_intersection(void) assert(set_query(result_set, &result[i]) != 0); } + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + assert(set_intersection(set1, set2) == NULL); + + /* Can allocate set, can't copy all values */ + + alloc_test_set_limit(sizeof(void *) * (7 + 193 + 2)); + allocated = alloc_test_get_allocated(); + assert(set_intersection(set1, set2) == NULL); + assert(alloc_test_get_allocated() == allocated); + set_free(set1); set_free(set2); set_free(result_set); @@ -311,6 +346,11 @@ void test_set_to_array(void) *array[i] = 0; } + /* Test out of memory scenario */ + + alloc_test_set_limit(0); + assert(set_to_array(set) == NULL); + free(array); set_free(set); } From f0498d5164f05bad033696a4f44df6a9d7467807 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 26 Aug 2008 13:41:39 +0000 Subject: [PATCH 103/250] Change allocation limit to limit a number of allocations, not a number of bytes. --- test/alloc-testing.c | 159 +++++++++++--------------------------- test/alloc-testing.h | 13 ++-- test/test-alloc-testing.c | 64 +++++++-------- test/test-arraylist.c | 2 +- test/test-binary-heap.c | 2 +- test/test-bloom-filter.c | 2 +- test/test-hash-table.c | 2 +- test/test-set.c | 8 +- test/test-trie.c | 2 +- 9 files changed, 92 insertions(+), 162 deletions(-) diff --git a/test/alloc-testing.c b/test/alloc-testing.c index d3c9da8..f2a7e26 100644 --- a/test/alloc-testing.c +++ b/test/alloc-testing.c @@ -59,7 +59,9 @@ struct _BlockHeader { static size_t allocated_bytes = 0; -/* Allocation limit, negative value means no limit. */ +/* Limit on number of allocations that are possible. Each time an allocation + * is made, this is decremented. When it reaches zero, no more allocations + * are allowed. If this has a negative value, the limit is disabled. */ signed int allocation_limit = -1; @@ -78,14 +80,6 @@ static BlockHeader *alloc_test_get_header(void *ptr) return result; } -/* Test whether a new value of allocated_bytes would be valid. */ - -static int alloc_test_new_size_allowed(size_t new_size) -{ - return allocation_limit < 0 - || new_size <= allocation_limit; -} - /* Overwrite a block of memory with a repeated pattern. */ static void alloc_test_overwrite(void *ptr, size_t length, unsigned int pattern) @@ -106,11 +100,17 @@ static void alloc_test_overwrite(void *ptr, size_t length, unsigned int pattern) /* Base malloc function used by other functions. */ -BlockHeader *alloc_test_base_malloc(size_t bytes) +void *alloc_test_malloc(size_t bytes) { BlockHeader *header; void *ptr; + /* Check if we have reached the allocation limit. */ + + if (allocation_limit == 0) { + return NULL; + } + /* Allocate the requested block with enough room for the block header * as well. */ @@ -129,62 +129,23 @@ BlockHeader *alloc_test_base_malloc(size_t bytes) ptr = header + 1; alloc_test_overwrite(ptr, bytes, MALLOC_PATTERN); - return header; -} - -/* Base free function */ - -void alloc_test_base_free(BlockHeader *header) -{ - void *ptr; - - /* Trash the allocated block to foil any code that relies on memory - * that has been freed. */ - - ptr = header + 1; - alloc_test_overwrite(ptr, header->bytes, FREE_PATTERN); - - /* Trash the magic number in the block header to stop the same block - * from being freed again. */ - - header->magic_number = 0; - - /* Free the allocated memory. */ - - free(header); -} - -/* Main malloc function */ - -void *alloc_test_malloc(size_t bytes) -{ - BlockHeader *header; - void *result; - - /* Check if we have reached the allocation limit. */ - - if (!alloc_test_new_size_allowed(allocated_bytes + bytes)) { - return NULL; - } + /* Update counter */ - /* Do the allocation */ + allocated_bytes += bytes; - header = alloc_test_base_malloc(bytes); + /* Decrease the allocation limit */ - if (header == NULL) { - return NULL; + if (allocation_limit > 0) { + --allocation_limit; } - /* Update counter */ - - allocated_bytes += bytes; - /* Skip past the header and return the block itself */ - result = header + 1; - return result; + return header + 1; } +/* Base free function */ + void alloc_test_free(void *ptr) { BlockHeader *header; @@ -196,13 +157,25 @@ void alloc_test_free(void *ptr) return; } - /* Free the block */ + /* Get the block header and do a sanity check */ header = alloc_test_get_header(ptr); block_size = header->bytes; assert(allocated_bytes >= block_size); - alloc_test_base_free(header); + /* Trash the allocated block to foil any code that relies on memory + * that has been freed. */ + + alloc_test_overwrite(ptr, header->bytes, FREE_PATTERN); + + /* Trash the magic number in the block header to stop the same block + * from being freed again. */ + + header->magic_number = 0; + + /* Free the allocated memory. */ + + free(header); /* Update counter */ @@ -211,68 +184,34 @@ void alloc_test_free(void *ptr) void *alloc_test_realloc(void *ptr, size_t bytes) { - BlockHeader *old_block, *new_block; + BlockHeader *header; void *new_ptr; - size_t old_bytes; - size_t new_allocated_bytes; size_t bytes_to_copy; - /* A NULL value can be passed to ptr to make realloc behave - * like malloc(). */ - - if (ptr != NULL) { - old_block = alloc_test_get_header(ptr); - old_bytes = old_block->bytes; - } else { - old_block = NULL; - old_bytes = 0; - } - - /* Sanity check the new allocated_bytes value */ - - assert(allocated_bytes + bytes >= old_bytes); - - /* Check the new value for allocated bytes is within the - * allocation limit. */ + /* Allocate the new block */ - new_allocated_bytes = allocated_bytes + bytes - old_bytes; + new_ptr = alloc_test_malloc(bytes); - if (!alloc_test_new_size_allowed(new_allocated_bytes)) { + if (new_ptr == NULL) { return NULL; } - /* Always allocate a new block, to ensure that code does not rely - * on reallocated blocks having the same memory location. */ + /* Copy over the old data and free the old block, if there was any. */ - new_block = alloc_test_base_malloc(bytes); - - if (new_block == NULL) { - return NULL; - } - - /* Work out how many bytes to copy. */ + if (ptr != NULL) { + header = alloc_test_get_header(ptr); - if (bytes < old_bytes) { - bytes_to_copy = bytes; - } else { - bytes_to_copy = old_bytes; - } + bytes_to_copy = header->bytes; - /* Copy the old block to the new block. */ + if (bytes_to_copy > bytes) { + bytes_to_copy = bytes; + } - new_ptr = new_block + 1; - memcpy(new_ptr, ptr, bytes_to_copy); + memcpy(new_ptr, ptr, bytes_to_copy); - /* Free the old block. */ - - if (old_block != NULL) { - alloc_test_base_free(old_block); + alloc_test_free(ptr); } - /* Update allocated_bytes counter. */ - - allocated_bytes = new_allocated_bytes; - return new_ptr; } @@ -311,13 +250,9 @@ char *alloc_test_strdup(const char *string) return result; } -void alloc_test_set_limit(signed int bytes) +void alloc_test_set_limit(signed int alloc_count) { - if (bytes < 0) { - allocation_limit = -1; - } else { - allocation_limit = allocated_bytes + bytes; - } + allocation_limit = alloc_count; } size_t alloc_test_get_allocated(void) diff --git a/test/alloc-testing.h b/test/alloc-testing.h index 57eddf5..1d3ffef 100644 --- a/test/alloc-testing.h +++ b/test/alloc-testing.h @@ -107,14 +107,15 @@ char *alloc_test_strdup(const char *string); * Set an artificial limit on the amount of memory that can be * allocated. * - * @param bytes The maximum number of bytes that may be allocated, - * relative to the currently allocated number of bytes. - * For example, if this has a value of 100, 100 more - * bytes may be allocated. If this has a negative - * value, any current limit is disabled. + * @param alloc_count Number of allocations that are possible after + * this call. For example, if this has a value + * of 3, malloc() can be called successfully + * three times, but all allocation attempts + * after this will fail. If this has a negative + * value, the allocation limit is disabled. */ -void alloc_test_set_limit(signed int bytes); +void alloc_test_set_limit(signed int alloc_count); /** * Get a count of the number of bytes currently allocated. diff --git a/test/test-alloc-testing.c b/test/test-alloc-testing.c index 7b56054..bfdd039 100644 --- a/test/test-alloc-testing.c +++ b/test/test-alloc-testing.c @@ -30,7 +30,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. static void test_malloc_free(void) { - void *block; + void *block, *block2, *block3, *block4; unsigned char *ptr; int i; @@ -59,13 +59,20 @@ static void test_malloc_free(void) /* Try setting a limit */ - alloc_test_set_limit(1024); + alloc_test_set_limit(3); - block = malloc(1025); - assert(block == NULL); block = malloc(1024); assert(block != NULL); + block2 = malloc(1024); + assert(block2 != NULL); + block3 = malloc(1024); + assert(block3 != NULL); + block4 = malloc(1024); + assert(block4 == NULL); free(block); + free(block2); + free(block3); + free(block4); } static void test_realloc(void) @@ -117,17 +124,17 @@ static void test_realloc(void) /* Test realloc with a limit set */ - alloc_test_set_limit(1024); - block = malloc(512); assert(block != NULL); assert(alloc_test_get_allocated() == 512); + alloc_test_set_limit(1); + block = realloc(block, 1024); assert(block != NULL); assert(alloc_test_get_allocated() == 1024); - assert(realloc(block, 1025) == NULL); + assert(realloc(block, 2048) == NULL); assert(alloc_test_get_allocated() == 1024); free(block); @@ -135,14 +142,15 @@ static void test_realloc(void) /* Test NULL realloc with limit */ - block = realloc(NULL, 1025); - assert(block == NULL); - assert(alloc_test_get_allocated() == 0); + alloc_test_set_limit(1); block = realloc(NULL, 1024); assert(block != NULL); assert(alloc_test_get_allocated() == 1024); + assert(realloc(NULL, 1024) == NULL); + assert(alloc_test_get_allocated() == 1024); + free(block); } @@ -173,16 +181,15 @@ static void test_calloc(void) /* Test calloc with limit */ - alloc_test_set_limit(1024); - - block = calloc(1025, 1); - assert(block == NULL); - assert(alloc_test_get_allocated() == 0); + alloc_test_set_limit(1); block = calloc(1024, 1); assert(block != NULL); assert(alloc_test_get_allocated() == 1024); + assert(calloc(1024, 1) == NULL); + assert(alloc_test_get_allocated() == 1024); + free(block); } @@ -207,23 +214,21 @@ static void test_strdup(void) /* Test strdup with limit */ - alloc_test_set_limit(12); - - str = strdup("hello world1"); - assert(str == NULL); - assert(alloc_test_get_allocated() == 0); + alloc_test_set_limit(1); str = strdup("hello world"); assert(str != NULL); assert(alloc_test_get_allocated() == 12); + assert(strdup("hello world") == NULL); + assert(alloc_test_get_allocated() == 12); + free(str); } static void test_limits(void) { void *block; - void *block2; /* Test normal malloc */ @@ -233,29 +238,18 @@ static void test_limits(void) /* Test malloc with limit */ - alloc_test_set_limit(1024); - assert(malloc(2048) == NULL); + alloc_test_set_limit(1); block = malloc(1024); assert(block != NULL); + assert(malloc(1024) == NULL); free(block); /* Check that it is possible to remove the limit */ alloc_test_set_limit(-1); - block = malloc(2048); - assert(block != NULL); - free(block); - - /* Check that limits are set _relative_ to the currently allocated - amount of memory */ - - block2 = malloc(1024); - assert(alloc_test_get_allocated() == 1024); - alloc_test_set_limit(2048); - block = malloc(2048); + block = malloc(1024); assert(block != NULL); free(block); - free(block2); } static UnitTestFunction tests[] = { diff --git a/test/test-arraylist.c b/test/test-arraylist.c index a2b407f..0185ee4 100644 --- a/test/test-arraylist.c +++ b/test/test-arraylist.c @@ -81,7 +81,7 @@ void test_arraylist_new_free(void) arraylist = arraylist_new(0); assert(arraylist == NULL); - alloc_test_set_limit(100 * sizeof(void *)); + alloc_test_set_limit(1); arraylist = arraylist_new(100); assert(arraylist == NULL); } diff --git a/test/test-binary-heap.c b/test/test-binary-heap.c index d8bec3d..0920b1d 100644 --- a/test/test-binary-heap.c +++ b/test/test-binary-heap.c @@ -45,7 +45,7 @@ void test_binary_heap_new_free(void) heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); assert(heap == NULL); - alloc_test_set_limit(16 * sizeof(void *)); + alloc_test_set_limit(1); heap = binary_heap_new(BINARY_HEAP_TYPE_MIN, int_compare); assert(heap == NULL); } diff --git a/test/test-bloom-filter.c b/test/test-bloom-filter.c index 4d41a14..977279f 100644 --- a/test/test-bloom-filter.c +++ b/test/test-bloom-filter.c @@ -62,7 +62,7 @@ void test_bloom_filter_new_free(void) assert(filter == NULL); - alloc_test_set_limit(sizeof(void *) * 4); + alloc_test_set_limit(1); filter = bloom_filter_new(128, string_hash, 1); diff --git a/test/test-hash-table.c b/test/test-hash-table.c index ecdf649..b66a722 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -97,7 +97,7 @@ void test_hash_table_new_free(void) assert(hash_table == NULL); assert(alloc_test_get_allocated() == 0); - alloc_test_set_limit(8 * sizeof(void *)); + alloc_test_set_limit(1); hash_table = hash_table_new(int_hash, int_equal); assert(hash_table == NULL); assert(alloc_test_get_allocated() == 0); diff --git a/test/test-set.c b/test/test-set.c index 8d961fd..16f0ae6 100644 --- a/test/test-set.c +++ b/test/test-set.c @@ -94,7 +94,7 @@ void test_set_new_free(void) set = set_new(int_hash, int_equal); assert(set == NULL); - alloc_test_set_limit(7 * sizeof(void *)); + alloc_test_set_limit(1); set = set_new(int_hash, int_equal); assert(set == NULL); assert(alloc_test_get_allocated() == 0); @@ -249,7 +249,7 @@ void test_set_union(void) /* Can allocate set, can't copy all set1 values */ - alloc_test_set_limit(sizeof(void *) * (7 + 193 + 6)); + alloc_test_set_limit(2 + 2); allocated = alloc_test_get_allocated(); assert(set_union(set1, set2) == NULL); assert(alloc_test_get_allocated() == allocated); @@ -257,7 +257,7 @@ void test_set_union(void) /* Can allocate set, can copy set1 values, * can't copy all set2 values */ - alloc_test_set_limit(sizeof(void *) * (7 + 193 + 15)); + alloc_test_set_limit(2 + 7 + 2); allocated = alloc_test_get_allocated(); assert(set_union(set1, set2) == NULL); assert(alloc_test_get_allocated() == allocated); @@ -310,7 +310,7 @@ void test_set_intersection(void) /* Can allocate set, can't copy all values */ - alloc_test_set_limit(sizeof(void *) * (7 + 193 + 2)); + alloc_test_set_limit(2 + 2); allocated = alloc_test_get_allocated(); assert(set_intersection(set1, set2) == NULL); assert(alloc_test_get_allocated() == allocated); diff --git a/test/test-trie.c b/test/test-trie.c index 204c1c0..8a8682b 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -122,7 +122,7 @@ void test_trie_insert(void) /* Test rollback */ - alloc_test_set_limit(5 * 258 * sizeof(void *)); + alloc_test_set_limit(5); assert(trie_insert(trie, "hello world", "test value") == 0); assert(alloc_test_get_allocated() == allocated); assert(trie_num_entries(trie) == entries); From c3cf596dcd196cf4e1652c2e81028ae9ee141153 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 27 Aug 2008 20:29:09 +0000 Subject: [PATCH 104/250] Add missing C++ extern "C" declarations to headers. --- src/binary-heap.h | 4 ++++ src/binomial-heap.h | 4 ++++ src/list.h | 8 ++++++++ src/slist.h | 8 ++++++++ 4 files changed, 24 insertions(+) diff --git a/src/binary-heap.h b/src/binary-heap.h index 36718aa..96b81fc 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -143,5 +143,9 @@ BinaryHeapValue binary_heap_pop(BinaryHeap *heap); int binary_heap_num_entries(BinaryHeap *heap); +#ifdef __cplusplus +} +#endif + #endif /* #ifndef ALGORITHM_BINARY_HEAP_H */ diff --git a/src/binomial-heap.h b/src/binomial-heap.h index 24c9fa4..bf3d814 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -143,5 +143,9 @@ BinomialHeapValue binomial_heap_pop(BinomialHeap *heap); int binomial_heap_num_entries(BinomialHeap *heap); +#ifdef __cplusplus +} +#endif + #endif /* #ifndef ALGORITHM_BINOMIAL_HEAP_H */ diff --git a/src/list.h b/src/list.h index 7530405..add3e78 100644 --- a/src/list.h +++ b/src/list.h @@ -53,6 +53,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef ALGORITHM_LIST_H #define ALGORITHM_LIST_H +#ifdef __cplusplus +extern "C" { +#endif + /** * Represents an entry in a doubly-linked list. The empty list is * represented by a NULL pointer. To initialise a new doubly linked @@ -300,5 +304,9 @@ ListValue list_iter_next(ListIterator *iterator); void list_iter_remove(ListIterator *iterator); +#ifdef __cplusplus +} +#endif + #endif /* #ifndef ALGORITHM_LIST_H */ diff --git a/src/slist.h b/src/slist.h index c66c126..4eb85e6 100644 --- a/src/slist.h +++ b/src/slist.h @@ -66,6 +66,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef ALGORITHM_SLIST_H #define ALGORITHM_SLIST_H +#ifdef __cplusplus +extern "C" { +#endif + /** * Represents an entry in a singly-linked list. The empty list is * represented by a NULL pointer. To initialise a new singly linked @@ -302,5 +306,9 @@ SListValue slist_iter_next(SListIterator *iterator); void slist_iter_remove(SListIterator *iterator); +#ifdef __cplusplus +} +#endif + #endif /* #ifndef ALGORITHM_SLIST_H */ From 74a8ff262d9e01a2bc7bd519310c822e37f3762c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 27 Aug 2008 21:25:09 +0000 Subject: [PATCH 105/250] Add test case for checking the library can be used from C++ programs. --- configure.ac | 1 + test/Makefile.am | 4 + test/framework.h | 8 ++ test/test-cpp.cpp | 231 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 test/test-cpp.cpp diff --git a/configure.ac b/configure.ac index b1e2ce2..a2f245f 100644 --- a/configure.ac +++ b/configure.ac @@ -4,6 +4,7 @@ AC_CONFIG_AUX_DIR(autotools) AM_INIT_AUTOMAKE($PACKAGE_TARNAME, $PACKAGE_VERSION, no-define) AC_PROG_CC +AC_PROG_CXX AC_PROG_LIBTOOL AC_PROG_INSTALL AC_PROG_MAKE_SET diff --git a/test/Makefile.am b/test/Makefile.am index b9b9157..36ef68e 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -10,6 +10,7 @@ TESTS = \ test-binary-heap \ test-binomial-heap \ test-bloom-filter \ + test-cpp \ test-list \ test-slist \ test-queue \ @@ -31,3 +32,6 @@ LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a EXTRA_DIST=valgrind-wrapper +test-cpp: test-cpp.cpp + $(CXX) $(AM_CFLAGS) $^ -o $@ $(LDADD) + diff --git a/test/framework.h b/test/framework.h index 5901e22..bfc92b2 100644 --- a/test/framework.h +++ b/test/framework.h @@ -21,6 +21,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef TEST_FRAMEWORK_H #define TEST_FRAMEWORK_H +#ifdef __cplusplus +extern "C" { +#endif + /** * @file framework.h * @@ -43,5 +47,9 @@ typedef void (*UnitTestFunction)(void); void run_tests(UnitTestFunction *tests); +#ifdef __cplusplus +} +#endif + #endif /* #ifndef TEST_FRAMEWORK_H */ diff --git a/test/test-cpp.cpp b/test/test-cpp.cpp new file mode 100644 index 0000000..f2410da --- /dev/null +++ b/test/test-cpp.cpp @@ -0,0 +1,231 @@ +/* + +Copyright (c) 2005-2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +/* This file tests that the library can be used from C++ programs. */ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "framework.h" + +static void test_compare_int(void) +{ + int a, b; + + a = 1; b = 2; + assert(!int_equal(&a, &b)); + a = 2; b = 2; + assert(int_equal(&a, &b)); +} + +static void test_compare_pointer(void) +{ + int a, b; + void *p1, *p2; + + p1 = &a; p2 = &b; + assert(!pointer_equal(p1, p2)); + p1 = &a; p2 = &a; + assert(pointer_equal(p1, p2)); +} + +static void test_compare_string(void) +{ + char s1[] = "hello"; + char s2[] = "hello"; + char s3[] = "world"; + + assert(!string_equal(s1, s3)); + assert(string_equal(s1, s2)); +} + +static void test_hash_int(void) +{ + int a, b; + + a = 1; b = 2; + assert(int_hash(&a) != int_hash(&b)); + a = 2; b = 2; + assert(int_hash(&a) == int_hash(&b)); +} + +static void test_hash_pointer(void) +{ + int a, b; + void *p1, *p2; + + p1 = &a; p2 = &b; + assert(pointer_hash(p1) != pointer_hash(p2)); + p1 = &a; p2 = &a; + assert(pointer_hash(p1) == pointer_hash(p2)); +} + +static void test_hash_string(void) +{ + char s1[] = "hello"; + char s2[] = "hello"; + char s3[] = "world"; + + assert(string_hash(s1) != string_hash(s3)); + assert(string_hash(s1) == string_hash(s2)); +} + +static void test_arraylist(void) +{ + ArrayList *arraylist; + + arraylist = arraylist_new(0); + arraylist_free(arraylist); +} + +static void test_avl_tree(void) +{ + AVLTree *avl_tree; + + avl_tree = avl_tree_new(string_compare); + avl_tree_free(avl_tree); +} + +static void test_binary_heap(void) +{ + BinaryHeap *heap; + + heap = binary_heap_new(BINARY_HEAP_TYPE_MAX, string_compare); + binary_heap_free(heap); +} + +static void test_binomial_heap(void) +{ + BinomialHeap *heap; + + heap = binomial_heap_new(BINOMIAL_HEAP_TYPE_MAX, string_compare); + binomial_heap_free(heap); +} + +static void test_bloom_filter(void) +{ + BloomFilter *filter; + + filter = bloom_filter_new(16, string_hash, 10); + bloom_filter_free(filter); +} + +static void test_hash_table(void) +{ + HashTable *hash_table; + + hash_table = hash_table_new(string_hash, string_equal); + hash_table_free(hash_table); +} + +static void test_list(void) +{ + ListEntry *list = NULL; + int a, b, c; + + list_prepend(&list, &a); + list_prepend(&list, &b); + list_prepend(&list, &c); + + list_free(list); +} + +static void test_queue(void) +{ + Queue *queue; + + queue = queue_new(); + queue_free(queue); +} + +static void test_set(void) +{ + Set *set; + + set = set_new(string_hash, string_equal); + set_free(set); +} + +static void test_slist(void) +{ + SListEntry *list = NULL; + int a, b, c; + + slist_prepend(&list, &a); + slist_prepend(&list, &b); + slist_prepend(&list, &c); + + slist_free(list); +} + +static void test_trie(void) +{ + Trie *trie; + + trie = trie_new(); + trie_free(trie); +} + +static UnitTestFunction tests[] = { + test_compare_int, + test_compare_pointer, + test_compare_string, + test_hash_int, + test_hash_pointer, + test_hash_string, + test_arraylist, + test_avl_tree, + test_binary_heap, + test_binomial_heap, + test_bloom_filter, + test_hash_table, + test_list, + test_queue, + test_set, + test_slist, + test_trie, + NULL +}; + +int main(int argc, char *argv[]) +{ + run_tests(tests); +} + From 55890adce331972d55adcac0c9bb1098b66fb072 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 27 Aug 2008 21:37:01 +0000 Subject: [PATCH 106/250] Smart indent all source. --- src/avl-tree.c | 16 ++++++++-------- src/avl-tree.h | 4 ++-- src/binary-heap.h | 4 ++-- src/binomial-heap.c | 8 ++++---- src/binomial-heap.h | 4 ++-- src/trie.c | 2 +- test/test-cpp.cpp | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/avl-tree.c b/src/avl-tree.c index 7d009ea..4acf426 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -179,7 +179,7 @@ static AVLTreeNode *avl_tree_rotate(AVLTree *tree, AVLTreeNode *node, AVLTreeNode *new_root; /* The child of this node will take its place: - for a left rotation, it is the right child, and vice versa. */ + for a left rotation, it is the right child, and vice versa. */ new_root = node->children[1-direction]; @@ -205,7 +205,7 @@ static AVLTreeNode *avl_tree_rotate(AVLTree *tree, AVLTreeNode *node, avl_tree_update_height(new_root); avl_tree_update_height(node); - return new_root; + return new_root; } @@ -245,7 +245,7 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) * rotation) */ avl_tree_rotate(tree, right_subtree, - AVL_TREE_NODE_RIGHT); + AVL_TREE_NODE_RIGHT); } /* Perform a left rotation. After this, the right child will @@ -267,7 +267,7 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) * rotation) */ avl_tree_rotate(tree, left_subtree, - AVL_TREE_NODE_LEFT); + AVL_TREE_NODE_LEFT); } /* Perform a right rotation. After this, the left child will @@ -287,7 +287,7 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) static void avl_tree_balance_to_root(AVLTree *tree, AVLTreeNode *node) { - AVLTreeNode *rover; + AVLTreeNode *rover; rover = node; @@ -342,9 +342,9 @@ AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) *rover = new_node; - /* Rebalance the tree, starting from the previous node. */ + /* Rebalance the tree, starting from the previous node. */ - avl_tree_balance_to_root(tree, previous_node); + avl_tree_balance_to_root(tree, previous_node); /* Keep track of the number of entries */ @@ -475,7 +475,7 @@ void avl_tree_remove_node(AVLTree *tree, AVLTreeNode *node) /* Rebalance the tree */ - avl_tree_balance_to_root(tree, balance_startpoint); + avl_tree_balance_to_root(tree, balance_startpoint); } /* Remove a node by key */ diff --git a/src/avl-tree.h b/src/avl-tree.h index d5830ce..45de3fe 100644 --- a/src/avl-tree.h +++ b/src/avl-tree.h @@ -101,8 +101,8 @@ typedef struct _AVLTreeNode AVLTreeNode; */ typedef enum { - AVL_TREE_NODE_LEFT = 0, - AVL_TREE_NODE_RIGHT = 1 + AVL_TREE_NODE_LEFT = 0, + AVL_TREE_NODE_RIGHT = 1 } AVLTreeNodeSide; /** diff --git a/src/binary-heap.h b/src/binary-heap.h index 96b81fc..bd5ae63 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -51,11 +51,11 @@ extern "C" { */ typedef enum { - /** A minimum heap. */ + /** A minimum heap. */ BINARY_HEAP_TYPE_MIN, - /** A maximum heap. */ + /** A maximum heap. */ BINARY_HEAP_TYPE_MAX } BinaryHeapType; diff --git a/src/binomial-heap.c b/src/binomial-heap.c index ee8b090..bdf237e 100644 --- a/src/binomial-heap.c +++ b/src/binomial-heap.c @@ -132,10 +132,10 @@ static BinomialTree *binomial_tree_merge(BinomialHeap *heap, new_tree->subtrees = malloc(sizeof(BinomialTree *) * new_tree->order); - if (new_tree->subtrees == NULL) { - free(new_tree); - return NULL; - } + if (new_tree->subtrees == NULL) { + free(new_tree); + return NULL; + } memcpy(new_tree->subtrees, tree1->subtrees, sizeof(BinomialTree *) * tree1->order); diff --git a/src/binomial-heap.h b/src/binomial-heap.h index bf3d814..5442bbe 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -51,11 +51,11 @@ extern "C" { */ typedef enum { - /** A minimum heap. */ + /** A minimum heap. */ BINOMIAL_HEAP_TYPE_MIN, - /** A maximum heap. */ + /** A maximum heap. */ BINOMIAL_HEAP_TYPE_MAX } BinomialHeapType; diff --git a/src/trie.c b/src/trie.c index ddf8581..643a110 100644 --- a/src/trie.c +++ b/src/trie.c @@ -149,7 +149,7 @@ static void trie_insert_rollback(Trie *trie, char *key) --node->use_count; if (node->use_count == 0) { - free(node); + free(node); if (prev_ptr != NULL) { *prev_ptr = NULL; diff --git a/test/test-cpp.cpp b/test/test-cpp.cpp index f2410da..b46de57 100644 --- a/test/test-cpp.cpp +++ b/test/test-cpp.cpp @@ -204,7 +204,7 @@ static void test_trie(void) } static UnitTestFunction tests[] = { - test_compare_int, + test_compare_int, test_compare_pointer, test_compare_string, test_hash_int, From 87f6b7bec2254841fa0dda130ae9e3e893ec1e88 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 3 Sep 2008 00:48:46 +0000 Subject: [PATCH 107/250] Add script for generating coverage reports from gcov files. --- src/Makefile.am | 2 ++ src/gencov | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100755 src/gencov diff --git a/src/Makefile.am b/src/Makefile.am index a23cc37..9943a18 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,3 +29,5 @@ headerfiles_HEADERS=$(MAIN_HEADERFILES) calgheaderfilesdir=$(headerfilesdir)/libcalg calgheaderfiles_HEADERS=$(CALG_HEADERFILES) +EXTRA_DIST=gencov + diff --git a/src/gencov b/src/gencov new file mode 100755 index 0000000..9ef02df --- /dev/null +++ b/src/gencov @@ -0,0 +1,11 @@ +#!/bin/sh +# +# Simple shell script to generate a coverage report. +# + +for d in *.c; do + obj=`echo $d | sed "s/^/libcalgtest_a-/" | sed "s/.c$/.o/"` + + gcov -b -o $obj $d +done + From 6421c6a98973a5aee8f524d61c2bc93482a538c8 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 4 Sep 2008 19:53:44 +0000 Subject: [PATCH 108/250] Use a non-recursive algorithm for trie_free. Add a test case for this. --- src/trie.c | 66 +++++++++++++++++++++++++++++++++--------------- test/test-trie.c | 39 +++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 27 deletions(-) diff --git a/src/trie.c b/src/trie.c index 643a110..6962703 100644 --- a/src/trie.c +++ b/src/trie.c @@ -43,24 +43,6 @@ struct _Trie { TrieNode *root_node; }; -static void trie_free_node(TrieNode *node) -{ - int i; - - if (node == NULL) - return; - - /* First, free all subnodes */ - - for (i=0; i<256; ++i) { - trie_free_node(node->next[i]); - } - - /* Free this node */ - - free(node); -} - Trie *trie_new(void) { Trie *new_trie; @@ -76,11 +58,55 @@ Trie *trie_new(void) return new_trie; } +static void trie_free_list_push(TrieNode **list, TrieNode *node) +{ + node->data = *list; + *list = node; +} + +static TrieNode *trie_free_list_pop(TrieNode **list) +{ + TrieNode *result; + + result = *list; + *list = result->data; + + return result; +} + void trie_free(Trie *trie) { - /* Free the subnode, and all others by implication */ + TrieNode *free_list; + TrieNode *node; + int i; + + free_list = NULL; + + /* Start with the root node */ + + if (trie->root_node != NULL) { + trie_free_list_push(&free_list, trie->root_node); + } - trie_free_node(trie->root_node); + /* Go through the free list, freeing nodes. We add new nodes as + * we encounter them; in this way, all the nodes are freed + * non-recursively. */ + + while (free_list != NULL) { + node = trie_free_list_pop(&free_list); + + /* Add all children of this node to the free list */ + + for (i=0; i<256; ++i) { + if (node->next[i] != NULL) { + trie_free_list_push(&free_list, node->next[i]); + } + } + + /* Free the node */ + + free(node); + } /* Free the trie */ diff --git a/test/test-trie.c b/test/test-trie.c index 8a8682b..dbb0416 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -28,8 +28,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "trie.h" -int test_array[100000]; -char test_strings[100000][10]; +#define NUM_TEST_VALUES 10000 + +int test_array[NUM_TEST_VALUES]; +char test_strings[NUM_TEST_VALUES][10]; Trie *generate_trie(void) { @@ -42,7 +44,7 @@ Trie *generate_trie(void) trie = trie_new(); entries = 0; - for (i=0; i<100000; ++i) { + for (i=0; i Date: Thu, 4 Sep 2008 20:06:13 +0000 Subject: [PATCH 109/250] Reword some of the text about the license. --- README | 10 +++++----- doc/intro.h | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/README b/README index 65aa54b..a9ccd8a 100644 --- a/README +++ b/README @@ -2,10 +2,10 @@ C Algorithms The C programming language includes a very limited standard library in -comparison to other modern programming languages. This is a collection -of common Computer Science algorithms which may be used in C projects. +comparison to other modern programming languages. This is a collection of +common Computer Science algorithms which may be used in C projects. -The code is licensed under the ISC license (a simplified version of the -Modified BSD license). As such, it may legitimately be reused in any -project, whether Proprietary or Open Source. +The code is licensed under the ISC license (a simplified version of the BSD +license that is functionally identical). As such, it may legitimately be +reused in any project, whether Proprietary or Open Source. diff --git a/doc/intro.h b/doc/intro.h index 95fbb82..f0af1aa 100644 --- a/doc/intro.h +++ b/doc/intro.h @@ -32,8 +32,9 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * used in C projects. * * The code is licensed under the ISC license (a simplified version - * of the Modified BSD license). As such, it may be reused in any - * project, whether Proprietary or Open Source. + * of the BSD license that is functionally identical). + * As such, it may be reused in any project, whether Proprietary or + * Open Source. * * @section Data_structures Data structures * From d55fec9e06c72e0b133730a2dc41f2216ef38244 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 12 Sep 2008 23:54:04 +0000 Subject: [PATCH 110/250] Expand binomial heap test case to include out of memory scenarios. --- test/test-binomial-heap.c | 131 +++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 3 deletions(-) diff --git a/test/test-binomial-heap.c b/test/test-binomial-heap.c index 7199bc6..ed3b817 100644 --- a/test/test-binomial-heap.c +++ b/test/test-binomial-heap.c @@ -38,6 +38,12 @@ void test_binomial_heap_new_free(void) heap = binomial_heap_new(BINOMIAL_HEAP_TYPE_MIN, int_compare); binomial_heap_free(heap); } + + /* Test for out of memory */ + + alloc_test_set_limit(0); + + assert(binomial_heap_new(BINOMIAL_HEAP_TYPE_MIN, int_compare) == NULL); } void test_binomial_heap_insert(void) @@ -49,10 +55,15 @@ void test_binomial_heap_insert(void) for (i=0; i<1000; ++i) { test_array[i] = i; - binomial_heap_insert(heap, &test_array[i]); + assert(binomial_heap_insert(heap, &test_array[i]) != 0); } assert(binomial_heap_num_entries(heap) == 1000); + /* Test for out of memory */ + + alloc_test_set_limit(0); + assert(binomial_heap_insert(heap, &i) == 0); + binomial_heap_free(heap); } @@ -68,7 +79,7 @@ void test_min_heap(void) for (i=0; i<1000; ++i) { test_array[i] = i; - binomial_heap_insert(heap, &test_array[i]); + assert(binomial_heap_insert(heap, &test_array[i]) != 0); } /* Pop values off the heap and check they are in order */ @@ -81,6 +92,11 @@ void test_min_heap(void) i = *val; } + /* Test pop on an empty heap */ + + val = (int *) binomial_heap_pop(heap); + assert(val == NULL); + binomial_heap_free(heap); } @@ -96,7 +112,7 @@ void test_max_heap(void) for (i=0; i<1000; ++i) { test_array[i] = i; - binomial_heap_insert(heap, &test_array[i]); + assert(binomial_heap_insert(heap, &test_array[i]) != 0); } /* Pop values off the heap and check they are in order */ @@ -109,14 +125,123 @@ void test_max_heap(void) i = *val; } + /* Test pop on an empty heap */ + + val = (int *) binomial_heap_pop(heap); + assert(val == NULL); + binomial_heap_free(heap); } +static BinomialHeap *generate_heap(void) +{ + BinomialHeap *heap; + int i; + + heap = binomial_heap_new(BINOMIAL_HEAP_TYPE_MIN, int_compare); + + /* Push a load of values onto the heap */ + + for (i=0; i<1000; ++i) { + test_array[i] = i; + if (i != 400) { + assert(binomial_heap_insert(heap, &test_array[i]) != 0); + } + } + + return heap; +} + +/* Verify that the values read out of the specified heap are the + * same as those inserted in generate_heap. */ + +static void verify_heap(BinomialHeap *heap) +{ + int *val; + int numvals; + int i; + + numvals = binomial_heap_num_entries(heap); + assert(numvals == 999); + + for (i=0; i<1000; ++i) { + if (i == 400) { + continue; + } + + /* Pop off the next value and check it */ + + val = binomial_heap_pop(heap); + assert(*val == i); + + /* Decrement num values counter */ + + --numvals; + assert(binomial_heap_num_entries(heap) == numvals); + } +} + +/* Test out of memory when doing an insert */ + +static void test_insert_out_of_memory(void) +{ + BinomialHeap *heap; + int i; + + /* There are various memory allocations performed during the insert; + * probe at different limit levels to catch them all. */ + + for (i=0; i<6; ++i) { + heap = generate_heap(); + + /* Insert should fail */ + + alloc_test_set_limit(i); + test_array[400] = 400; + assert(binomial_heap_insert(heap, &test_array[400]) == 0); + alloc_test_set_limit(-1); + + /* Check that the heap is unharmed */ + + verify_heap(heap); + + binomial_heap_free(heap); + } +} + +/* Test out of memory when doing a pop */ + +void test_pop_out_of_memory(void) +{ + BinomialHeap *heap; + int i; + + /* There are various memory allocations performed as part of the merge + * done during the pop. Probe at different limit levels to catch them + * all. */ + + for (i=0; i<6; ++i) { + heap = generate_heap(); + + /* Pop should fail */ + + alloc_test_set_limit(i); + assert(binomial_heap_pop(heap) == NULL); + alloc_test_set_limit(-1); + + /* Check the heap is unharmed */ + + binomial_heap_free(heap); + } +} + static UnitTestFunction tests[] = { test_binomial_heap_new_free, test_binomial_heap_insert, test_min_heap, test_max_heap, + test_insert_out_of_memory, + test_pop_out_of_memory, NULL }; From 2df73861c33d144be4bc6659325f05401e06309c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 14 Sep 2008 01:04:48 +0000 Subject: [PATCH 111/250] Use constants for the number of test values. --- test/test-avl-tree.c | 20 +++++++------ test/test-binary-heap.c | 16 ++++++----- test/test-binomial-heap.c | 57 +++++++++++++++++++++----------------- test/test-hash-functions.c | 18 ++++++------ test/test-hash-table.c | 42 +++++++++++++++------------- 5 files changed, 83 insertions(+), 70 deletions(-) diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index 40dccd1..9f5923a 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -28,7 +28,9 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "avl-tree.h" #include "compare-int.h" -int test_array[1000]; +#define NUM_TEST_VALUES 1000 + +int test_array[NUM_TEST_VALUES]; #if 0 /* Tree print function - useful for debugging. */ @@ -161,7 +163,7 @@ AVLTree *create_tree(void) tree = avl_tree_new((AVLTreeCompareFunc) int_compare); - for (i=0; i<1000; ++i) { + for (i=0; i 0) { val = (int *) binary_heap_pop(heap); diff --git a/test/test-binomial-heap.c b/test/test-binomial-heap.c index ed3b817..d82b8d2 100644 --- a/test/test-binomial-heap.c +++ b/test/test-binomial-heap.c @@ -27,23 +27,25 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "binomial-heap.h" #include "compare-int.h" -int test_array[1000]; +#define NUM_TEST_VALUES 10000 + +int test_array[NUM_TEST_VALUES]; void test_binomial_heap_new_free(void) { BinomialHeap *heap; int i; - for (i=0; i<1000; ++i) { + for (i=0; i 0) { val = (int *) binomial_heap_pop(heap); @@ -125,14 +127,16 @@ void test_max_heap(void) i = *val; } - /* Test pop on an empty heap */ + /* Test pop on an empty heap */ - val = (int *) binomial_heap_pop(heap); - assert(val == NULL); + val = (int *) binomial_heap_pop(heap); + assert(val == NULL); binomial_heap_free(heap); } +#define TEST_VALUE (NUM_TEST_VALUES / 2) + static BinomialHeap *generate_heap(void) { BinomialHeap *heap; @@ -142,9 +146,9 @@ static BinomialHeap *generate_heap(void) /* Push a load of values onto the heap */ - for (i=0; i<1000; ++i) { + for (i=0; i Date: Sun, 14 Sep 2008 01:24:28 +0000 Subject: [PATCH 112/250] Turn off optimisation for test build. --- configure.ac | 30 +++++++++++++++++++++++++----- src/Makefile.am | 5 ++--- test/Makefile.am | 2 +- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index a2f245f..06c81b7 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,21 @@ AC_PROG_LIBTOOL AC_PROG_INSTALL AC_PROG_MAKE_SET +if [[ "$GCC" = "yes" ]]; then + is_gcc=true +else + is_gcc=false +fi + +TEST_CFLAGS="" + +# Turn on all warnings for gcc. Turn off optimisation for the test build. + +if $is_gcc; then + CFLAGS="$CFLAGS -Wall" + TEST_CFLAGS="$TEST_CFLAGS -Wall -O0" +fi + # Support for coverage analysis via gcov: coverage=no @@ -16,11 +31,9 @@ AC_ARG_ENABLE(coverage, [ --enable-coverage Enable coverage testing. ], [ coverage=yes ]) -COV_FLAGS="" - if [[ "$coverage" = "yes" ]]; then - if [[ "$GCC" = "yes" ]]; then - COV_FLAGS="-fprofile-arcs -ftest-coverage" + if $is_gcc; then + TEST_CFLAGS="$TEST_CFLAGS -fprofile-arcs -ftest-coverage" else AC_MSG_ERROR([Can only enable coverage when using gcc.]) fi @@ -43,9 +56,16 @@ fi AM_CONDITIONAL(USE_VALGRIND, $use_valgrind) +# Save the default CFLAGS and clear them, so that the test build +# of the library doesn't get the optimisation flags. + +MAIN_CFLAGS="$CFLAGS" +CFLAGS="" + AM_CONFIG_HEADER(config.h:config.h.in) -AC_SUBST(COV_FLAGS) +AC_SUBST(MAIN_CFLAGS) +AC_SUBST(TEST_CFLAGS) AC_SUBST(ac_aux_dir) AC_OUTPUT([ diff --git a/src/Makefile.am b/src/Makefile.am index 9943a18..70ea750 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,4 @@ -AM_CFLAGS = -Wall - check_LIBRARIES=libcalgtest.a lib_LTLIBRARIES=libcalg.la @@ -18,9 +16,10 @@ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c -libcalgtest_a_CFLAGS=$(COV_FLAGS) -O0 -DALLOC_TESTING -I../test +libcalgtest_a_CFLAGS=$(TEST_CFLAGS) -DALLOC_TESTING -I../test libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) +libcalg_la_CFLAGS=$(MAIN_CFLAGS) libcalg_la_SOURCES=$(SRC) $(MAIN_HEADERFILES) $(CALG_HEADERFILES) headerfilesdir=$(includedir)/libcalg-1.0 diff --git a/test/Makefile.am b/test/Makefile.am index 36ef68e..f3490bb 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -27,7 +27,7 @@ libtestframework_a_SOURCES=\ alloc-testing.c alloc-testing.h \ framework.c framework.h -AM_CFLAGS = $(COV_FLAGS) -I../src -Wall +AM_CFLAGS = $(TEST_CFLAGS) -I../src LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a EXTRA_DIST=valgrind-wrapper From 59aed0d70a63ef1195fc9ad5b4e2cb4d1b2febbd Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 14 Sep 2008 01:43:19 +0000 Subject: [PATCH 113/250] Fix build of test-cpp.cpp to use the proper automake method. --- test/Makefile.am | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index f3490bb..3c5fc40 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,4 +1,8 @@ +AM_CFLAGS = $(TEST_CFLAGS) -I../src +AM_CXXFLAGS = $(AM_CFLAGS) +LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a + if USE_VALGRIND TESTS_ENVIRONMENT=./valgrind-wrapper endif @@ -27,11 +31,7 @@ libtestframework_a_SOURCES=\ alloc-testing.c alloc-testing.h \ framework.c framework.h -AM_CFLAGS = $(TEST_CFLAGS) -I../src -LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a +test_cpp_SOURCES = test-cpp.cpp EXTRA_DIST=valgrind-wrapper -test-cpp: test-cpp.cpp - $(CXX) $(AM_CFLAGS) $^ -o $@ $(LDADD) - From f91ea029ad0655dd7ec3e77ea7426c47608633ee Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 14 Sep 2008 02:05:39 +0000 Subject: [PATCH 114/250] Bump version to v1.2.0, update NEWS and ChangeLog. --- ChangeLog | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++ NEWS | 22 ++++++ configure.ac | 2 +- 3 files changed, 216 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index af7dc81..17e7001 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,196 @@ +2008-09-14 02:43:19 fraggle + + Fix build of test-cpp.cpp to use the proper automake method. + +2008-09-14 02:24:28 fraggle + + Turn off optimisation for test build. + +2008-09-14 02:04:48 fraggle + + Use constants for the number of test values. + +2008-09-13 00:54:04 fraggle + + Expand binomial heap test case to include out of memory scenarios. + +2008-09-04 21:06:13 fraggle + + Reword some of the text about the license. + +2008-09-04 20:53:44 fraggle + + Use a non-recursive algorithm for trie_free. Add a test case for + this. + +2008-09-03 01:48:46 fraggle + + Add script for generating coverage reports from gcov files. + +2008-08-27 22:37:01 fraggle + + Smart indent all source. + +2008-08-27 22:25:09 fraggle + + Add test case for checking the library can be used from C++ programs. + +2008-08-27 21:29:09 fraggle + + Add missing C++ extern "C" declarations to headers. + +2008-08-26 14:41:39 fraggle + + Change allocation limit to limit a number of allocations, not a number + of bytes. + +2008-08-25 23:36:17 fraggle + + Improve coverage for set. + +2008-08-25 22:38:41 fraggle + + Rename test_ functions -> test_trie_. + +2008-08-25 22:36:00 fraggle + + Check return value for trie_insert. + +2008-08-25 22:29:58 fraggle + + Test out of memory scenario for trie, and fix rollback to work + properly. + +2008-08-25 22:28:20 fraggle + + Turn off optimisation for test library build. + +2008-06-23 01:45:28 fraggle + + Make avl_tree_node_parent_side function static, as it is internal. + +2008-06-21 21:24:28 fraggle + + Add out of memory checks for set, hash table. + +2008-06-21 20:05:45 fraggle + + Remove extra calls to find_subtree_height. + +2008-06-19 18:46:24 fraggle + + Add test cases for allocation testing framework. + +2008-06-18 01:36:26 fraggle + + Update Doxyfile to latest Doxygen. + +2008-06-17 22:11:48 fraggle + + Fix doxygen warnings. + +2008-06-17 22:10:58 fraggle + + Put coverage CFLAGS in COV_FLAGS rather than in main CFLAGS. + +2008-06-16 21:37:27 fraggle + + Update comments, add rebalance to root function. + +2008-06-16 20:44:55 fraggle + + Combine rotate_left and rotate_right functions into a single rotate + function. + +2008-06-16 20:24:09 fraggle + + Replace AVL tree node left/right child pointers with a two element + array. Restructure remove_node function to be more obviously correct. + +2008-06-16 20:20:52 fraggle + + Remove alloc testing linked list, as it is unused. + +2008-06-13 20:54:17 fraggle + + More bloom filter and linked list tests. + +2008-06-13 20:53:19 fraggle + + Allow allocations to reach the limit, but not exceed it. + +2008-06-13 20:13:12 fraggle + + Add more AVL tree tests. + +2008-06-13 19:53:23 fraggle + + Improve avl_tree_remove_node testing function. + +2008-06-13 19:49:53 fraggle + + Fix bugs in AVL tree. + +2008-06-13 19:39:49 fraggle + + Add copyright header to valgrind wrapper script. + +2008-06-13 18:59:14 fraggle + + Add missing test framework files. + +2008-06-13 17:47:20 fraggle + + Add check for failed malloc(). + +2008-06-13 01:00:21 fraggle + + Switch to ISC license, update copyright to 2005-2008. + +2008-06-12 20:58:31 fraggle + + Add assertations for [s]list_{prepend,append}, out of memory test + cases. + +2008-06-12 20:40:48 fraggle + + Add the ability to limit memory allocation for testing malloc() out of + memory conditions and a basic test framework for checking that memory + is correctly freed. Add malloc test cases for the queue, binary heap, + and arraylist. + +2008-06-11 23:42:59 fraggle + + Fix Doxygen errors. + +2008-06-11 23:34:05 fraggle + + Move alloc-testing.[ch] to test/ + +2008-06-11 23:18:35 fraggle + + Add initial test framework for testing memory allocation/free. + +2008-06-11 23:09:22 fraggle + + Prepend x to work with empty strings on old shell interpreters. + +2008-06-03 20:47:03 fraggle + + Add configure for compiling with profiling (gcov) and valgrind. + +2008-06-02 21:04:01 fraggle + + Fix memory leaks in unit tests. + +2008-06-02 20:45:14 fraggle + + Fix memory leak in hash table. + +2008-06-01 20:31:06 fraggle + + Update ChangeLog, bump to v1.1.0. + 2008-06-01 20:27:48 fraggle Fix smart-indent to expand tabs to the next tab point rather than diff --git a/NEWS b/NEWS index e129db2..56f8c38 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,26 @@ +v1.2.0 (14th September 2008) + + * The license has been changed to the ISC license. + * Support for compiling with gcc coverage options and running tests in + valgrind. + * All headers now have extern "C" definitions for use in C++ programs. + * Trie free function uses a non-recursive algorithm to avoid the + possibility of stack overflow. + + Test suite: + * Framework added for testing memory allocation/free. + * Tests have been fixed to properly free any memory allocated during + execution of the test. + * Tests have been expanded to increase the code coverage. + * A test case has been added for testing use of the program in C++ + programs. + + Bugs fixed: + * Memory leak in hash table. + * Bugs with the AVL tree. + * Trie responds to out of memory scenarios correctly. + v1.1.0 (1st June 2008) * Added data structures: diff --git a/configure.ac b/configure.ac index 06c81b7..2ede18f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(C Algorithms, 1.1.0, fraggle@users.sourceforge.net, c-algorithms) +AC_INIT(C Algorithms, 1.2.0, fraggle@users.sourceforge.net, c-algorithms) AC_CONFIG_AUX_DIR(autotools) AM_INIT_AUTOMAKE($PACKAGE_TARNAME, $PACKAGE_VERSION, no-define) From 3b36094612b182fdde81cca79abd23d8dfe72648 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 27 Sep 2008 23:44:13 +0000 Subject: [PATCH 115/250] Fix bug with negative characters in trie keys causing crash. Add functions to do insert, lookup and remove of trie entries using binary strings rather than NUL-terminated text strings. Thanks to Giulio Paci for these. --- src/trie.c | 218 +++++++++++++++++++++++++++++++++++++++++++++-- src/trie.h | 51 ++++++++++- test/test-trie.c | 125 +++++++++++++++++++++++++++ 3 files changed, 385 insertions(+), 9 deletions(-) diff --git a/src/trie.c b/src/trie.c index 6962703..a03324a 100644 --- a/src/trie.c +++ b/src/trie.c @@ -117,7 +117,6 @@ static TrieNode *trie_find_end(Trie *trie, char *key) { TrieNode *node; char *p; - int c; /* Search down the trie until the end of string is reached */ @@ -133,7 +132,36 @@ static TrieNode *trie_find_end(Trie *trie, char *key) /* Jump to the next node */ - c = *p; + node = node->next[(unsigned char) *p]; + } + + /* This key is present if the value at the last node is not NULL */ + + return node; +} + +static TrieNode *trie_find_end_binary(Trie *trie, unsigned char *key, + int key_length) +{ + TrieNode *node; + int j; + int c; + + /* Search down the trie until the end of string is reached */ + + node = trie->root_node; + + for (j=0; jnext[c]; } @@ -144,13 +172,13 @@ static TrieNode *trie_find_end(Trie *trie, char *key) /* Roll back an insert operation after a failed malloc() call. */ -static void trie_insert_rollback(Trie *trie, char *key) +static void trie_insert_rollback(Trie *trie, unsigned char *key) { TrieNode *node; TrieNode **prev_ptr; TrieNode *next_node; TrieNode **next_prev_ptr; - char *p; + unsigned char *p; /* Follow the chain along. We know that we will never reach the * end of the string because trie_insert never got that far. As a @@ -165,7 +193,7 @@ static void trie_insert_rollback(Trie *trie, char *key) /* Find the next node now. We might free this node. */ - next_prev_ptr = &node->next[(int) *p]; + next_prev_ptr = &node->next[(unsigned char) *p]; next_node = *next_prev_ptr; ++p; @@ -237,7 +265,7 @@ int trie_insert(Trie *trie, char *key, TrieValue value) /* Allocation failed. Go back and undo * what we have done so far. */ - trie_insert_rollback(trie, key); + trie_insert_rollback(trie, (unsigned char *) key); return 0; } @@ -255,7 +283,7 @@ int trie_insert(Trie *trie, char *key, TrieValue value) /* Current character */ - c = *p; + c = (unsigned char) *p; /* Reached the end of string? If so, we're finished. */ @@ -277,6 +305,167 @@ int trie_insert(Trie *trie, char *key, TrieValue value) return 1; } + +int trie_insert_binary(Trie *trie, unsigned char *key, int key_length, + TrieValue value) +{ + TrieNode **rover; + TrieNode *node; + int p,c; + + /* Cannot insert NULL values */ + + if (value == TRIE_NULL) { + return 0; + } + + /* Search to see if this is already in the tree */ + + node = trie_find_end_binary(trie, key, key_length); + + /* Already in the tree? If so, replace the existing value and + * return success. */ + + if (node != NULL && node->data != TRIE_NULL) { + node->data = value; + return 1; + } + + /* Search down the trie until we reach the end of string, + * creating nodes as necessary */ + + rover = &trie->root_node; + p = 0; + + for (;;) { + + node = *rover; + + if (node == NULL) { + + /* Node does not exist, so create it */ + + node = (TrieNode *) calloc(1, sizeof(TrieNode)); + + if (node == NULL) { + + /* Allocation failed. Go back and undo + * what we have done so far. */ + + trie_insert_rollback(trie, key); + + return 0; + } + + node->data = TRIE_NULL; + + /* Link in to the trie */ + + *rover = node; + } + + /* Increase the node use count */ + + ++node->use_count; + + /* Current character */ + + c = (unsigned char) key[p]; + + /* Reached the end of string? If so, we're finished. */ + + if (p == key_length) { + + /* Set the data at the node we have reached */ + + node->data = value; + + break; + } + + /* Advance to the next node in the chain */ + + rover = &node->next[c]; + ++p; + } + + return 1; +} + +int trie_remove_binary(Trie *trie, unsigned char *key, int key_length) +{ + TrieNode *node; + TrieNode *next; + TrieNode **last_next_ptr; + int p, c; + + /* Find the end node and remove the value */ + + node = trie_find_end_binary(trie, key, key_length); + + if (node != NULL && node->data != TRIE_NULL) { + node->data = TRIE_NULL; + } else { + return 0; + } + + /* Now traverse the tree again as before, decrementing the use + * count of each node. Free back nodes as necessary. */ + + node = trie->root_node; + last_next_ptr = &trie->root_node; + p = 0; + + for (;;) { + + /* Find the next node */ + c = (unsigned char) key[p]; + next = node->next[c]; + + /* Free this node if necessary */ + + --node->use_count; + + if (node->use_count <= 0) { + free(node); + + /* Set the "next" pointer on the previous node to NULL, + * to unlink the freed node from the tree. This only + * needs to be done once in a remove. After the first + * unlink, all further nodes are also going to be + * free'd. */ + + if (last_next_ptr != NULL) { + *last_next_ptr = NULL; + last_next_ptr = NULL; + } + } + + /* Go to the next character or finish */ + if (p == key_length) { + break; + } else { + ++p; + } + + /* If necessary, save the location of the "next" pointer + * so that it may be set to NULL on the next iteration if + * the next node visited is freed. */ + + if (last_next_ptr != NULL) { + last_next_ptr = &node->next[c]; + } + + /* Jump to the next node */ + + node = next; + } + + /* Removed successfully */ + + return 1; +} + int trie_remove(Trie *trie, char *key) { TrieNode *node; @@ -306,7 +495,7 @@ int trie_remove(Trie *trie, char *key) /* Find the next node */ - c = *p; + c = (unsigned char) *p; next = node->next[c]; /* Free this node if necessary */ @@ -367,6 +556,19 @@ TrieValue trie_lookup(Trie *trie, char *key) } } +TrieValue trie_lookup_binary(Trie *trie, unsigned char *key, int key_length) +{ + TrieNode *node; + + node = trie_find_end_binary(trie, key, key_length); + + if (node != NULL) { + return node->data; + } else { + return TRIE_NULL; + } +} + int trie_num_entries(Trie *trie) { /* To find the number of entries, simply look at the use count diff --git a/src/trie.h b/src/trie.h index 7b0525e..d141336 100644 --- a/src/trie.h +++ b/src/trie.h @@ -81,7 +81,8 @@ Trie *trie_new(void); void trie_free(Trie *trie); /** - * Insert a new key-value pair into a trie. + * Insert a new key-value pair into a trie. The key is a NUL-terminated + * string. For binary strings, use @ref trie_insert_binary. * * @param trie The trie. * @param key The key to access the new value. @@ -93,8 +94,26 @@ void trie_free(Trie *trie); int trie_insert(Trie *trie, char *key, TrieValue value); +/** + * Insert a new key-value pair into a trie. The key is a sequence of bytes. + * For a key that is a NUL-terminated text string, use @ref trie_insert. + * + * @param trie The trie. + * @param key The key to access the new value. + * @param key_length The key length in bytes. + * @param value The value. + * @return Non-zero if the value was inserted successfully, + * or zero if it was not possible to allocate + * memory for the new entry. + */ + +int trie_insert_binary(Trie *trie, unsigned char *key, + int key_length, TrieValue value); + /** * Look up a value from its key in a trie. + * The key is a NUL-terminated string; for binary strings, use + * @ref trie_lookup_binary. * * @param trie The trie. * @param key The key. @@ -104,8 +123,24 @@ int trie_insert(Trie *trie, char *key, TrieValue value); TrieValue trie_lookup(Trie *trie, char *key); +/** + * Look up a value from its key in a trie. + * The key is a sequence of bytes; for a key that is a NUL-terminated + * text string, use @ref trie_lookup. + * + * @param trie The trie. + * @param key The key. + * @param key_length The key length in bytes. + * @return The value associated with the key, or + * @ref TRIE_NULL if not found in the trie. + */ + +TrieValue trie_lookup_binary(Trie *trie, unsigned char *key, int key_length); + /** * Remove an entry from a trie. + * The key is a NUL-terminated string; for binary strings, use + * @ref trie_lookup_binary. * * @param trie The trie. * @param key The key of the entry to remove. @@ -115,6 +150,20 @@ TrieValue trie_lookup(Trie *trie, char *key); int trie_remove(Trie *trie, char *key); +/** + * Remove an entry from a trie. + * The key is a sequence of bytes; for a key that is a NUL-terminated + * text string, use @ref trie_lookup. + * + * @param trie The trie. + * @param key The key of the entry to remove. + * @param key_length The key length in bytes. + * @return Non-zero if the key was removed successfully, + * or zero if it is not present in the trie. + */ + +int trie_remove_binary(Trie *trie, unsigned char *key, int key_length); + /** * Find the number of entries in a trie. * diff --git a/test/test-trie.c b/test/test-trie.c index dbb0416..3bd0330 100644 --- a/test/test-trie.c +++ b/test/test-trie.c @@ -32,6 +32,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. int test_array[NUM_TEST_VALUES]; char test_strings[NUM_TEST_VALUES][10]; +unsigned char bin_key[] = { 'a', 'b', 'c', 0, 1, 2, 0xff }; +unsigned char bin_key2[] = { 'a', 'b', 'c', 0, 1, 2, 0xff, 0 }; +unsigned char bin_key3[] = { 'a', 'b', 'c' }; +unsigned char bin_key4[] = { 'z', 0, 'z', 'z' }; Trie *generate_trie(void) { @@ -254,6 +258,123 @@ static void test_trie_free_long(void) free(long_string); } +/* Test the use of the trie when characters in the keys used are negative + * (top bit set in the character; alternative, c >= 128). */ + +static void test_trie_negative_keys(void) +{ + char my_key[] = { 'a', 'b', 'c', -50, -20, '\0' }; + Trie *trie; + void *value; + + trie = trie_new(); + + assert(trie_insert(trie, my_key, "hello world") != 0); + + value = trie_lookup(trie, my_key); + + assert(!strcmp(value, "hello world")); + + assert(trie_remove(trie, my_key) != 0); + assert(trie_remove(trie, my_key) == 0); + assert(trie_lookup(trie, my_key) == NULL); + + trie_free(trie); +} + +Trie *generate_binary_trie(void) +{ + Trie *trie; + + trie = trie_new(); + + /* Insert some values */ + + assert(trie_insert_binary(trie, + bin_key2, sizeof(bin_key2), + "goodbye world") != 0); + assert(trie_insert_binary(trie, + bin_key, sizeof(bin_key), + "hello world") != 0); + + return trie; +} + +void test_trie_insert_binary(void) +{ + Trie *trie; + char *value; + + trie = generate_binary_trie(); + + /* Overwrite a value */ + + assert(trie_insert_binary(trie, + bin_key, sizeof(bin_key), + "hi world") != 0); + + /* Insert NULL value doesn't work */ + + assert(trie_insert_binary(trie, bin_key3, sizeof(bin_key3), NULL) == 0); + + /* Read them back */ + + value = trie_lookup_binary(trie, bin_key, sizeof(bin_key)); + assert(!strcmp(value, "hi world")); + + value = trie_lookup_binary(trie, bin_key2, sizeof(bin_key2)); + assert(!strcmp(value, "goodbye world")); + + trie_free(trie); +} + +void test_trie_insert_out_of_memory(void) +{ + Trie *trie; + + trie = generate_binary_trie(); + + alloc_test_set_limit(3); + + assert(trie_insert_binary(trie, + bin_key4, sizeof(bin_key4), + "test value") == 0); + + assert(trie_lookup_binary(trie, bin_key4, sizeof(bin_key4)) == NULL); + assert(trie_num_entries(trie) == 2); + + trie_free(trie); +} + +void test_trie_remove_binary(void) +{ + Trie *trie; + void *value; + + trie = generate_binary_trie(); + + /* Test look up and remove of invalid values */ + + value = trie_lookup_binary(trie, bin_key3, sizeof(bin_key3)); + assert(value == NULL); + + assert(trie_remove_binary(trie, bin_key3, sizeof(bin_key3)) == 0); + + assert(trie_lookup_binary(trie, bin_key4, sizeof(bin_key4)) == 0); + assert(trie_remove_binary(trie, bin_key4, sizeof(bin_key4)) == 0); + + /* Remove the two values */ + + assert(trie_remove_binary(trie, bin_key2, sizeof(bin_key2)) != 0); + assert(trie_lookup_binary(trie, bin_key2, sizeof(bin_key2)) == NULL); + assert(trie_lookup_binary(trie, bin_key, sizeof(bin_key)) != NULL); + + assert(trie_remove_binary(trie, bin_key, sizeof(bin_key)) != 0); + assert(trie_lookup_binary(trie, bin_key, sizeof(bin_key)) == NULL); + + trie_free(trie); +} + static UnitTestFunction tests[] = { test_trie_new_free, test_trie_insert, @@ -262,6 +383,10 @@ static UnitTestFunction tests[] = { test_trie_replace, test_trie_insert_empty, test_trie_free_long, + test_trie_negative_keys, + test_trie_insert_binary, + test_trie_insert_out_of_memory, + test_trie_remove_binary, NULL }; From ec9061022668d50c93ef8a82e6cdc285aef74523 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 1 Oct 2008 20:23:59 +0000 Subject: [PATCH 116/250] Add local vim project settings file. --- .lvimrc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .lvimrc diff --git a/.lvimrc b/.lvimrc new file mode 100644 index 0000000..6cbc45f --- /dev/null +++ b/.lvimrc @@ -0,0 +1,6 @@ +" Local vimrc configuration file. Install the localvimrc.vim vim script. +set noexpandtab +set tabstop=8 +set softtabstop=8 +set shiftwidth=8 + From b1e06c4be1f07f8b4eb60bc3aacb1d6dbdf46372 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 10 Nov 2008 23:18:56 +0000 Subject: [PATCH 117/250] Compile tests in debug mode. --- src/Makefile.am | 2 +- test/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 70ea750..7dbc284 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c -libcalgtest_a_CFLAGS=$(TEST_CFLAGS) -DALLOC_TESTING -I../test +libcalgtest_a_CFLAGS=$(TEST_CFLAGS) -DALLOC_TESTING -I../test -g libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) libcalg_la_CFLAGS=$(MAIN_CFLAGS) diff --git a/test/Makefile.am b/test/Makefile.am index 3c5fc40..f59780a 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,5 +1,5 @@ -AM_CFLAGS = $(TEST_CFLAGS) -I../src +AM_CFLAGS = $(TEST_CFLAGS) -I../src -g AM_CXXFLAGS = $(AM_CFLAGS) LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a From c27b8ce9a68d513be49a36a606b63c3485c4d398 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 10 Nov 2008 23:26:38 +0000 Subject: [PATCH 118/250] Initial red-black tree implementation (incomplete). --- src/Makefile.am | 4 +- src/libcalg.h | 1 + src/rb-tree.c | 506 ++++++++++++++++++++++++++++++++++++++++++++ src/rb-tree.h | 296 ++++++++++++++++++++++++++ test/Makefile.am | 1 + test/test-rb-tree.c | 382 +++++++++++++++++++++++++++++++++ 6 files changed, 1188 insertions(+), 2 deletions(-) create mode 100644 src/rb-tree.c create mode 100644 src/rb-tree.h create mode 100644 test/test-rb-tree.c diff --git a/src/Makefile.am b/src/Makefile.am index 7dbc284..1f87723 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,13 +8,13 @@ CALG_HEADERFILES=\ arraylist.h compare-int.h hash-int.h hash-table.h set.h \ avl-tree.h compare-pointer.h hash-pointer.h list.h slist.h \ queue.h compare-string.h hash-string.h trie.h binary-heap.h \ -bloom-filter.h binomial-heap.h +bloom-filter.h binomial-heap.h rb-tree.h SRC=\ arraylist.c compare-pointer.c hash-pointer.c list.c slist.c \ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ -bloom-filter.c binomial-heap.c +bloom-filter.c binomial-heap.c rb-tree.c libcalgtest_a_CFLAGS=$(TEST_CFLAGS) -DALLOC_TESTING -I../test -g libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) diff --git a/src/libcalg.h b/src/libcalg.h index e1c22d4..fc50a4c 100644 --- a/src/libcalg.h +++ b/src/libcalg.h @@ -37,6 +37,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include diff --git a/src/rb-tree.c b/src/rb-tree.c new file mode 100644 index 0000000..fe788c0 --- /dev/null +++ b/src/rb-tree.c @@ -0,0 +1,506 @@ + +/* + +Copyright (c) 2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +#include + +#include "rb-tree.h" + +/* malloc() / free() testing */ + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + +struct _RBTreeNode { + RBTreeNodeColor color; + RBTreeKey key; + RBTreeValue value; + RBTreeNode *parent; + RBTreeNode *children[2]; +}; + +struct _RBTree { + RBTreeNode *root_node; + RBTreeCompareFunc compare_func; + int num_nodes; +}; + +static RBTreeNodeSide rb_tree_node_side(RBTreeNode *node) +{ + if (node->parent->children[RB_TREE_NODE_LEFT] == node) { + return RB_TREE_NODE_LEFT; + } else { + return RB_TREE_NODE_RIGHT; + } +} + +static RBTreeNode *rb_tree_node_sibling(RBTreeNode *node) +{ + RBTreeNodeSide side; + + side = rb_tree_node_side(node); + + return node->parent->children[1 - side]; +} + +RBTreeNode *rb_tree_node_uncle(RBTreeNode *node) +{ + return rb_tree_node_sibling(node->parent); +} + +/* Replace node1 with node2 at its parent. */ + +static void rb_tree_node_replace(RBTree *tree, RBTreeNode *node1, + RBTreeNode *node2) +{ + int side; + + /* Set the node's parent pointer. */ + + if (node2 != NULL) { + node2->parent = node1->parent; + } + + /* The root node? */ + + if (node1->parent == NULL) { + tree->root_node = node2; + } else { + side = rb_tree_node_side(node1); + node1->parent->children[side] = node2; + } +} + +/* Rotate a section of the tree. 'node' is the node at the top + * of the section to be rotated. 'direction' is the direction in + * which to rotate the tree: left or right, as shown in the following + * diagram: + * + * Left rotation: Right rotation: + * + * B D + * / \ / \ + * A D B E + * / \ / \ + * C E A C + + * is rotated to: is rotated to: + * + * D B + * / \ / \ + * B E A D + * / \ / \ + * A C C E + */ + +static RBTreeNode *rb_tree_rotate(RBTree *tree, RBTreeNode *node, + RBTreeNodeSide direction) +{ + RBTreeNode *new_root; + + /* The child of this node will take its place: + for a left rotation, it is the right child, and vice versa. */ + + new_root = node->children[1-direction]; + + /* Make new_root the root, update parent pointers. */ + + rb_tree_node_replace(tree, node, new_root); + + /* Rearrange pointers */ + + node->children[1-direction] = new_root->children[direction]; + new_root->children[direction] = node; + + /* Update parent references */ + + node->parent = new_root; + + if (node->children[1-direction] != NULL) { + node->children[1-direction]->parent = node; + } + + return new_root; +} + + +RBTree *rb_tree_new(RBTreeCompareFunc compare_func) +{ + RBTree *new_tree; + + new_tree = malloc(sizeof(RBTree)); + + if (new_tree == NULL) { + return NULL; + } + + new_tree->root_node = NULL; + new_tree->num_nodes = 0; + new_tree->compare_func = compare_func; + + return new_tree; +} + +static void rb_tree_free_subtree(RBTreeNode *node) +{ + if (node != NULL) { + /* Recurse to subnodes */ + + rb_tree_free_subtree(node->children[RB_TREE_NODE_LEFT]); + rb_tree_free_subtree(node->children[RB_TREE_NODE_RIGHT]); + + /* Free this node */ + + free(node); + } +} + +void rb_tree_free(RBTree *tree) +{ + /* Free all nodes in the tree */ + + rb_tree_free_subtree(tree->root_node); + + /* Free back the main tree structure */ + + free(tree); +} + +static void rb_tree_insert_case1(RBTree *tree, RBTreeNode *node); +static void rb_tree_insert_case2(RBTree *tree, RBTreeNode *node); +static void rb_tree_insert_case3(RBTree *tree, RBTreeNode *node); +static void rb_tree_insert_case4(RBTree *tree, RBTreeNode *node); +static void rb_tree_insert_case5(RBTree *tree, RBTreeNode *node); + +/* Insert case 1: If the new node is at the root of the tree, it must + * be recolored black, as the root is always black. */ + +static void rb_tree_insert_case1(RBTree *tree, RBTreeNode *node) +{ + if (node->parent == NULL) { + + /* The root node is black */ + + node->color = RB_TREE_NODE_BLACK; + + } else { + + /* Not root */ + + rb_tree_insert_case2(tree, node); + } +} + +/* Insert case 2: If the parent of the new node is red, this + * conflicts with the red-black tree conditions, as both children + * of every red node are black. */ + +static void rb_tree_insert_case2(RBTree *tree, RBTreeNode *node) +{ + /* Note that if this function is being called, we already know + * the node has a parent, as it is not the root node. */ + + if (node->parent->color != RB_TREE_NODE_BLACK) { + rb_tree_insert_case3(tree, node); + } +} + +/* Insert case 3: If the parent and uncle are both red, repaint them + * both black and repaint the grandparent red. */ + +static void rb_tree_insert_case3(RBTree *tree, RBTreeNode *node) +{ + RBTreeNode *grandparent; + RBTreeNode *uncle; + + /* Note that the node must have a grandparent, as the parent + * is red, and the root node is always black. */ + + grandparent = node->parent->parent; + uncle = rb_tree_node_uncle(node); + + if (uncle != NULL && uncle->color == RB_TREE_NODE_RED) { + + node->parent->color = RB_TREE_NODE_BLACK; + uncle->color = RB_TREE_NODE_BLACK; + grandparent->color = RB_TREE_NODE_RED; + + /* Recurse to grandparent */ + + rb_tree_insert_case1(tree, grandparent); + + } else { + rb_tree_insert_case4(tree, node); + } +} + +/* Case 4: If the parent is red, but the uncle is black, we need to do + * some rotations to keep the tree balanced and complying with the tree + * conditions. If the node is on the opposite side relative to its parent + * as the parent is relative to its grandparent, rotate around the + * parent. Either way, we will continue to case 5. + * + * eg. + * + * B B + * / \ / \ + * R B -> node -> R B + * \ / + * R <- node R + * + */ + +void rb_tree_insert_case4(RBTree *tree, RBTreeNode *node) +{ + RBTreeNode *next_node; + RBTreeNodeSide side; + + /* Note that at this point, by implication from case 3, we know + * that the parent is red, but the uncle is black. We therefore + * only need to examine what side the node is on relative + * to its parent, and the side the parent is on relative to + * the grandparent. */ + + side = rb_tree_node_side(node); + + if (side != rb_tree_node_side(node->parent)) { + + /* After the rotation, we will continue to case 5, but + * the parent node will be at the bottom. */ + + next_node = node->parent; + + /* Rotate around the parent in the opposite direction + * to side. */ + + rb_tree_rotate(tree, node->parent, 1-side); + } else { + next_node = node; + } + + rb_tree_insert_case5(tree, next_node); +} + +/* Case 5: The node is on the same side relative to its parent as the + * parent is relative to its grandparent. The node and its parent are + * red, but the uncle is black. + * + * Now, rotate at the grandparent and recolor the parent and grandparent + * to black and red respectively. + * + * G/B P/B + * / \ / \ + * P/R U/B -> N/R G/R + * / \ / \ + * N/R ? ? U/B + * + */ + +void rb_tree_insert_case5(RBTree *tree, RBTreeNode *node) +{ + RBTreeNode *parent; + RBTreeNode *grandparent; + RBTreeNodeSide side; + + parent = node->parent; + grandparent = parent->parent; + + /* What side are we, relative to the parent? This will determine + * the direction that we rotate. */ + + side = rb_tree_node_side(node); + + /* Rotate at the grandparent, in the opposite direction to side. */ + + rb_tree_rotate(tree, grandparent, 1-side); + + /* Recolor the (old) parent and grandparent. */ + + parent->color = RB_TREE_NODE_BLACK; + grandparent->color = RB_TREE_NODE_RED; +} + +RBTreeNode *rb_tree_insert(RBTree *tree, RBTreeKey key, RBTreeValue value) +{ + RBTreeNode *node; + RBTreeNode **rover; + RBTreeNode *parent; + RBTreeNodeSide side; + + /* Allocate a new node */ + + node = malloc(sizeof(RBTreeNode)); + + if (node == NULL) { + return NULL; + } + + /* Set up structure. Initially, the node is red. */ + + node->key = key; + node->value = value; + node->color = RB_TREE_NODE_RED; + node->children[RB_TREE_NODE_LEFT] = NULL; + node->children[RB_TREE_NODE_RIGHT] = NULL; + + /* First, perform a normal binary tree-style insert. */ + + parent = NULL; + rover = &tree->root_node; + + while (*rover != NULL) { + + /* Update parent */ + + parent = *rover; + + /* Choose which path to go down, left or right child */ + + if (tree->compare_func(value, (*rover)->value) < 0) { + side = RB_TREE_NODE_LEFT; + } else { + side = RB_TREE_NODE_RIGHT; + } + + rover = &(*rover)->children[side]; + } + + /* Insert at the position we have reached */ + + *rover = node; + node->parent = parent; + + /* Possibly reorder the tree. */ + + rb_tree_insert_case1(tree, node); + + /* Update the node count */ + + ++tree->num_nodes; + + return node; +} + +RBTreeNode *rb_tree_lookup_node(RBTree *tree, RBTreeKey key) +{ + RBTreeNode *node; + RBTreeNodeSide side; + int diff; + + node = tree->root_node; + + /* Search down the tree. */ + + while (node != NULL) { + diff = tree->compare_func(key, node->key); + + if (diff == 0) { + return node; + } else if (diff < 0) { + side = RB_TREE_NODE_LEFT; + } else { + side = RB_TREE_NODE_RIGHT; + } + + node = node->children[side]; + } + + /* Not found. */ + + return NULL; +} + +RBTreeValue rb_tree_lookup(RBTree *tree, RBTreeKey key) +{ + RBTreeNode *node; + + /* Find the node for this key. */ + + node = rb_tree_lookup_node(tree, key); + + if (node == NULL) { + return RB_TREE_NULL; + } else { + return node->value; + } +} + +void rb_tree_remove_node(RBTree *tree, RBTreeNode *node) +{ + /* TODO */ +} + +int rb_tree_remove(RBTree *tree, RBTreeKey key) +{ + RBTreeNode *node; + + /* Find the node to remove. */ + + node = rb_tree_lookup_node(tree, key); + + if (node == NULL) { + return 0; + } + + rb_tree_remove_node(tree, node); + + return 1; +} + +RBTreeNode *rb_tree_root_node(RBTree *tree) +{ + return tree->root_node; +} + +RBTreeKey rb_tree_node_key(RBTreeNode *node) +{ + return node->key; +} + +RBTreeValue rb_tree_node_value(RBTreeNode *node) +{ + return node->value; +} + +RBTreeNode *rb_tree_node_child(RBTreeNode *node, RBTreeNodeSide side) +{ + if (side == RB_TREE_NODE_LEFT || side == RB_TREE_NODE_RIGHT) { + return node->children[side]; + } else { + return NULL; + } +} + +RBTreeNode *rb_tree_node_parent(RBTreeNode *node) +{ + return node->parent; +} + +RBTreeValue *rb_tree_to_array(RBTree *tree) +{ + /* TODO */ +} + +int rb_tree_num_entries(RBTree *tree) +{ + return tree->num_nodes; +} + diff --git a/src/rb-tree.h b/src/rb-tree.h new file mode 100644 index 0000000..1b23165 --- /dev/null +++ b/src/rb-tree.h @@ -0,0 +1,296 @@ +/* + +Copyright (c) 2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +/** @file rbtree.h + * + * @brief Balanced binary tree + * + * The red-black tree structure is a balanced binary tree which stores + * a collection of nodes (see @ref RBTreeNode). Each node has + * a key and a value associated with it. The nodes are sorted + * within the tree based on the order of their keys. Modifications + * to the tree are constructed such that the tree remains + * balanced at all times (there are always roughly equal numbers + * of nodes on either side of the tree). + * + * Balanced binary trees have several uses. They can be used + * as a mapping (searching for a value based on its key), or + * as a set of keys which is always ordered. + * + * To create a new red-black tree, use @ref rb_tree_new. To destroy + * a red-black tree, use @ref rb_tree_free. + * + * To insert a new key-value pair into a red-black tree, use + * @ref rb_tree_insert. To remove an entry from a + * red-black tree, use @ref rb_tree_remove or @ref rb_tree_remove_node. + * + * To search a red-black tree, use @ref rb_tree_lookup or + * @ref rb_tree_lookup_node. + * + * Tree nodes can be queried using the + * @ref rb_tree_node_left_child, + * @ref rb_tree_node_right_child, + * @ref rb_tree_node_parent, + * @ref rb_tree_node_key and + * @ref rb_tree_node_value functions. + */ + +#ifndef ALGORITHM_RB_TREE_H +#define ALGORITHM_RB_TREE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A red-black tree balanced binary tree. + * + * @see rb_tree_new + */ + +typedef struct _RBTree RBTree; + +/** + * A key for an @ref RBTree. + */ + +typedef void *RBTreeKey; + +/** + * A value stored in an @ref RBTree. + */ + +typedef void *RBTreeValue; + +/** + * A null @ref RBTreeValue. + */ + +#define RB_TREE_NULL ((void *) 0) + +/** + * A node in a red-black tree. + * + * @see rb_tree_node_left_child + * @see rb_tree_node_right_child + * @see rb_tree_node_parent + * @see rb_tree_node_key + * @see rb_tree_node_value + */ + +typedef struct _RBTreeNode RBTreeNode; + +/** + * Type of function used to compare keys in a red-black tree. + * + * @param data1 The first key. + * @param data2 The second key. + * @return A negative number if data1 should be sorted + * before data2, a positive number if data2 should + * be sorted before data1, zero if the two keys + * are equal. + */ + +typedef int (*RBTreeCompareFunc)(RBTreeValue data1, RBTreeValue data2); + +/** + * Each node in a red-black tree is either red or black. + */ + +typedef enum { + RB_TREE_NODE_RED, + RB_TREE_NODE_BLACK, +} RBTreeNodeColor; + +/** + * A @ref RBTreeNode can have left and right children. + */ + +typedef enum { + RB_TREE_NODE_LEFT = 0, + RB_TREE_NODE_RIGHT = 1 +} RBTreeNodeSide; + +/** + * Create a new red-black tree. + * + * @param compare_func Function to use when comparing keys in the tree. + * @return A new red-black tree, or NULL if it was not possible + * to allocate the memory. + */ + +RBTree *rb_tree_new(RBTreeCompareFunc compare_func); + +/** + * Destroy a red-black tree. + * + * @param tree The tree to destroy. + */ + +void rb_tree_free(RBTree *tree); + +/** + * Insert a new key-value pair into a red-black tree. + * + * @param tree The tree. + * @param key The key to insert. + * @param value The value to insert. + * @return The newly created tree node containing the + * key and value, or NULL if it was not possible + * to allocate the new memory. + */ + +RBTreeNode *rb_tree_insert(RBTree *tree, RBTreeKey key, RBTreeValue value); + +/** + * Remove a node from a tree. + * + * @param tree The tree. + * @param node The node to remove + */ + +void rb_tree_remove_node(RBTree *tree, RBTreeNode *node); + +/** + * Remove an entry from a tree, specifying the key of the node to + * remove. + * + * @param tree The tree. + * @param key The key of the node to remove. + * @return Zero (false) if no node with the specified key was + * found in the tree, non-zero (true) if a node with + * the specified key was removed. + */ + +int rb_tree_remove(RBTree *tree, RBTreeKey key); + +/** + * Search a red-black tree for a node with a particular key. This uses + * the tree as a mapping. + * + * @param tree The red-black tree to search. + * @param key The key to search for. + * @return The tree node containing the given key, or NULL + * if no entry with the given key is found. + */ + +RBTreeNode *rb_tree_lookup_node(RBTree *tree, RBTreeKey key); + +/** + * Search a red-black tree for a value corresponding to a particular key. + * This uses the tree as a mapping. Note that this performs + * identically to @ref rb_tree_lookup_node, except that the value + * at the node is returned rather than the node itself. + * + * @param tree The red-black tree to search. + * @param key The key to search for. + * @return The value associated with the given key, or + * RB_TREE_NULL if no entry with the given key is + * found. + */ + +RBTreeValue rb_tree_lookup(RBTree *tree, RBTreeKey key); + +/** + * Find the root node of a tree. + * + * @param tree The tree. + * @return The root node of the tree, or NULL if the tree is + * empty. + */ + +RBTreeNode *rb_tree_root_node(RBTree *tree); + +/** + * Retrieve the key for a given tree node. + * + * @param node The tree node. + * @return The key to the given node. + */ + +RBTreeKey rb_tree_node_key(RBTreeNode *node); + +/** + * Retrieve the value at a given tree node. + * + * @param node The tree node. + * @return The value at the given node. + */ + +RBTreeValue rb_tree_node_value(RBTreeNode *node); + +/** + * Get a child of a given tree node. + * + * @param node The tree node. + * @param side The side relative to the node. + * @return The child of the tree node, or NULL if the + * node has no child on the specified side. + */ + +RBTreeNode *rb_tree_node_child(RBTreeNode *node, RBTreeNodeSide side); + +/** + * Find the parent node of a given tree node. + * + * @param node The tree node. + * @return The parent node of the tree node, or NULL if + * this is the root node. + */ + +RBTreeNode *rb_tree_node_parent(RBTreeNode *node); + +/** + * Find the height of a subtree. + * + * @param node The root node of the subtree. + * @return The height of the subtree. + */ + +int rb_tree_subtree_height(RBTreeNode *node); + +/** + * Convert the keys in a red-black tree into a C array. This allows + * the tree to be used as an ordered set. + * + * @param tree The tree. + * @return A newly allocated C array containing all the keys + * in the tree, in order. The length of the array + * is equal to the number of entries in the tree + * (see @ref rb_tree_num_entries). + */ + +RBTreeValue *rb_tree_to_array(RBTree *tree); + +/** + * Retrieve the number of entries in the tree. + * + * @param tree The tree. + * @return The number of key-value pairs stored in the tree. + */ + +int rb_tree_num_entries(RBTree *tree); + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef ALGORITHM_RB_TREE_H */ + diff --git a/test/Makefile.am b/test/Makefile.am index f59780a..f34da95 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -21,6 +21,7 @@ TESTS = \ test-compare-functions \ test-hash-functions \ test-hash-table \ + test-rb-tree \ test-set \ test-trie diff --git a/test/test-rb-tree.c b/test/test-rb-tree.c new file mode 100644 index 0000000..f56ff14 --- /dev/null +++ b/test/test-rb-tree.c @@ -0,0 +1,382 @@ +/* + +Copyright (c) 2008, Simon Howard + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +#include +#include +#include + +#include "alloc-testing.h" +#include "framework.h" + +#include "rb-tree.h" +#include "compare-int.h" + +#define NUM_TEST_VALUES 1000 + +int test_array[NUM_TEST_VALUES]; + +#if 0 +/* Tree print function - useful for debugging. */ + +static void print_tree(RBTreeNode *node, int depth) +{ + int *value; + int i; + + if (node == NULL) { + return; + } + + print_tree(rb_tree_node_child(node, RB_TREE_NODE_LEFT), depth + 1); + + for (i=0; i right_height) { + return left_height + 1; + } else { + return right_height + 1; + } +} + +void validate_tree(RBTree *tree) +{ +} + +RBTree *create_tree(void) +{ + RBTree *tree; + int i; + + /* Create a tree and fill with nodes */ + + tree = rb_tree_new((RBTreeCompareFunc) int_compare); + + for (i=0; i Date: Thu, 27 Nov 2008 20:39:34 +0000 Subject: [PATCH 119/250] Use "nothing up my sleeve" numbers for the bloom filter salts, derived from "A Million Random Digits with 100,000 Normal Deviates". --- src/bloom-filter.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/bloom-filter.c b/src/bloom-filter.c index 1a1604a..a4750b9 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -36,26 +36,36 @@ struct _BloomFilter { unsigned int num_functions; }; -/* Salt values. These salts are XORed with the output of the hash - * function to give multiple unique hashes. */ +/* Salt values. These salts are XORed with the output of the hash function to + * give multiple unique hashes. + * + * These are "nothing up my sleeve" numbers: they are derived from the first + * 256 numbers in the book "A Million Random Digits with 100,000 Normal + * Deviates" published by the RAND corporation, ISBN 0-8330-3047-7. + * + * The numbers here were derived by taking each number from the book in turn, + * then multiplying by 256 and dividing by 100,000 to give a byte range value. + * Groups of four numbers were then combined to give 32-bit integers, most + * significant byte first. + */ static const unsigned int salts[] = { - 0x5cee4612, 0xb5587b1c, 0xa250f2b0, 0xa3bf6d2a, - 0x7a81bd1a, 0x92888d7f, 0x1dc977c7, 0xedc96624, - 0x920c85d9, 0xf16066b3, 0xc6f0d4b3, 0x2b76eb86, - 0xcacb3893, 0x493d81c5, 0xf5a133ac, 0x039740bf, - 0x162b8224, 0xf841de90, 0xc3e5090d, 0x3bce93a7, - 0xf1860334, 0xe832b5f1, 0xf5b6535b, 0xe4cf4fa6, - 0x8357b769, 0x1442b07a, 0x21c5863d, 0xabc0d846, - 0x6dc0d77a, 0x23a3992c, 0xe12179ba, 0xd81d1e23, - 0xcff4727b, 0xe957ecfb, 0xee8f391a, 0x426efa23, - 0x3a34ff2c, 0x8b875d94, 0x34fd0f63, 0xf159daae, - 0xaabab8b3, 0xa83a07ba, 0x4e54fb33, 0xfb82fab8, - 0x2ae2888f, 0xd1a307a8, 0xbe33322d, 0x87c73f86, - 0x7270fa7e, 0x68673c55, 0x2c8026d0, 0xead8e422, - 0xa3ee5132, 0xecb67767, 0x1c3b1ae5, 0x47adf5b6, - 0xf4518d30, 0x46e62797, 0x9889aa76, 0x1405aadf, - 0xf62f9124, 0x5c435ac5, 0x35b8dfe3, 0x651c08c5, + 0x1953c322, 0x588ccf17, 0x64bf600c, 0xa6be3f3d, + 0x341a02ea, 0x15b03217, 0x3b062858, 0x5956fd06, + 0x18b5624f, 0xe3be0b46, 0x20ffcd5c, 0xa35dfd2b, + 0x1fc4a9bf, 0x57c45d5c, 0xa8661c4a, 0x4f1b74d2, + 0x5a6dde13, 0x3b18dac6, 0x05a8afbf, 0xbbda2fe2, + 0xa2520d78, 0xe7934849, 0xd541bc75, 0x09a55b57, + 0x9b345ae2, 0xfc2d26af, 0x38679cef, 0x81bd1e0d, + 0x654681ae, 0x4b3d87ad, 0xd5ff10fb, 0x23b32f67, + 0xafc7e366, 0xdd955ead, 0xe7c34b1c, 0xfeace0a6, + 0xeb16f09d, 0x3c57a72d, 0x2c8294c5, 0xba92662a, + 0xcd5b2d14, 0x743936c8, 0x2489beff, 0xc6c56e00, + 0x74a4f606, 0xb244a94a, 0x5edfc423, 0xf1901934, + 0x24af7691, 0xf6c98b25, 0xea25af46, 0x76d5f2e6, + 0x5e33cdf2, 0x445eb357, 0x88556bd2, 0x70d1da7a, + 0x54449368, 0x381020bc, 0x1c0520bf, 0xf7e44942, + 0xa27e2a58, 0x66866fc5, 0x12519ce7, 0x437a8456, }; BloomFilter *bloom_filter_new(unsigned int table_size, From 0acb69684ecffbea878a70d1d3a8215365d77866 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 19 Jul 2009 19:32:28 +0000 Subject: [PATCH 120/250] Turn on compiler warnings for signed/unsigned comparison/conversion. Fix up warnings generated by compiler. --- configure.ac | 5 ++- src/arraylist.c | 25 +++++++------ src/arraylist.h | 20 ++++++---- src/avl-tree.c | 10 ++--- src/avl-tree.h | 2 +- src/binary-heap.c | 28 +++++++------- src/binary-heap.h | 2 +- src/binomial-heap.c | 54 ++++++++++++++------------- src/binomial-heap.h | 2 +- src/bloom-filter.c | 4 +- src/hash-table.c | 54 +++++++++++++-------------- src/hash-table.h | 4 +- src/list.c | 34 ++++++++--------- src/list.h | 6 +-- src/set.c | 78 +++++++++++++++++++-------------------- src/set.h | 4 +- src/slist.c | 36 +++++++++--------- src/slist.h | 6 +-- src/trie.c | 2 +- src/trie.h | 2 +- test/test-arraylist.c | 14 +------ test/test-avl-tree.c | 16 ++++---- test/test-binomial-heap.c | 10 ++--- test/test-hash-table.c | 6 +-- test/test-list.c | 14 ++----- test/test-set.c | 14 +++---- test/test-trie.c | 8 ++-- 27 files changed, 227 insertions(+), 233 deletions(-) diff --git a/configure.ac b/configure.ac index 2ede18f..c7c8876 100644 --- a/configure.ac +++ b/configure.ac @@ -20,8 +20,9 @@ TEST_CFLAGS="" # Turn on all warnings for gcc. Turn off optimisation for the test build. if $is_gcc; then - CFLAGS="$CFLAGS -Wall" - TEST_CFLAGS="$TEST_CFLAGS -Wall -O0" + WARNINGS="-Wall -Wsign-compare -Wconversion" + CFLAGS="$CFLAGS $WARNINGS" + TEST_CFLAGS="$TEST_CFLAGS $WARNINGS -O0" fi # Support for coverage analysis via gcov: diff --git a/src/arraylist.c b/src/arraylist.c index 3616f57..4b3883c 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -31,7 +31,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* Automatically resizing array */ -ArrayList *arraylist_new(int length) +ArrayList *arraylist_new(unsigned int length) { ArrayList *new_arraylist; @@ -78,7 +78,7 @@ void arraylist_free(ArrayList *arraylist) static int arraylist_enlarge(ArrayList *arraylist) { ArrayListValue *data; - int newsize; + unsigned int newsize; /* Double the allocated size */ @@ -98,7 +98,8 @@ static int arraylist_enlarge(ArrayList *arraylist) } } -int arraylist_insert(ArrayList *arraylist, int index, ArrayListValue data) +int arraylist_insert(ArrayList *arraylist, unsigned int index, + ArrayListValue data) { /* Sanity check the index */ @@ -139,7 +140,8 @@ int arraylist_prepend(ArrayList *arraylist, ArrayListValue data) return arraylist_insert(arraylist, 0, data); } -void arraylist_remove_range(ArrayList *arraylist, int index, int length) +void arraylist_remove_range(ArrayList *arraylist, unsigned int index, + unsigned int length) { /* Check this is a valid range */ @@ -158,7 +160,7 @@ void arraylist_remove_range(ArrayList *arraylist, int index, int length) arraylist->length -= length; } -void arraylist_remove(ArrayList *arraylist, int index) +void arraylist_remove(ArrayList *arraylist, unsigned int index) { arraylist_remove_range(arraylist, index, 1); } @@ -167,11 +169,11 @@ int arraylist_index_of(ArrayList *arraylist, ArrayListEqualFunc callback, ArrayListValue data) { - int i; + unsigned int i; for (i=0; ilength; ++i) { if (callback(arraylist->data[i], data) != 0) - return i; + return (int) i; } return -1; @@ -184,14 +186,15 @@ void arraylist_clear(ArrayList *arraylist) arraylist->length = 0; } -static void arraylist_sort_internal(ArrayListValue *list_data, int list_length, +static void arraylist_sort_internal(ArrayListValue *list_data, + unsigned int list_length, ArrayListCompareFunc compare_func) { ArrayListValue pivot; ArrayListValue tmp; - int i; - int list1_length; - int list2_length; + unsigned int i; + unsigned int list1_length; + unsigned int list2_length; /* If less than two items, it is always sorted. */ diff --git a/src/arraylist.h b/src/arraylist.h index b0ce8a1..8c205b2 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -70,11 +70,11 @@ struct _ArrayList { /** Length of the array */ - int length; + unsigned int length; /** Private data and should not be accessed */ - int _alloced; + unsigned int _alloced; }; /** @@ -105,12 +105,14 @@ typedef int (*ArrayListCompareFunc)(ArrayListValue value1, * * @param length Hint to the initialise function as to the amount * of memory to allocate initially to the ArrayList. + * If a value of zero is given, a sensible default + * size is used. * @return A new arraylist, or NULL if it was not possible * to allocate the memory. * @see arraylist_free */ -ArrayList *arraylist_new(int length); +ArrayList *arraylist_new(unsigned int length); /** * Destroy an ArrayList and free back the memory it uses. @@ -151,7 +153,7 @@ int arraylist_prepend(ArrayList *arraylist, ArrayListValue data); * @param index The index of the entry to remove. */ -void arraylist_remove(ArrayList *arraylist, int index); +void arraylist_remove(ArrayList *arraylist, unsigned int index); /** * Remove a range of entries at the specified location in an ArrayList. @@ -161,7 +163,8 @@ void arraylist_remove(ArrayList *arraylist, int index); * @param length The length of the range to remove. */ -void arraylist_remove_range(ArrayList *arraylist, int index, int length); +void arraylist_remove_range(ArrayList *arraylist, unsigned int index, + unsigned int length); /** * Insert a value at the specified index in an ArrayList. @@ -176,7 +179,8 @@ void arraylist_remove_range(ArrayList *arraylist, int index, int length); * if it was impossible to allocate more memory). */ -int arraylist_insert(ArrayList *arraylist, int index, ArrayListValue data); +int arraylist_insert(ArrayList *arraylist, unsigned int index, + ArrayListValue data); /** * Find the index of a particular value in an ArrayList. @@ -189,8 +193,8 @@ int arraylist_insert(ArrayList *arraylist, int index, ArrayListValue data); * @return The index of the value if found, or -1 if not found. */ -int arraylist_index_of(ArrayList *arraylist, - ArrayListEqualFunc callback, +int arraylist_index_of(ArrayList *arraylist, + ArrayListEqualFunc callback, ArrayListValue data); /** diff --git a/src/avl-tree.c b/src/avl-tree.c index 4acf426..647bbc7 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -41,7 +41,7 @@ struct _AVLTreeNode { struct _AVLTree { AVLTreeNode *root_node; AVLTreeCompareFunc compare_func; - int num_nodes; + unsigned int num_nodes; }; AVLTree *avl_tree_new(AVLTreeCompareFunc compare_func) @@ -577,7 +577,7 @@ AVLTreeNode *avl_tree_node_parent(AVLTreeNode *node) return node->parent; } -int avl_tree_num_entries(AVLTree *tree) +unsigned int avl_tree_num_entries(AVLTree *tree) { return tree->num_nodes; } @@ -612,17 +612,17 @@ AVLTreeValue *avl_tree_to_array(AVLTree *tree) int index; /* Allocate the array */ - + array = malloc(sizeof(AVLTreeValue) * tree->num_nodes); if (array == NULL) { return NULL; } - + index = 0; /* Add all keys */ - + avl_tree_to_array_add_subtree(tree->root_node, array, &index); return array; diff --git a/src/avl-tree.h b/src/avl-tree.h index 45de3fe..0d4087c 100644 --- a/src/avl-tree.h +++ b/src/avl-tree.h @@ -276,7 +276,7 @@ AVLTreeValue *avl_tree_to_array(AVLTree *tree); * @return The number of key-value pairs stored in the tree. */ -int avl_tree_num_entries(AVLTree *tree); +unsigned int avl_tree_num_entries(AVLTree *tree); #ifdef __cplusplus } diff --git a/src/binary-heap.c b/src/binary-heap.c index 351480f..c071947 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -31,8 +31,8 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. struct _BinaryHeap { BinaryHeapType heap_type; BinaryHeapValue *values; - int num_values; - int alloced_size; + unsigned int num_values; + unsigned int alloced_size; BinaryHeapCompareFunc compare_func; }; @@ -82,24 +82,24 @@ void binary_heap_free(BinaryHeap *heap) int binary_heap_insert(BinaryHeap *heap, BinaryHeapValue value) { BinaryHeapValue *new_values; - int index; - int newsize; - int parent; + unsigned int index; + unsigned int new_size; + unsigned int parent; /* Possibly realloc the heap to a larger size */ if (heap->num_values >= heap->alloced_size) { /* Double the table size */ - - newsize = heap->alloced_size * 2; - new_values = realloc(heap->values, sizeof(BinaryHeapValue) * newsize); + + new_size = heap->alloced_size * 2; + new_values = realloc(heap->values, sizeof(BinaryHeapValue) * new_size); if (new_values == NULL) { return 0; } - - heap->alloced_size = newsize; + + heap->alloced_size = new_size; heap->values = new_values; } @@ -147,9 +147,9 @@ BinaryHeapValue binary_heap_pop(BinaryHeap *heap) { BinaryHeapValue result; BinaryHeapValue new_value; - int index; - int next_index; - int child1, child2; + unsigned int index; + unsigned int next_index; + unsigned int child1, child2; /* Empty heap? */ @@ -225,7 +225,7 @@ BinaryHeapValue binary_heap_pop(BinaryHeap *heap) return result; } -int binary_heap_num_entries(BinaryHeap *heap) +unsigned int binary_heap_num_entries(BinaryHeap *heap) { return heap->num_values; } diff --git a/src/binary-heap.h b/src/binary-heap.h index bd5ae63..7840ff1 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -141,7 +141,7 @@ BinaryHeapValue binary_heap_pop(BinaryHeap *heap); * @return The number of values in the heap. */ -int binary_heap_num_entries(BinaryHeap *heap); +unsigned int binary_heap_num_entries(BinaryHeap *heap); #ifdef __cplusplus } diff --git a/src/binomial-heap.c b/src/binomial-heap.c index bdf237e..32a1337 100644 --- a/src/binomial-heap.c +++ b/src/binomial-heap.c @@ -20,6 +20,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include "binomial-heap.h" @@ -43,9 +44,9 @@ struct _BinomialHeap { BinomialHeapType heap_type; BinomialHeapCompareFunc compare_func; - int num_values; + unsigned int num_values; BinomialTree **roots; - int roots_length; + unsigned int roots_length; }; static int binomial_heap_cmp(BinomialHeap *heap, @@ -86,7 +87,7 @@ static void binomial_tree_unref(BinomialTree *tree) for (i=0; iorder; ++i) { binomial_tree_unref(tree->subtrees[i]); } - + free(tree->subtrees); free(tree); } @@ -111,7 +112,7 @@ static BinomialTree *binomial_tree_merge(BinomialHeap *heap, tree1 = tree2; tree2 = tmp; } - + /* Allocate a new tree */ new_tree = malloc(sizeof(BinomialTree)); @@ -121,7 +122,7 @@ static BinomialTree *binomial_tree_merge(BinomialHeap *heap, } new_tree->refcount = 0; - new_tree->order = tree1->order + 1; + new_tree->order = (unsigned short) (tree1->order + 1); /* Take the smallest value of the two trees */ @@ -154,9 +155,10 @@ static BinomialTree *binomial_tree_merge(BinomialHeap *heap, * binomial_heap_merge. Go through the list of roots so far and remove * references that have been added. */ -static void binomial_heap_merge_undo(BinomialTree **new_roots, int count) +static void binomial_heap_merge_undo(BinomialTree **new_roots, + unsigned int count) { - int i; + unsigned int i; for (i=0; i<=count; ++i) { binomial_tree_unref(new_roots[i]); @@ -171,13 +173,13 @@ static void binomial_heap_merge_undo(BinomialTree **new_roots, int count) static int binomial_heap_merge(BinomialHeap *heap, BinomialHeap *other) { BinomialTree **new_roots; - int new_roots_length; + unsigned int new_roots_length; BinomialTree *vals[3]; int num_vals; BinomialTree *carry; BinomialTree *new_carry; - int i; - int max; + unsigned int max; + unsigned int i; /* Find the maximum length of the two heaps. Add one because * after merging we may have one more value to carry over. */ @@ -336,7 +338,7 @@ BinomialHeap *binomial_heap_new(BinomialHeapType heap_type, void binomial_heap_free(BinomialHeap *heap) { - int i; + unsigned int i; /* Unreference all trees in the heap. This should free * back all subtrees. */ @@ -402,35 +404,35 @@ BinomialHeapValue binomial_heap_pop(BinomialHeap *heap) BinomialTree *least_tree; BinomialHeap fake_heap; BinomialHeapValue result; - int least; - int i; + unsigned int i; + unsigned int least_index; if (heap->num_values == 0) { return BINOMIAL_HEAP_NULL; } - + /* Find the tree with the lowest root value */ - - least = -1; + + least_index = UINT_MAX; for (i=0; iroots_length; ++i) { if (heap->roots[i] == NULL) { continue; } - - if (least < 0 - || binomial_heap_cmp(heap, - heap->roots[i]->value, - heap->roots[least]->value) < 0) { - least = i; + + if (least_index == UINT_MAX + || binomial_heap_cmp(heap, + heap->roots[i]->value, + heap->roots[least_index]->value) < 0) { + least_index = i; } } /* Remove the least_tree from the heap. */ - least_tree = heap->roots[least]; - heap->roots[least] = NULL; + least_tree = heap->roots[least_index]; + heap->roots[least_index] = NULL; /* Construct a fake heap containing the data in the least tree */ @@ -460,7 +462,7 @@ BinomialHeapValue binomial_heap_pop(BinomialHeap *heap) /* Add the least tree back */ - heap->roots[least] = least_tree; + heap->roots[least_index] = least_tree; /* Pop failed */ @@ -468,7 +470,7 @@ BinomialHeapValue binomial_heap_pop(BinomialHeap *heap) } } -int binomial_heap_num_entries(BinomialHeap *heap) +unsigned int binomial_heap_num_entries(BinomialHeap *heap) { return heap->num_values; } diff --git a/src/binomial-heap.h b/src/binomial-heap.h index 5442bbe..5d3511b 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -141,7 +141,7 @@ BinomialHeapValue binomial_heap_pop(BinomialHeap *heap); * @return The number of values in the heap. */ -int binomial_heap_num_entries(BinomialHeap *heap); +unsigned int binomial_heap_num_entries(BinomialHeap *heap); #ifdef __cplusplus } diff --git a/src/bloom-filter.c b/src/bloom-filter.c index a4750b9..5b2ca7b 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -119,6 +119,7 @@ void bloom_filter_insert(BloomFilter *bloomfilter, BloomFilterValue value) unsigned long subhash; unsigned int index; unsigned int i; + unsigned char b; /* Generate hash of the value to insert */ @@ -141,7 +142,8 @@ void bloom_filter_insert(BloomFilter *bloomfilter, BloomFilterValue value) * index / 8 finds the byte index of the table, * index % 8 gives the bit index within that byte to set. */ - bloomfilter->table[index / 8] |= 1 << (index % 8); + b = (unsigned char) (1 << (index % 8)); + bloomfilter->table[index / 8] |= b; } } diff --git a/src/hash-table.c b/src/hash-table.c index cc0b8b7..dce89a2 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -39,13 +39,13 @@ struct _HashTableEntry { struct _HashTable { HashTableEntry **table; - int table_size; + unsigned int table_size; HashTableHashFunc hash_func; HashTableEqualFunc equal_func; HashTableKeyFreeFunc key_free_func; HashTableValueFreeFunc value_free_func; - int entries; - int prime_index; + unsigned int entries; + unsigned int prime_index; }; /* This is a set of good hash table prime numbers, from: @@ -60,7 +60,7 @@ static const unsigned int hash_table_primes[] = { 402653189, 805306457, 1610612741, }; -static const int hash_table_num_primes +static const unsigned int hash_table_num_primes = sizeof(hash_table_primes) / sizeof(int); /* Internal function used to allocate the table on hash table creation @@ -68,7 +68,7 @@ static const int hash_table_num_primes static int hash_table_allocate_table(HashTable *hash_table) { - int new_table_size; + unsigned int new_table_size; /* Determine the table size based on the current prime index. * An attempt is made here to ensure sensible behavior if the @@ -148,7 +148,7 @@ void hash_table_free(HashTable *hash_table) { HashTableEntry *rover; HashTableEntry *next; - int i; + unsigned int i; /* Free all entries in all chains */ @@ -182,12 +182,12 @@ void hash_table_register_free_functions(HashTable *hash_table, static int hash_table_enlarge(HashTable *hash_table) { HashTableEntry **old_table; - int old_table_size; - int old_prime_index; + unsigned int old_table_size; + unsigned int old_prime_index; HashTableEntry *rover; HashTableEntry *next; - int index; - int i; + unsigned int index; + unsigned int i; /* Store a copy of the old table */ @@ -244,7 +244,7 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue va { HashTableEntry *rover; HashTableEntry *newentry; - int index; + unsigned int index; /* If there are too many items in the table with respect to the table * size, the number of hash collisions increases and performance @@ -328,7 +328,7 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue va HashTableValue hash_table_lookup(HashTable *hash_table, HashTableKey key) { HashTableEntry *rover; - int index; + unsigned int index; /* Generate the hash of the key and hence the index into the table */ @@ -358,7 +358,7 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key) { HashTableEntry **rover; HashTableEntry *entry; - int index; + unsigned int index; int result; /* Generate the hash of the key and hence the index into the table */ @@ -406,25 +406,25 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key) return result; } -int hash_table_num_entries(HashTable *hash_table) +unsigned int hash_table_num_entries(HashTable *hash_table) { return hash_table->entries; } void hash_table_iterate(HashTable *hash_table, HashTableIterator *iterator) { - int chain; - + unsigned int chain; + iterator->hash_table = hash_table; /* Default value of next if no entries are found. */ - + iterator->next_entry = NULL; - + /* Find the first entry */ - + for (chain=0; chaintable_size; ++chain) { - + if (hash_table->table[chain] != NULL) { iterator->next_entry = hash_table->table[chain]; iterator->next_chain = chain; @@ -443,16 +443,16 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) HashTableEntry *current_entry; HashTable *hash_table; HashTableValue result; - int chain; + unsigned int chain; hash_table = iterator->hash_table; /* No more entries? */ - + if (iterator->next_entry == NULL) { return HASH_TABLE_NULL; } - + /* Result is immediately available */ current_entry = iterator->next_entry; @@ -461,19 +461,19 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) /* Find the next entry */ if (current_entry->next != NULL) { - + /* Next entry in current chain */ iterator->next_entry = current_entry->next; - + } else { - + /* None left in this chain, so advance to the next chain */ chain = iterator->next_chain + 1; /* Default value if no next chain found */ - + iterator->next_entry = NULL; while (chain < hash_table->table_size) { diff --git a/src/hash-table.h b/src/hash-table.h index e4f6e35..31ed21c 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -86,7 +86,7 @@ typedef void *HashTableValue; struct _HashTableIterator { HashTable *hash_table; HashTableEntry *next_entry; - int next_chain; + unsigned int next_chain; }; /** @@ -210,7 +210,7 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key); * @return The number of entries in the hash table. */ -int hash_table_num_entries(HashTable *hash_table); +unsigned int hash_table_num_entries(HashTable *hash_table); /** * Initialise a @ref HashTableIterator to iterate over a hash table. diff --git a/src/list.c b/src/list.c index 8fb4cd1..2d1f3be 100644 --- a/src/list.c +++ b/src/list.c @@ -137,10 +137,10 @@ ListEntry *list_next(ListEntry *listentry) return listentry->next; } -ListEntry *list_nth_entry(ListEntry *list, int n) +ListEntry *list_nth_entry(ListEntry *list, unsigned int n) { ListEntry *entry; - int i; + unsigned int i; /* Negative values are always out of range */ @@ -164,7 +164,7 @@ ListEntry *list_nth_entry(ListEntry *list, int n) return entry; } -ListValue list_nth_data(ListEntry *list, int n) +ListValue list_nth_data(ListEntry *list, unsigned int n) { ListEntry *entry; @@ -181,18 +181,18 @@ ListValue list_nth_data(ListEntry *list, int n) } } -int list_length(ListEntry *list) +unsigned int list_length(ListEntry *list) { ListEntry *entry; - int length; + unsigned int length; length = 0; entry = list; while (entry != NULL) { - + /* Count the number of entries */ - + ++length; entry = entry->next; @@ -204,30 +204,30 @@ int list_length(ListEntry *list) ListValue *list_to_array(ListEntry *list) { ListEntry *rover; - int listlen; ListValue *array; - int i; + unsigned int length; + unsigned int i; /* Allocate an array equal in size to the list length */ - - listlen = list_length(list); - array = malloc(sizeof(ListValue) * listlen); + length = list_length(list); + + array = malloc(sizeof(ListValue) * length); if (array == NULL) { return NULL; } - + /* Add all entries to the array */ - + rover = list; - - for (i=0; idata; - + /* Jump to the next list node */ rover = rover->next; diff --git a/src/list.h b/src/list.h index add3e78..cce8f87 100644 --- a/src/list.h +++ b/src/list.h @@ -184,7 +184,7 @@ ListValue list_data(ListEntry *listentry); * @return The entry at the specified index, or NULL if out of range. */ -ListEntry *list_nth_entry(ListEntry *list, int n); +ListEntry *list_nth_entry(ListEntry *list, unsigned int n); /** * Retrieve the value at a specified index in the list. @@ -195,7 +195,7 @@ ListEntry *list_nth_entry(ListEntry *list, int n); * unsuccessful. */ -ListValue list_nth_data(ListEntry *list, int n); +ListValue list_nth_data(ListEntry *list, unsigned int n); /** * Find the length of a list. @@ -204,7 +204,7 @@ ListValue list_nth_data(ListEntry *list, int n); * @return The number of entries in the list. */ -int list_length(ListEntry *list); +unsigned int list_length(ListEntry *list); /** * Create a C array containing the contents of a list. diff --git a/src/set.c b/src/set.c index fe7430d..3e97882 100644 --- a/src/set.c +++ b/src/set.c @@ -37,9 +37,9 @@ struct _SetEntry { struct _Set { SetEntry **table; - int entries; - int table_size; - int prime_index; + unsigned int entries; + unsigned int table_size; + unsigned int prime_index; SetHashFunc hash_func; SetEqualFunc equal_func; SetFreeFunc free_func; @@ -57,7 +57,7 @@ static const unsigned int set_primes[] = { 402653189, 805306457, 1610612741, }; -static const int set_num_primes = sizeof(set_primes) / sizeof(int); +static const unsigned int set_num_primes = sizeof(set_primes) / sizeof(int); static int set_allocate_table(Set *set) { @@ -125,10 +125,10 @@ void set_free(Set *set) { SetEntry *rover; SetEntry *next; - int i; - + unsigned int i; + /* Free all entries in all chains */ - + for (i=0; itable_size; ++i) { rover = set->table[i]; @@ -140,11 +140,11 @@ void set_free(Set *set) set_free_entry(set, rover); /* Advance to the next entry in the chain */ - + rover = next; } } - + /* Free the table */ free(set->table); @@ -164,13 +164,13 @@ static int set_enlarge(Set *set) SetEntry *rover; SetEntry *next; SetEntry **old_table; - int old_table_size; - int old_prime_index; - int index; - int i; + unsigned int old_table_size; + unsigned int old_prime_index; + unsigned int index; + unsigned int i; /* Store the old table */ - + old_table = set->table; old_table_size = set->table_size; old_prime_index = set->prime_index; @@ -227,13 +227,13 @@ int set_insert(Set *set, SetValue data) { SetEntry *newentry; SetEntry *rover; - int index; + unsigned int index; /* The hash table becomes less efficient as the number of entries * increases. Check if the percentage used becomes large. */ - + if ((set->entries * 3) / set->table_size > 0) { - + /* The table is more than 1/3 full and must be increased in size */ if (!set_enlarge(set)) { @@ -254,12 +254,12 @@ int set_insert(Set *set, SetValue data) while (rover != NULL) { if (set->equal_func(data, rover->data) != 0) { - + /* This data is already in the set */ return 0; } - + rover = rover->next; } @@ -293,7 +293,7 @@ int set_remove(Set *set, SetValue data) { SetEntry **rover; SetEntry *entry; - int index; + unsigned int index; /* Look up the data by its hash key */ @@ -305,7 +305,7 @@ int set_remove(Set *set, SetValue data) while (*rover != NULL) { if (set->equal_func(data, (*rover)->data) != 0) { - + /* Found the entry */ entry = *rover; @@ -338,7 +338,7 @@ int set_remove(Set *set, SetValue data) int set_query(Set *set, SetValue data) { SetEntry *rover; - int index; + unsigned int index; /* Look up the data by its hash key */ @@ -350,7 +350,7 @@ int set_query(Set *set, SetValue data) while (rover != NULL) { if (set->equal_func(data, rover->data) != 0) { - + /* Found the entry */ return 1; @@ -366,7 +366,7 @@ int set_query(Set *set, SetValue data) return 0; } -int set_num_entries(Set *set) +unsigned int set_num_entries(Set *set) { return set->entries; } @@ -375,21 +375,21 @@ SetValue *set_to_array(Set *set) { SetValue *array; int array_counter; - int i; + unsigned int i; SetEntry *rover; - + /* Create an array to hold the set entries */ - + array = malloc(sizeof(SetValue) * set->entries); if (array == NULL) { return NULL; } - + array_counter = 0; /* Iterate over all entries in all chains */ - + for (i=0; itable_size; ++i) { rover = set->table[i]; @@ -397,12 +397,12 @@ SetValue *set_to_array(Set *set) while (rover != NULL) { /* Add this value to the array */ - + array[array_counter] = rover->data; ++array_counter; /* Advance to the next entry */ - + rover = rover->next; } } @@ -513,13 +513,13 @@ Set *set_intersection(Set *set1, Set *set2) void set_iterate(Set *set, SetIterator *iter) { - int chain; - + unsigned int chain; + iter->set = set; iter->next_entry = NULL; /* Find the first entry */ - + for (chain = 0; chain < set->table_size; ++chain) { /* There is a value at the start of this chain */ @@ -529,7 +529,7 @@ void set_iterate(Set *set, SetIterator *iter) break; } } - + iter->next_chain = chain; } @@ -538,12 +538,12 @@ SetValue set_iter_next(SetIterator *iterator) Set *set; SetValue result; SetEntry *current_entry; - int chain; + unsigned int chain; set = iterator->set; /* No more entries? */ - + if (iterator->next_entry == NULL) { return SET_NULL; } @@ -562,7 +562,7 @@ SetValue set_iter_next(SetIterator *iterator) iterator->next_entry = current_entry->next; } else { - + /* Default value if no valid chain is found */ iterator->next_entry = NULL; @@ -576,7 +576,7 @@ SetValue set_iter_next(SetIterator *iterator) /* Is there a chain at this table entry? */ if (set->table[chain] != NULL) { - + /* Valid chain found! */ iterator->next_entry = set->table[chain]; diff --git a/src/set.h b/src/set.h index 5a90d7d..6ee010f 100644 --- a/src/set.h +++ b/src/set.h @@ -85,7 +85,7 @@ typedef void *SetValue; struct _SetIterator { Set *set; SetEntry *next_entry; - int next_chain; + unsigned int next_chain; }; /** @@ -188,7 +188,7 @@ int set_query(Set *set, SetValue data); * @return A count of the number of entries in the set. */ -int set_num_entries(Set *set); +unsigned int set_num_entries(Set *set); /** * Create an array containing all entries in a set. diff --git a/src/slist.c b/src/slist.c index f588ebc..e3110df 100644 --- a/src/slist.c +++ b/src/slist.c @@ -125,10 +125,10 @@ SListEntry *slist_next(SListEntry *listentry) return listentry->next; } -SListEntry *slist_nth_entry(SListEntry *list, int n) +SListEntry *slist_nth_entry(SListEntry *list, unsigned int n) { SListEntry *entry; - int i; + unsigned int i; /* Negative values are always out of range */ @@ -152,7 +152,7 @@ SListEntry *slist_nth_entry(SListEntry *list, int n) return entry; } -SListValue slist_nth_data(SListEntry *list, int n) +SListValue slist_nth_data(SListEntry *list, unsigned int n) { SListEntry *entry; @@ -169,18 +169,18 @@ SListValue slist_nth_data(SListEntry *list, int n) } } -int slist_length(SListEntry *list) +unsigned int slist_length(SListEntry *list) { SListEntry *entry; - int length; + unsigned int length; length = 0; entry = list; while (entry != NULL) { - + /* Count the number of entries */ - + ++length; entry = entry->next; @@ -192,30 +192,30 @@ int slist_length(SListEntry *list) SListValue *slist_to_array(SListEntry *list) { SListEntry *rover; - int listlen; SListValue *array; - int i; + unsigned int length; + unsigned int i; /* Allocate an array equal in size to the list length */ - - listlen = slist_length(list); - array = malloc(sizeof(SListValue) * listlen); + length = slist_length(list); + + array = malloc(sizeof(SListValue) * length); if (array == NULL) { return NULL; } - + /* Add all entries to the array */ - + rover = list; - - for (i=0; idata; - + /* Jump to the next list node */ rover = rover->next; @@ -233,7 +233,7 @@ int slist_remove_entry(SListEntry **list, SListEntry *entry) if (*list == NULL || entry == NULL) { return 0; } - + /* Action to take is different if the entry is the first in the list */ if (*list == entry) { diff --git a/src/slist.h b/src/slist.h index 4eb85e6..fef0e65 100644 --- a/src/slist.h +++ b/src/slist.h @@ -182,7 +182,7 @@ SListValue slist_data(SListEntry *listentry); * @return The entry at the specified index, or NULL if out of range. */ -SListEntry *slist_nth_entry(SListEntry *list, int n); +SListEntry *slist_nth_entry(SListEntry *list, unsigned int n); /** * Retrieve the value stored at a specified index in the list. @@ -193,7 +193,7 @@ SListEntry *slist_nth_entry(SListEntry *list, int n); * @ref SLIST_NULL if unsuccessful. */ -SListValue slist_nth_data(SListEntry *list, int n); +SListValue slist_nth_data(SListEntry *list, unsigned int n); /** * Find the length of a list. @@ -202,7 +202,7 @@ SListValue slist_nth_data(SListEntry *list, int n); * @return The number of entries in the list. */ -int slist_length(SListEntry *list); +unsigned int slist_length(SListEntry *list); /** * Create a C array containing the contents of a list. diff --git a/src/trie.c b/src/trie.c index a03324a..2aa2b65 100644 --- a/src/trie.c +++ b/src/trie.c @@ -569,7 +569,7 @@ TrieValue trie_lookup_binary(Trie *trie, unsigned char *key, int key_length) } } -int trie_num_entries(Trie *trie) +unsigned int trie_num_entries(Trie *trie) { /* To find the number of entries, simply look at the use count * of the root node. */ diff --git a/src/trie.h b/src/trie.h index d141336..22ebe97 100644 --- a/src/trie.h +++ b/src/trie.h @@ -171,7 +171,7 @@ int trie_remove_binary(Trie *trie, unsigned char *key, int key_length); * @return Count of the number of entries in the trie. */ -int trie_num_entries(Trie *trie); +unsigned int trie_num_entries(Trie *trie); #ifdef __cplusplus } diff --git a/test/test-arraylist.c b/test/test-arraylist.c index 0185ee4..84dba36 100644 --- a/test/test-arraylist.c +++ b/test/test-arraylist.c @@ -59,12 +59,6 @@ void test_arraylist_new_free(void) assert(arraylist != NULL); arraylist_free(arraylist); - /* Negative size also gives default */ - - arraylist = arraylist_new(-1); - assert(arraylist != NULL); - arraylist_free(arraylist); - /* Normal allocated */ arraylist = arraylist_new(10); @@ -203,7 +197,6 @@ void test_arraylist_insert(void) /* Check for out of range insert */ assert(arraylist->length == 16); - assert(arraylist_insert(arraylist, -1, &variable1) == 0); assert(arraylist_insert(arraylist, 17, &variable1) == 0); assert(arraylist->length == 16); @@ -282,9 +275,7 @@ void test_arraylist_remove_range(void) /* Try some invalid ones and check they don't do anything */ arraylist_remove_range(arraylist, 10, 10); - arraylist_remove_range(arraylist, -1, 10); arraylist_remove_range(arraylist, 0, 16); - arraylist_remove_range(arraylist, 0, -1); assert(arraylist->length == 13); @@ -313,7 +304,6 @@ void test_arraylist_remove(void) /* Try some invalid removes */ - arraylist_remove(arraylist, -1); arraylist_remove(arraylist, 15); assert(arraylist->length == 15); @@ -390,8 +380,8 @@ void test_arraylist_sort(void) ArrayList *arraylist; int entries[] = { 89, 4, 23, 42, 4, 16, 15, 4, 8, 99, 50, 30, 4 }; int sorted[] = { 4, 4, 4, 4, 8, 15, 16, 23, 30, 42, 50, 89, 99 }; - int num_entries = sizeof(entries) / sizeof(int); - int i; + unsigned int num_entries = sizeof(entries) / sizeof(int); + unsigned int i; arraylist = arraylist_new(10); diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index 9f5923a..04b573f 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -197,7 +197,7 @@ void test_avl_tree_insert_lookup(void) { AVLTree *tree; AVLTreeNode *node; - int i; + unsigned int i; int *value; /* Create a tree containing some values. Validate the @@ -206,7 +206,7 @@ void test_avl_tree_insert_lookup(void) tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i Date: Mon, 20 Jul 2009 00:16:18 +0000 Subject: [PATCH 121/250] Shut up remaining signed/unsigned warnings. --- src/list.c | 21 +++++++++++---------- src/list.h | 3 ++- src/slist.c | 19 ++++++++++--------- src/slist.h | 8 ++++---- test/alloc-testing.c | 6 +++--- test/test-slist.c | 14 ++++---------- 6 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/list.c b/src/list.c index 2d1f3be..fad369d 100644 --- a/src/list.c +++ b/src/list.c @@ -284,37 +284,38 @@ int list_remove_entry(ListEntry **list, ListEntry *entry) return 1; } -int list_remove_data(ListEntry **list, ListEqualFunc callback, ListValue data) +unsigned int list_remove_data(ListEntry **list, ListEqualFunc callback, + ListValue data) { - int entries_removed; + unsigned int entries_removed; ListEntry *rover; ListEntry *next; - + entries_removed = 0; /* Iterate over the entries in the list */ - + rover = *list; - + while (rover != NULL) { next = rover->next; if (callback(rover->data, data)) { - /* This data needs to be removed. Unlink this entry + /* This data needs to be removed. Unlink this entry * from the list. */ if (rover->prev == NULL) { - + /* This is the first entry in the list */ *list = rover->next; } else { - /* Point the previous entry at its new + /* Point the previous entry at its new * location */ - + rover->prev->next = rover->next; } @@ -328,7 +329,7 @@ int list_remove_data(ListEntry **list, ListEqualFunc callback, ListValue data) ++entries_removed; } - + /* Advance to the next list entry */ rover = next; diff --git a/src/list.h b/src/list.h index cce8f87..af16f58 100644 --- a/src/list.h +++ b/src/list.h @@ -239,7 +239,8 @@ int list_remove_entry(ListEntry **list, ListEntry *entry); * @return The number of entries removed from the list. */ -int list_remove_data(ListEntry **list, ListEqualFunc callback, ListValue data); +unsigned int list_remove_data(ListEntry **list, ListEqualFunc callback, + ListValue data); /** * Sort a list. diff --git a/src/slist.c b/src/slist.c index e3110df..5d61159 100644 --- a/src/slist.c +++ b/src/slist.c @@ -276,37 +276,38 @@ int slist_remove_entry(SListEntry **list, SListEntry *entry) return 1; } -int slist_remove_data(SListEntry **list, SListEqualFunc callback, SListValue data) +unsigned int slist_remove_data(SListEntry **list, SListEqualFunc callback, + SListValue data) { SListEntry **rover; SListEntry *next; - int entries_removed; + unsigned int entries_removed; entries_removed = 0; /* Iterate over the list. 'rover' points at the entrypoint into the - * current entry, ie. the list variable for the first entry in the + * current entry, ie. the list variable for the first entry in the * list, or the "next" field of the preceding entry. */ - + rover = list; while (*rover != NULL) { - + /* Should this entry be removed? */ - + if (callback((*rover)->data, data) != 0) { - + /* Data found, so remove this entry and free */ next = (*rover)->next; free(*rover); *rover = next; - + /* Count the number of entries removed */ ++entries_removed; } else { - + /* Advance to the next entry */ rover = &((*rover)->next); diff --git a/src/slist.h b/src/slist.h index fef0e65..f135949 100644 --- a/src/slist.h +++ b/src/slist.h @@ -231,15 +231,15 @@ int slist_remove_entry(SListEntry **list, SListEntry *entry); * Remove all occurrences of a particular value from a list. * * @param list Pointer to the list. - * @param callback Callback function to invoke to compare values in the + * @param callback Callback function to invoke to compare values in the * list with the value to remove. * @param data The value to remove from the list. * @return The number of entries removed from the list. */ -int slist_remove_data(SListEntry **list, - SListEqualFunc callback, - SListValue data); +unsigned int slist_remove_data(SListEntry **list, + SListEqualFunc callback, + SListValue data); /** * Sort a list. diff --git a/test/alloc-testing.c b/test/alloc-testing.c index f2a7e26..3c64b49 100644 --- a/test/alloc-testing.c +++ b/test/alloc-testing.c @@ -86,15 +86,15 @@ static void alloc_test_overwrite(void *ptr, size_t length, unsigned int pattern) { unsigned char *byte_ptr; unsigned int pattern_seq; - unsigned char pattern_byte; + unsigned char b; size_t i; byte_ptr = ptr; for (i=0; i> (8 * pattern_seq)) & 0xff; - byte_ptr[i] = pattern_byte; + b = (unsigned char) ((pattern >> (8 * pattern_seq)) & 0xff); + byte_ptr[i] = b; } } diff --git a/test/test-slist.c b/test/test-slist.c index adfe403..d1c1949 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -147,11 +147,6 @@ void test_slist_nth_entry(void) entry = slist_nth_entry(list, 3); assert(slist_data(entry) == &variable4); - /* Check negative values */ - - entry = slist_nth_entry(list, -1); - assert(entry == NULL); - /* Check out of range values */ entry = slist_nth_entry(list, 4); @@ -177,7 +172,6 @@ void test_slist_nth_data(void) /* Check out of range values */ - assert(slist_nth_data(list, -1) == NULL); assert(slist_nth_data(list, 4) == NULL); assert(slist_nth_data(list, 400) == NULL); @@ -247,10 +241,10 @@ void test_slist_remove_entry(void) void test_slist_remove_data(void) { int entries[] = { 89, 4, 23, 42, 4, 16, 15, 4, 8, 99, 50, 30, 4 }; - int num_entries = sizeof(entries) / sizeof(int); + unsigned int num_entries = sizeof(entries) / sizeof(int); int val; SListEntry *list; - int i; + unsigned int i; /* Generate a list containing all the entries in the array */ @@ -293,8 +287,8 @@ void test_slist_sort(void) SListEntry *list; int entries[] = { 89, 4, 23, 42, 4, 16, 15, 4, 8, 99, 50, 30, 4 }; int sorted[] = { 4, 4, 4, 4, 8, 15, 16, 23, 30, 42, 50, 89, 99 }; - int num_entries = sizeof(entries) / sizeof(int); - int i; + unsigned int num_entries = sizeof(entries) / sizeof(int); + unsigned int i; list = NULL; From 69b590e72df7f807b3b085b991814d1bd428a56b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 16 Aug 2009 18:28:49 +0000 Subject: [PATCH 122/250] Make hash functions return int rather than long. --- src/bloom-filter.c | 8 ++++---- src/bloom-filter.h | 2 +- src/hash-int.c | 4 ++-- src/hash-int.h | 2 +- src/hash-pointer.c | 6 ++++-- src/hash-pointer.h | 2 +- src/hash-string.c | 8 ++++---- src/hash-string.h | 4 ++-- src/hash-table.h | 2 +- src/set.h | 2 +- test/alloc-testing.c | 4 ++-- 11 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/bloom-filter.c b/src/bloom-filter.c index 5b2ca7b..334cc56 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -115,8 +115,8 @@ void bloom_filter_free(BloomFilter *bloomfilter) void bloom_filter_insert(BloomFilter *bloomfilter, BloomFilterValue value) { - unsigned long hash; - unsigned long subhash; + unsigned int hash; + unsigned int subhash; unsigned int index; unsigned int i; unsigned char b; @@ -149,8 +149,8 @@ void bloom_filter_insert(BloomFilter *bloomfilter, BloomFilterValue value) int bloom_filter_query(BloomFilter *bloomfilter, BloomFilterValue value) { - unsigned long hash; - unsigned long subhash; + unsigned int hash; + unsigned int subhash; unsigned int index; unsigned int i; unsigned char b; diff --git a/src/bloom-filter.h b/src/bloom-filter.h index ae20a3d..364d4f5 100644 --- a/src/bloom-filter.h +++ b/src/bloom-filter.h @@ -64,7 +64,7 @@ typedef void *BloomFilterValue; * @return The hash value. */ -typedef unsigned long (*BloomFilterHashFunc)(BloomFilterValue data); +typedef unsigned int (*BloomFilterHashFunc)(BloomFilterValue data); /** * Create a new bloom filter. diff --git a/src/hash-int.c b/src/hash-int.c index 1cfd660..70c0f04 100644 --- a/src/hash-int.c +++ b/src/hash-int.c @@ -22,12 +22,12 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* Hash function for a pointer to an integer */ -unsigned long int_hash(void *vlocation) +unsigned int int_hash(void *vlocation) { int *location; location = (int *) vlocation; - return (unsigned long) *location; + return (unsigned int) *location; } diff --git a/src/hash-int.h b/src/hash-int.h index 3babc81..bb6e43f 100644 --- a/src/hash-int.h +++ b/src/hash-int.h @@ -39,7 +39,7 @@ extern "C" { * @return A hash key for the value at the location. */ -unsigned long int_hash(void *location); +unsigned int int_hash(void *location); #ifdef __cplusplus } diff --git a/src/hash-pointer.c b/src/hash-pointer.c index 3585ccc..3943353 100644 --- a/src/hash-pointer.c +++ b/src/hash-pointer.c @@ -18,12 +18,14 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include "hash-pointer.h" /* Hash function for a generic pointer */ -unsigned long pointer_hash(void *location) +unsigned int pointer_hash(void *location) { - return (unsigned long) location; + return (unsigned int) (unsigned long) location; } diff --git a/src/hash-pointer.h b/src/hash-pointer.h index 82660b0..6cc1657 100644 --- a/src/hash-pointer.h +++ b/src/hash-pointer.h @@ -39,7 +39,7 @@ extern "C" { * @return A hash key for the pointer. */ -unsigned long pointer_hash(void *location); +unsigned int pointer_hash(void *location); #ifdef __cplusplus } diff --git a/src/hash-string.c b/src/hash-string.c index b524098..a9d17b5 100644 --- a/src/hash-string.c +++ b/src/hash-string.c @@ -24,11 +24,11 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* String hash function */ -unsigned long string_hash(void *string) +unsigned int string_hash(void *string) { /* This is the djb2 string hash function */ - unsigned long result = 5381; + unsigned int result = 5381; unsigned char *p; p = (unsigned char *) string; @@ -44,9 +44,9 @@ unsigned long string_hash(void *string) /* The same function, with a tolower on every character so that * case is ignored. This code is duplicated for performance. */ -unsigned long string_nocase_hash(void *string) +unsigned int string_nocase_hash(void *string) { - unsigned long result = 5381; + unsigned int result = 5381; unsigned char *p; p = (unsigned char *) string; diff --git a/src/hash-string.h b/src/hash-string.h index 12f3de1..d81087d 100644 --- a/src/hash-string.h +++ b/src/hash-string.h @@ -39,7 +39,7 @@ extern "C" { * @return A hash key for the string. */ -unsigned long string_hash(void *string); +unsigned int string_hash(void *string); /** * Generate a hash key from a string, ignoring the case of letters. @@ -48,7 +48,7 @@ unsigned long string_hash(void *string); * @return A hash key for the string. */ -unsigned long string_nocase_hash(void *string); +unsigned int string_nocase_hash(void *string); #ifdef __cplusplus } diff --git a/src/hash-table.h b/src/hash-table.h index 31ed21c..ba5717f 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -103,7 +103,7 @@ struct _HashTableIterator { * @return The hash value. */ -typedef unsigned long (*HashTableHashFunc)(HashTableKey value); +typedef unsigned int (*HashTableHashFunc)(HashTableKey value); /** * Function used to compare two keys for equality. diff --git a/src/set.h b/src/set.h index 6ee010f..ffd08f8 100644 --- a/src/set.h +++ b/src/set.h @@ -98,7 +98,7 @@ struct _SetIterator { * Hash function. Generates a hash key for values to be stored in a set. */ -typedef unsigned long (*SetHashFunc)(SetValue value); +typedef unsigned int (*SetHashFunc)(SetValue value); /** * Equality function. Compares two values to determine if they are diff --git a/test/alloc-testing.c b/test/alloc-testing.c index 3c64b49..87a01d4 100644 --- a/test/alloc-testing.c +++ b/test/alloc-testing.c @@ -85,14 +85,14 @@ static BlockHeader *alloc_test_get_header(void *ptr) static void alloc_test_overwrite(void *ptr, size_t length, unsigned int pattern) { unsigned char *byte_ptr; - unsigned int pattern_seq; + int pattern_seq; unsigned char b; size_t i; byte_ptr = ptr; for (i=0; i> (8 * pattern_seq)) & 0xff); byte_ptr[i] = b; } From 5815a56dc4ab60a4a5b55a796d1394c82712a4e6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 16 Aug 2009 18:32:01 +0000 Subject: [PATCH 123/250] Use addition rather than XOR (works as a better hash). --- src/hash-string.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hash-string.c b/src/hash-string.c index a9d17b5..5b9a5ce 100644 --- a/src/hash-string.c +++ b/src/hash-string.c @@ -34,14 +34,14 @@ unsigned int string_hash(void *string) p = (unsigned char *) string; while (*p != '\0') { - result = ((result << 5) ^ result ) ^ (*p); + result = ((result << 5) + result ) + *p; ++p; } return result; } -/* The same function, with a tolower on every character so that +/* The same function, with a tolower on every character so that * case is ignored. This code is duplicated for performance. */ unsigned int string_nocase_hash(void *string) @@ -52,10 +52,10 @@ unsigned int string_nocase_hash(void *string) p = (unsigned char *) string; while (*p != '\0') { - result = ((result << 5) ^ result ) ^ tolower(*p); + result = ((result << 5) + result ) + tolower(*p); ++p; } - + return result; } From 67ce51d8d82cc22e63258376498a90e3f3e5b3f5 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 16 Aug 2009 18:36:33 +0000 Subject: [PATCH 124/250] Fix warning. --- src/hash-string.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hash-string.c b/src/hash-string.c index 5b9a5ce..313efff 100644 --- a/src/hash-string.c +++ b/src/hash-string.c @@ -34,7 +34,7 @@ unsigned int string_hash(void *string) p = (unsigned char *) string; while (*p != '\0') { - result = ((result << 5) + result ) + *p; + result = (result << 5) + result + *p; ++p; } @@ -52,7 +52,7 @@ unsigned int string_nocase_hash(void *string) p = (unsigned char *) string; while (*p != '\0') { - result = ((result << 5) + result ) + tolower(*p); + result = (result << 5) + result + (unsigned int) tolower(*p); ++p; } From 64e363103bae51a5dea93d2f6eecbc94b0204a40 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 5 Feb 2011 19:12:35 +0000 Subject: [PATCH 125/250] Fix documentation comment (thanks Dave Kiddell). --- src/arraylist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arraylist.h b/src/arraylist.h index 8c205b2..4f8f915 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -80,7 +80,7 @@ struct _ArrayList { /** * Compare two values in an arraylist to determine if they are equal. * - * @return Non-zero if the values are not equal, zero if they are equal. + * @return Non-zero if the values are equal, zero if they are not equal. */ typedef int (*ArrayListEqualFunc)(ArrayListValue value1, ArrayListValue value2); From 6bd3e85061d7cc64d2bab5303bc44dda43abebce Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 25 Apr 2015 23:46:29 -0400 Subject: [PATCH 126/250] Update configure.ac to modern standards. This corrects a warning about the use of the AM_INIT_AUTOMAKE macro, documented here: https://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation --- configure.ac | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c7c8876..89cda17 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,9 @@ AC_INIT(C Algorithms, 1.2.0, fraggle@users.sourceforge.net, c-algorithms) AC_CONFIG_AUX_DIR(autotools) +AC_CONFIG_SRCDIR([src/arraylist.c]) +AC_CONFIG_MACRO_DIRS([m4]) -AM_INIT_AUTOMAKE($PACKAGE_TARNAME, $PACKAGE_VERSION, no-define) +AM_INIT_AUTOMAKE AC_PROG_CC AC_PROG_CXX From 71b31dbb0ddac77e72efd0324f6d54236727d290 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 25 Apr 2015 23:47:50 -0400 Subject: [PATCH 127/250] Use limits.h rather than values.h for UINT_MAX. ANSI C puts these constants in limits.h, not values.h. --- src/binomial-heap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/binomial-heap.c b/src/binomial-heap.c index 32a1337..ec96646 100644 --- a/src/binomial-heap.c +++ b/src/binomial-heap.c @@ -20,7 +20,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include +#include #include "binomial-heap.h" From d102a212206cd57bb37703e68df600aa410ce4f7 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 25 Apr 2015 23:50:31 -0400 Subject: [PATCH 128/250] Update email address. No longer using Sourceforge for the project, so giving a Sourceforge email address seems inappropriate. --- AUTHORS | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 1f671e2..9e6a3c2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1 @@ -Simon Howard +Simon Howard diff --git a/configure.ac b/configure.ac index 89cda17..efcc830 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(C Algorithms, 1.2.0, fraggle@users.sourceforge.net, c-algorithms) +AC_INIT(C Algorithms, 1.2.0, fraggle@removethisbit.gmail.com, c-algorithms) AC_CONFIG_AUX_DIR(autotools) AC_CONFIG_SRCDIR([src/arraylist.c]) AC_CONFIG_MACRO_DIRS([m4]) From d880c1b6feb7e45ef83a599295dab64b1d8a31f5 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 26 Apr 2015 00:03:21 -0400 Subject: [PATCH 129/250] Wipe out ChangeLog file. Just link to the GitHub commits page, as there's no sense in maintaining a text file with a separate copy of the change history. --- ChangeLog | 851 +---------------------------------------------- tools/svnhistory | 189 ----------- 2 files changed, 3 insertions(+), 1037 deletions(-) delete mode 100755 tools/svnhistory diff --git a/ChangeLog b/ChangeLog index 17e7001..c346264 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,849 +1,4 @@ -2008-09-14 02:43:19 fraggle - - Fix build of test-cpp.cpp to use the proper automake method. - -2008-09-14 02:24:28 fraggle - - Turn off optimisation for test build. - -2008-09-14 02:04:48 fraggle - - Use constants for the number of test values. - -2008-09-13 00:54:04 fraggle - - Expand binomial heap test case to include out of memory scenarios. - -2008-09-04 21:06:13 fraggle - - Reword some of the text about the license. - -2008-09-04 20:53:44 fraggle - - Use a non-recursive algorithm for trie_free. Add a test case for - this. - -2008-09-03 01:48:46 fraggle - - Add script for generating coverage reports from gcov files. - -2008-08-27 22:37:01 fraggle - - Smart indent all source. - -2008-08-27 22:25:09 fraggle - - Add test case for checking the library can be used from C++ programs. - -2008-08-27 21:29:09 fraggle - - Add missing C++ extern "C" declarations to headers. - -2008-08-26 14:41:39 fraggle - - Change allocation limit to limit a number of allocations, not a number - of bytes. - -2008-08-25 23:36:17 fraggle - - Improve coverage for set. - -2008-08-25 22:38:41 fraggle - - Rename test_ functions -> test_trie_. - -2008-08-25 22:36:00 fraggle - - Check return value for trie_insert. - -2008-08-25 22:29:58 fraggle - - Test out of memory scenario for trie, and fix rollback to work - properly. - -2008-08-25 22:28:20 fraggle - - Turn off optimisation for test library build. - -2008-06-23 01:45:28 fraggle - - Make avl_tree_node_parent_side function static, as it is internal. - -2008-06-21 21:24:28 fraggle - - Add out of memory checks for set, hash table. - -2008-06-21 20:05:45 fraggle - - Remove extra calls to find_subtree_height. - -2008-06-19 18:46:24 fraggle - - Add test cases for allocation testing framework. - -2008-06-18 01:36:26 fraggle - - Update Doxyfile to latest Doxygen. - -2008-06-17 22:11:48 fraggle - - Fix doxygen warnings. - -2008-06-17 22:10:58 fraggle - - Put coverage CFLAGS in COV_FLAGS rather than in main CFLAGS. - -2008-06-16 21:37:27 fraggle - - Update comments, add rebalance to root function. - -2008-06-16 20:44:55 fraggle - - Combine rotate_left and rotate_right functions into a single rotate - function. - -2008-06-16 20:24:09 fraggle - - Replace AVL tree node left/right child pointers with a two element - array. Restructure remove_node function to be more obviously correct. - -2008-06-16 20:20:52 fraggle - - Remove alloc testing linked list, as it is unused. - -2008-06-13 20:54:17 fraggle - - More bloom filter and linked list tests. - -2008-06-13 20:53:19 fraggle - - Allow allocations to reach the limit, but not exceed it. - -2008-06-13 20:13:12 fraggle - - Add more AVL tree tests. - -2008-06-13 19:53:23 fraggle - - Improve avl_tree_remove_node testing function. - -2008-06-13 19:49:53 fraggle - - Fix bugs in AVL tree. - -2008-06-13 19:39:49 fraggle - - Add copyright header to valgrind wrapper script. - -2008-06-13 18:59:14 fraggle - - Add missing test framework files. - -2008-06-13 17:47:20 fraggle - - Add check for failed malloc(). - -2008-06-13 01:00:21 fraggle - - Switch to ISC license, update copyright to 2005-2008. - -2008-06-12 20:58:31 fraggle - - Add assertations for [s]list_{prepend,append}, out of memory test - cases. - -2008-06-12 20:40:48 fraggle - - Add the ability to limit memory allocation for testing malloc() out of - memory conditions and a basic test framework for checking that memory - is correctly freed. Add malloc test cases for the queue, binary heap, - and arraylist. - -2008-06-11 23:42:59 fraggle - - Fix Doxygen errors. - -2008-06-11 23:34:05 fraggle - - Move alloc-testing.[ch] to test/ - -2008-06-11 23:18:35 fraggle - - Add initial test framework for testing memory allocation/free. - -2008-06-11 23:09:22 fraggle - - Prepend x to work with empty strings on old shell interpreters. - -2008-06-03 20:47:03 fraggle - - Add configure for compiling with profiling (gcov) and valgrind. - -2008-06-02 21:04:01 fraggle - - Fix memory leaks in unit tests. - -2008-06-02 20:45:14 fraggle - - Fix memory leak in hash table. - -2008-06-01 20:31:06 fraggle - - Update ChangeLog, bump to v1.1.0. - -2008-06-01 20:27:48 fraggle - - Fix smart-indent to expand tabs to the next tab point rather than - doing a simple replace. - -2008-06-01 20:27:02 fraggle - - Smart indent headers. - -2008-06-01 20:08:47 fraggle - - Documentation fixes: "data"->"value". - -2008-06-01 19:39:28 fraggle - - Fix documentation error. - -2008-06-01 19:36:05 fraggle - - Documentation fixes. - -2008-06-01 19:16:21 fraggle - - Initialise new trie nodes with TRIE_NULL. - -2008-06-01 19:15:49 fraggle - - Use 8 space tabs, replace cvshistory with svnhistory. - -2008-06-01 19:14:30 fraggle - - Remove coverage testing CFLAGS. - -2008-06-01 17:49:12 fraggle - - Add tests for some uncovered code. - -2008-06-01 16:41:54 fraggle - - Use string keys for test cases to ensure hash collisions occur and are - tested. - -2008-06-01 15:41:25 fraggle - - Indentation fixes. - -2008-05-30 21:26:07 fraggle - - Fix tabs/spaces. - -2008-05-30 21:23:33 fraggle - - Make list iterators cope with the current element being removed - independent of the iterator remove function. Add test cases for this. - -2008-05-30 01:51:18 fraggle - - Simplify linked list iterators and reduce iterator structure size. - -2008-04-16 21:41:46 fraggle - - Make the doubly-linked list type take a pointer to a structure to - initialise rather than allocating an iterator. - -2008-04-16 21:25:12 fraggle - - Make the singly-linked list type take a pointer to a structure to - initialise rather than allocating an iterator. - -2008-04-16 21:08:05 fraggle - - Make the set type take a pointer to a structure to initialise rather - than allocating an iterator. - -2008-04-16 20:57:09 fraggle - - Don't allocate hash table iterators; take a pointer to a structure to - initialise. - -2007-10-02 01:13:07 fraggle - - Return the value from the hash table iterator, not the key. - -2007-09-09 22:02:42 fraggle - - Add missing copyright notice. - -2007-06-10 04:22:20 fraggle - - Rename hashtable.[ch] -> hash-table.[ch] for consistency. Rename all - instances of hashtable to hash_table. - -2007-06-10 03:57:45 fraggle - - Test hash_table_register_free_functions. - -2007-06-10 03:56:57 fraggle - - Test set_register_free_function. - -2007-06-10 03:55:59 fraggle - - Test bloom_filter_free. - -2007-06-10 03:17:05 fraggle - - Rename avltree_* -> avl_tree_*, avltree.[ch] -> avl-tree.[ch] for - consistency with other files. - -2007-06-10 03:07:20 fraggle - - Set svn:ignore property on all directories. - -2006-11-22 00:41:28 fraggle - - Set reference count when allocating new trees. - -2006-11-22 00:31:34 fraggle - - Add new headers to libcalg.h. - -2006-11-22 00:15:27 fraggle - - Fix bug in set_to_array. - -2006-11-22 00:06:44 fraggle - - Separate out set value type to a separate type. - -2006-11-22 00:04:55 fraggle - - Abstract key/values into separate types, so that these can be changed - from "void *" if desired. - -2006-11-20 17:58:58 fraggle - - Test formatting cleanups. - -2006-11-20 17:55:53 fraggle - - Add binomial heap. - -2006-11-20 17:54:29 fraggle - - Fix bloom filter. - -2006-11-20 17:54:07 fraggle - - Add bloom filter test case. - -2006-11-15 23:35:18 fraggle - - Add bloom filter to front page in documentation. Fix documentation - warnings. - -2006-11-15 23:34:14 fraggle - - Rename bloom_filter_lookup to bloom_filter_query to be consistent with - the set data structure. - -2006-11-15 19:56:21 fraggle - - Add bloom filter union/intersection functions. - -2006-11-15 19:43:25 fraggle - - Add bloom filter read/load functions. - -2006-11-15 19:32:53 fraggle - - Make salts unsigned. - -2006-11-15 19:32:01 fraggle - - Add bloom filter. - -2006-10-30 20:15:18 fraggle - - Fix indentation. - -2006-10-30 20:13:10 fraggle - - Improved trie test cases. - -2006-10-30 20:12:29 fraggle - - Indentation fixes. - -2006-10-30 20:11:34 fraggle - - Trie fixes: recover properly from failed mallocs. Fix insert that - replaces an existing value. - -2006-10-30 20:09:29 fraggle - - Fix allocation size on reallocs. - -2006-10-28 13:21:26 fraggle - - Fix up indentation. - -2006-10-28 13:18:05 fraggle - - Reword comments. - -2006-10-28 13:17:45 fraggle - - Improve list iterate test case. - -2006-10-28 13:10:43 fraggle - - Convert slist_foreach to iterators. - -2006-10-27 20:57:06 fraggle - - Smart indent all source code. - -2006-10-27 20:50:36 fraggle - - Check the return value from malloc() and return error conditions if it - fails. - -2006-10-27 19:34:18 fraggle - - Replace list_foreach with iterator objects. - -2006-10-27 18:23:14 fraggle - - Improve the set_remove test function. - -2006-10-27 18:16:26 fraggle - - Fix lockup when removing entries from sets. - -2006-10-26 19:39:38 fraggle - - Use "good hash table primes" from - http://planetmath.org/encyclopedia/GoodHashTablePrimes.html - -2006-10-22 02:49:08 fraggle - - Add test suite for binary heap. - -2006-10-22 02:45:15 fraggle - - Fix errors: (i - 1) / 2 to get parent index, do not use child 2 when - it does not exist. - -2006-10-22 01:04:59 fraggle - - Add binary_heap_free. - -2006-10-21 23:27:40 fraggle - - Use calloc/malloc more appropriately (don't clear memory - unnecessarily), don't use memset where it isn't needed. - -2006-10-21 00:34:08 fraggle - - Add a binary heap implementation. - -2006-06-19 18:50:38 fraggle - - Remove the double-pointer usage (breaks remove while iterating). - -2006-06-19 18:32:33 fraggle - - Add test cases for set iterator functions. - -2006-06-19 18:22:21 fraggle - - Convert spaces to tabs. - -2006-06-19 18:18:14 fraggle - - Rename functions with _iterator_ to _iter_ for shorter names. - -2006-06-19 18:11:03 fraggle - - Convert hash table structure to use iterator objects instead of - foreach with callback functions. - -2006-06-17 20:23:11 fraggle - - Change set iteration to use iterator objects rather than foreach with - callback functions. - -2006-01-30 18:52:43 fraggle - - v1.0.0 - -2005-12-23 23:19:02 fraggle - - Make compare/hash functions take void pointers, removing the need to - cast the functions to the appropriate type when used. - -2005-12-23 22:39:39 fraggle - - Fix bug in list iterator, add test cases for iterator - -2005-12-23 19:08:17 fraggle - - Do not include complete path in Doxygen documentation - -2005-12-23 19:07:57 fraggle - - Add AVL tree to main documentation list; split data structures into - categories - -2005-12-23 18:57:38 fraggle - - List to array conversion functions - -2005-12-23 18:44:15 fraggle - - to_array conversion function. - -2005-12-23 18:25:36 fraggle - - Turn on warnings; remove unneeded variables. Add more test cases. - -2005-12-23 18:24:43 fraggle - - avltree_remove, avltree_free functions. - -2005-12-23 16:07:38 fraggle - - AVL tree: Remove debugging functions, fix bug with parent references - not updated on rotate. Add "remove" function and test cases. - -2005-12-23 02:11:27 fraggle - - More AVL tree documentation. - -2005-12-23 01:51:34 fraggle - - Update NEWS, ChangeLog - -2005-12-23 01:49:54 fraggle - - CVS history script - -2005-12-21 21:39:17 fraggle - - Add missing function declarations and some documentation. - -2005-12-20 23:21:36 fraggle - - Style cleanups: always use {} blocks for if statements. - -2005-12-20 23:20:23 fraggle - - Main header - -2005-12-17 13:45:52 fraggle - - Add trie - -2005-12-13 22:02:22 fraggle - - Smart indent all source code - -2005-12-13 21:54:51 fraggle - - Maintenance scripts - -2005-12-13 20:16:30 fraggle - - hash_table_foreach_remove function - -2005-12-13 19:57:56 fraggle - - Use unsigned int for prime arrays - -2005-12-13 19:54:03 fraggle - - Hash table iterator function; add missing num_entries function to - header. - -2005-12-13 19:29:57 fraggle - - Install header files, pkgconfig .pc file - -2005-12-13 19:28:19 fraggle - - Sort function - -2005-12-13 19:27:15 fraggle - - SLIST -> LIST (prevent conflict with the real slist.h) - -2005-12-11 01:58:51 fraggle - - Act as a mapping. Add a lookup function and accessor functions for - the nodes. - -2005-12-10 23:44:26 fraggle - - Set to array convertor function - -2005-12-10 23:17:40 fraggle - - Trie documentation - -2005-12-10 22:43:02 fraggle - - Trie testcase - -2005-12-10 22:42:18 fraggle - - Add remove, free functions, entries count - -2005-12-10 21:47:39 fraggle - - terminology: "duplicate" -> "copy" - -2005-12-01 17:47:42 fraggle - - Fix error in documentation - -2005-12-01 17:46:25 fraggle - - Move Doxyfile to the doc/ directory, only generate HTML documentation. - Include docs in dist. - -2005-11-30 00:58:02 fraggle - - First implementation of a trie - -2005-11-29 23:30:51 fraggle - - Algorithms -> data structures - -2005-11-29 23:25:59 fraggle - - When overwriting an existing value in a hashtable, use the new key and - not the old one. - -2005-11-29 23:24:01 fraggle - - Return results for set_remove and set_insert. Add free function - registration to free values. - -2005-11-29 23:03:07 fraggle - - Test cases for hash functions - -2005-11-29 22:49:17 fraggle - - Add test cases for case insensitive string compare functions - -2005-11-29 22:47:07 fraggle - - Fix case insensitive string compare - -2005-11-29 00:00:12 fraggle - - Key/value free functions - -2005-11-28 18:25:45 fraggle - - Case insensitive string hash and comparison functions - -2005-11-28 18:23:43 fraggle - - Duplicator functions for union and intersection calls to copy values. - -2005-11-28 18:20:59 fraggle - - Hashtable -> HashTable, hashtable_ -> hash_table_ - consistent naming - scheme and consistent with glib - -2005-11-26 23:27:57 fraggle - - First implementation of an AVL Tree - -2005-11-26 20:13:18 fraggle - - Exit with an error code of 0 if completed successfully - -2005-11-26 19:04:40 fraggle - - Set unit tests - -2005-11-26 19:03:18 fraggle - - Add union and intersection functions, fix bug in set_query - -2005-11-26 18:20:16 fraggle - - Rename set functions to be consistent with hashtable function names - -2005-11-26 18:11:26 fraggle - - Hash table test suite - -2005-11-26 18:11:01 fraggle - - Keep track of the number of entries in a hash table correctly. Add - num_entries function to retrieve the number of entries. - -2005-11-26 17:46:54 fraggle - - Test cases for the compare functions - -2005-11-26 16:59:07 fraggle - - Include the doc directory in distributions - -2005-11-26 16:13:08 fraggle - - Improve documentation, add an introduction page - -2005-11-26 15:21:53 fraggle - - Always show all warnings - -2005-11-26 15:21:40 fraggle - - Generate a configuration file so that the compiler command line is not - so cluttered. - -2005-11-26 15:18:40 fraggle - - Include the autotools directory in distribution - -2005-11-26 15:14:53 fraggle - - Use comparison functions from the library instead of duplicating - declarations - -2005-11-26 15:12:32 fraggle - - Add build system - -2005-11-26 15:11:30 fraggle - - AUTHORS file - -2005-11-26 14:42:55 fraggle - - Include manpage links for function names - -2005-11-26 14:38:07 fraggle - - Documentation improvements - -2005-11-26 14:27:30 fraggle - - Use prime numbered table sizes - -2005-11-26 13:34:42 fraggle - - Restructure directories - -2005-11-21 16:09:37 fraggle - - Implementation of a set - -2005-11-21 16:09:16 fraggle - - Function to retrieve a count of the number of entries - -2005-11-20 12:11:59 fraggle - - A set of values - -2005-11-20 02:47:04 fraggle - - Wording fix - -2005-11-20 02:43:46 fraggle - - Generate brief descriptions automatically - -2005-11-20 02:43:33 fraggle - - Documentation wording fixes - -2005-11-20 02:40:07 fraggle - - Do not display directories. Remove my local build dirs from the file - and use relative paths. - -2005-11-20 02:27:22 fraggle - - Documentation improvements; generate documentation through Doxygen - -2005-11-20 01:21:34 fraggle - - Hash table implementation - -2005-11-19 19:29:00 fraggle - - rm -f - -2005-11-19 19:28:24 fraggle - - Shut up compiler warnings - -2005-11-19 19:25:01 fraggle - - Turn on warnings on all makefiles - -2005-11-19 19:24:10 fraggle - - Use callback to determine data to remove with slist_remove_data - -2005-11-19 19:14:32 fraggle - - Split hash functions into a separate hash-functions directory - -2005-11-19 19:07:52 fraggle - - Doubly-linked list implementation - -2005-11-19 13:21:42 fraggle - - Add README - -2005-11-19 13:18:34 fraggle - - Add new test functions - -2005-11-19 13:18:23 fraggle - - Use callback functions when searching - -2005-11-19 13:10:54 fraggle - - Add a search function - -2005-11-19 12:47:34 fraggle - - Queue test cases - -2005-11-19 12:36:25 fraggle - - queue_empty -> queue_is_empty - -2005-11-19 12:28:35 fraggle - - Rename files, add headers and documentation - -2005-11-18 16:41:20 fraggle - - Update license to match source files - -2005-11-18 16:40:27 fraggle - - Compare functions for different types - -2005-11-18 16:37:23 fraggle - - Initial revision +The c-algorithms source code is maintained in Git. For a complete history +see the page on Github: + https://github.com/fragglet/c-algorithms/commits/master diff --git a/tools/svnhistory b/tools/svnhistory deleted file mode 100755 index cd41b0e..0000000 --- a/tools/svnhistory +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env ruby -# -# Copyright(C) Simon Howard -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. -# - -class Change - attr_accessor :author, :time, :description - - def initialize - @description = "" - end - - # Combine multiple lines of text into long run-on lines. Empty - # lines of text denote paragraphs. Lines beginning with '*' - # are also recognised as bullet point lists. - - def combine_lines(input) - result = "" - - input.each_line do |s| - s = s.chomp - - if result.length > 0 && result[-1, 1] != "\n" - - # Don't do any of this if we just started a new line - - if s =~ /^\s*$/ - # empty line; make this break a paragraph. - result += "\n\n" - elsif s =~ /^\s*\*/ - # bullet point - result += "\n" - else - result += " " - end - end - - result += s - end - - result - end - - # Reformat the description and break into lines - - def break_lines(input) - result = "" - - input.each_line do |s| - - if s =~ /^\s*$/ - # empty line - result += "\n" - else - - # Amount to indent each line by so that they align - # with the initial bullet point (if this line is a - # bullet point) - - indent_length = if s =~ /^(\s*\*\s*)/ - $1.length - else - 0 - end - - # Split this line into words, then add them to nextline - # one at a time until it reaches a 70 character limit. - - nextline = s[0, indent_length] - s = s[indent_length, s.length] - - words = s.split(/\s+/) - - words.each do |word| - - # If the next word will run over the limit, break - # onto a new line. - - if nextline.length > indent_length \ - && nextline.length + word.length + 1 > 70 - - result += nextline + "\n" - nextline = " " * indent_length - end - - # Space to separate from the previous word, but only - # if this is not the start of a line - - if nextline.length > indent_length - if nextline[-1, 1] == "." - - # Two spaces after a period - - nextline += " " - end - nextline += " " - end - - nextline += word - end - - # Print the last "unfinished" line - - if nextline.length > indent_length - result += nextline + "\n" - end - end - end - - result - end - - def remove_trailing_newlines(s) - while s[-2, 2] == "\n\n" - s = s.chop - end - - s - end - - def print_change - puts "#{@time} #{@author}" - puts "\t" - - munged = combine_lines(@description) - munged = break_lines(munged) - munged = remove_trailing_newlines(munged) - munged.each_line do |s| - puts "\t" + s - end - - puts - end -end - -changes = [] - -IO.popen("svn log .") do |io| - - current_change = nil - - io.each_line do |s| - - s = s.chomp - - if s =~ /^-+$/ - # start of a new change - - if current_change != nil - changes.push(current_change) - end - current_change = Change.new - elsif current_change.author == nil - # first line of new change - - fields = s.split(/ \| /) - current_change.author = fields[1] - - # time - timebits = fields[2].split(/\s+/) - current_change.time = timebits[0] + " " + timebits[1] - else - current_change.description += s + "\n" - end - end -end - -changes.each do |change| - change.print_change -end - From d6bc967330a3fe3f8ad55079b176aa1e1acc92d4 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 26 Apr 2015 00:04:32 -0400 Subject: [PATCH 130/250] Fix compiler warnings. --- src/arraylist.c | 4 ++-- src/list.c | 6 ------ src/rb-tree.c | 1 + src/slist.c | 6 ------ test/test-avl-tree.c | 2 -- test/test-rb-tree.c | 2 -- 6 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/arraylist.c b/src/arraylist.c index 4b3883c..78a6ae1 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -103,7 +103,7 @@ int arraylist_insert(ArrayList *arraylist, unsigned int index, { /* Sanity check the index */ - if (index < 0 || index > arraylist->length) { + if (index > arraylist->length) { return 0; } @@ -145,7 +145,7 @@ void arraylist_remove_range(ArrayList *arraylist, unsigned int index, { /* Check this is a valid range */ - if (index < 0 || length < 0 || index + length > arraylist->length) { + if (index > arraylist->length || index + length > arraylist->length) { return; } diff --git a/src/list.c b/src/list.c index fad369d..04d9dee 100644 --- a/src/list.c +++ b/src/list.c @@ -142,12 +142,6 @@ ListEntry *list_nth_entry(ListEntry *list, unsigned int n) ListEntry *entry; unsigned int i; - /* Negative values are always out of range */ - - if (n < 0) { - return NULL; - } - /* Iterate through n list entries to reach the desired entry. * Make sure we do not reach the end of the list. */ diff --git a/src/rb-tree.c b/src/rb-tree.c index fe788c0..ab82128 100644 --- a/src/rb-tree.c +++ b/src/rb-tree.c @@ -497,6 +497,7 @@ RBTreeNode *rb_tree_node_parent(RBTreeNode *node) RBTreeValue *rb_tree_to_array(RBTree *tree) { /* TODO */ + return NULL; } int rb_tree_num_entries(RBTree *tree) diff --git a/src/slist.c b/src/slist.c index 5d61159..7fdac2d 100644 --- a/src/slist.c +++ b/src/slist.c @@ -130,12 +130,6 @@ SListEntry *slist_nth_entry(SListEntry *list, unsigned int n) SListEntry *entry; unsigned int i; - /* Negative values are always out of range */ - - if (n < 0) { - return NULL; - } - /* Iterate through n list entries to reach the desired entry. * Make sure we do not reach the end of the list. */ diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index 04b573f..e00a453 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -269,10 +269,8 @@ void test_avl_tree_child(void) /* Check invalid values */ - assert(avl_tree_node_child(root, -1) == NULL); assert(avl_tree_node_child(root, 10000) == NULL); assert(avl_tree_node_child(root, 2) == NULL); - assert(avl_tree_node_child(root, -100000) == NULL); avl_tree_free(tree); } diff --git a/test/test-rb-tree.c b/test/test-rb-tree.c index f56ff14..3a7e67c 100644 --- a/test/test-rb-tree.c +++ b/test/test-rb-tree.c @@ -200,10 +200,8 @@ void test_rb_tree_child(void) /* Check invalid values */ - assert(rb_tree_node_child(root, -1) == NULL); assert(rb_tree_node_child(root, 10000) == NULL); assert(rb_tree_node_child(root, 2) == NULL); - assert(rb_tree_node_child(root, -100000) == NULL); rb_tree_free(tree); } From 09c5c98b7cfdbff5baa35db31bb236e94ee400a6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 26 Apr 2015 00:10:47 -0400 Subject: [PATCH 131/250] Remove trailing whitespace from files. --- NEWS | 4 +- doc/Doxyfile | 1120 ++++++++++++++++----------------- doc/intro.h | 42 +- src/arraylist.c | 52 +- src/arraylist.h | 54 +- src/avl-tree.c | 70 +-- src/avl-tree.h | 56 +- src/binary-heap.c | 48 +- src/binary-heap.h | 40 +- src/binomial-heap.c | 60 +- src/binomial-heap.h | 40 +- src/bloom-filter.c | 42 +- src/bloom-filter.h | 72 +-- src/compare-int.c | 26 +- src/compare-int.h | 32 +- src/compare-pointer.c | 26 +- src/compare-pointer.h | 26 +- src/compare-string.c | 28 +- src/compare-string.h | 30 +- src/hash-int.c | 26 +- src/hash-int.h | 30 +- src/hash-pointer.c | 26 +- src/hash-pointer.h | 28 +- src/hash-string.c | 26 +- src/hash-string.h | 28 +- src/hash-table.c | 80 +-- src/hash-table.h | 72 +-- src/libcalg.h | 26 +- src/list.c | 60 +- src/list.h | 68 +- src/queue.c | 46 +- src/queue.h | 36 +- src/rb-tree.h | 58 +- src/set.c | 64 +- src/set.h | 50 +- src/slist.c | 54 +- src/slist.h | 72 +-- src/trie.c | 62 +- src/trie.h | 44 +- test/alloc-testing.c | 36 +- test/alloc-testing.h | 46 +- test/framework.c | 26 +- test/framework.h | 26 +- test/test-alloc-testing.c | 26 +- test/test-arraylist.c | 32 +- test/test-avl-tree.c | 46 +- test/test-binary-heap.c | 26 +- test/test-binomial-heap.c | 30 +- test/test-bloom-filter.c | 30 +- test/test-compare-functions.c | 34 +- test/test-hash-functions.c | 30 +- test/test-hash-table.c | 46 +- test/test-list.c | 40 +- test/test-queue.c | 36 +- test/test-rb-tree.c | 42 +- test/test-set.c | 58 +- test/test-slist.c | 42 +- test/test-trie.c | 40 +- 58 files changed, 1758 insertions(+), 1758 deletions(-) diff --git a/NEWS b/NEWS index 56f8c38..a825d57 100644 --- a/NEWS +++ b/NEWS @@ -5,12 +5,12 @@ v1.2.0 (14th September 2008) * Support for compiling with gcc coverage options and running tests in valgrind. * All headers now have extern "C" definitions for use in C++ programs. - * Trie free function uses a non-recursive algorithm to avoid the + * Trie free function uses a non-recursive algorithm to avoid the possibility of stack overflow. Test suite: * Framework added for testing memory allocation/free. - * Tests have been fixed to properly free any memory allocated during + * Tests have been fixed to properly free any memory allocated during execution of the test. * Tests have been expanded to increase the code coverage. * A test case has been added for testing use of the program in C++ diff --git a/doc/Doxyfile b/doc/Doxyfile index 26b6b85..69d2d71 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -14,76 +14,76 @@ # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "C Algorithms" -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = . -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, # and Ukrainian. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ @@ -98,137 +98,137 @@ ABBREVIATE_BRIEF = "The $name class" \ an \ the -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = src/ -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO -# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member +# If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO @@ -238,33 +238,33 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO @@ -273,357 +273,357 @@ TYPEDEF_HIDES_STRUCT = NO # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file +# If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the +# Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES -# The ENABLED_SECTIONS tag can be used to enable conditional +# The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. -ENABLED_SECTIONS = +ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated +# The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = intro.h \ ../src -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.h -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = +EXCLUDE = -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see # the \image command). -IMAGE_PATH = +IMAGE_PATH = -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. -INPUT_FILTER = +INPUT_FILTER = -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. -FILTER_PATTERNS = +FILTER_PATTERNS = -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO @@ -632,32 +632,32 @@ FILTER_SOURCE_FILES = NO # configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO -# Setting the INLINE_SOURCES tag to YES will include the body +# Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO @@ -669,16 +669,16 @@ REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO @@ -687,166 +687,166 @@ VERBATIM_HEADERS = NO # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a # standard header. -HTML_HEADER = +HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a # standard footer. -HTML_FOOTER = +HTML_FOOTER = -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! -HTML_STYLESHEET = +HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. GENERATE_DOCSET = NO -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be # written to the html output directory. -CHM_FILE = +CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. -HHC_LOCATION = +HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members +# The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO -# This tag can be used to set the number of enum values (range [1..20]) +# This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 @@ -855,74 +855,74 @@ TREEVIEW_WIDTH = 250 # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. -EXTRA_PACKAGES = +EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! -LATEX_HEADER = +LATEX_HEADER = -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO @@ -931,68 +931,68 @@ LATEX_HIDE_INDICES = NO # configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = -# Set optional variables used in the generation of an rtf document. +# Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man -# The MAN_EXTENSION tag determines the extension that is added to +# The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = YES @@ -1001,33 +1001,33 @@ MAN_LINKS = YES # configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_SCHEMA = +XML_SCHEMA = -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_DTD = +XML_DTD = -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES @@ -1036,10 +1036,10 @@ XML_PROGRAMLISTING = YES # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO @@ -1048,320 +1048,320 @@ GENERATE_AUTOGEN_DEF = NO # configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- -# Configuration options related to the preprocessor +# Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by # the preprocessor. -INCLUDE_PATH = +INCLUDE_PATH = -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen +# If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = -# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. -GENERATE_TAGFILE = +GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES -# The PERL_PATH should be the absolute path and name of the perl script +# The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = NO -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. -MSCGEN_PATH = +MSCGEN_PATH = -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO -# If set to YES, the inheritance and collaboration graphs will show the +# If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png -# The tag DOT_PATH can be used to specify the path where the dot tool can be +# The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. -DOT_PATH = +DOT_PATH = -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the # \dotfile command). -DOTFILE_DIRS = +DOTFILE_DIRS = -# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 1000 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is enabled by default, which results in a transparent -# background. Warning: Depending on the platform used, enabling this option -# may lead to badly anti-aliased labels on the edges of a graph (i.e. they +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is enabled by default, which results in a transparent +# background. Warning: Depending on the platform used, enabling this option +# may lead to badly anti-aliased labels on the edges of a graph (i.e. they # become hard to read). DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- -# Configuration::additions related to the search engine +# Configuration::additions related to the search engine #--------------------------------------------------------------------------- -# The SEARCHENGINE tag specifies whether or not a search engine should be +# The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO diff --git a/doc/intro.h b/doc/intro.h index f0af1aa..172b180 100644 --- a/doc/intro.h +++ b/doc/intro.h @@ -2,23 +2,23 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* This file is a dummy header which is used to generate the +/* This file is a dummy header which is used to generate the * introduction in Doxygen. */ /** @@ -28,11 +28,11 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * The C programming language includes a very limited standard library in * comparison to other modern programming languages. This is a collection - * of common Computer Science data structures and algorithms which may be + * of common Computer Science data structures and algorithms which may be * used in C projects. - * + * * The code is licensed under the ISC license (a simplified version - * of the BSD license that is functionally identical). + * of the BSD license that is functionally identical). * As such, it may be reused in any project, whether Proprietary or * Open Source. * @@ -52,22 +52,22 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @subsection Mappings * - * @li @link hash-table.h Hash table @endlink: Collection of values which + * @li @link hash-table.h Hash table @endlink: Collection of values which * can be addressed using a key. * @li @link trie.h Trie @endlink: Fast mapping using strings as keys. * * @subsection Binary_search_trees Binary search trees * - * @li @link avl-tree.h AVL tree @endlink: Balanced binary search tree + * @li @link avl-tree.h AVL tree @endlink: Balanced binary search tree * with O(log n) worst case performance. * * @section Utility_functions Utility functions * - * All of the above data structures operate on void pointers. It is + * All of the above data structures operate on void pointers. It is * sometimes necessary to compare values (when sorting a list, for - * example) or generate a hash key (in a hash table or set). This + * example) or generate a hash key (in a hash table or set). This * is done by providing a pointer to a function which provides - * this functionality. The following functions provide this + * this functionality. The following functions provide this * functionality for some common data types. * * @li Integer @link compare-int.h comparison @endlink and diff --git a/src/arraylist.c b/src/arraylist.c index 78a6ae1..0cb7f17 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -36,12 +36,12 @@ ArrayList *arraylist_new(unsigned int length) ArrayList *new_arraylist; /* If the length is not specified, use a sensible default */ - + if (length <= 0) { length = 16; } - - /* Allocate the new ArrayList and fill in the fields. There are + + /* Allocate the new ArrayList and fill in the fields. There are * initially no entries. */ new_arraylist = (ArrayList *) malloc(sizeof(ArrayList)); @@ -49,7 +49,7 @@ ArrayList *arraylist_new(unsigned int length) if (new_arraylist == NULL) { return NULL; } - + new_arraylist->_alloced = length; new_arraylist->length = 0; @@ -83,7 +83,7 @@ static int arraylist_enlarge(ArrayList *arraylist) /* Double the allocated size */ newsize = arraylist->_alloced * 2; - + /* Reallocate the array to the new size */ data = realloc(arraylist->data, sizeof(ArrayListValue) * newsize); @@ -108,7 +108,7 @@ int arraylist_insert(ArrayList *arraylist, unsigned int index, } /* Increase the size if necessary */ - + if (arraylist->length + 1 > arraylist->_alloced) { if (!arraylist_enlarge(arraylist)) { return 0; @@ -118,7 +118,7 @@ int arraylist_insert(ArrayList *arraylist, unsigned int index, /* Move the contents of the array forward from the index * onwards */ - memmove(&arraylist->data[index + 1], + memmove(&arraylist->data[index + 1], &arraylist->data[index], (arraylist->length - index) * sizeof(ArrayListValue)); @@ -165,7 +165,7 @@ void arraylist_remove(ArrayList *arraylist, unsigned int index) arraylist_remove_range(arraylist, index, 1); } -int arraylist_index_of(ArrayList *arraylist, +int arraylist_index_of(ArrayList *arraylist, ArrayListEqualFunc callback, ArrayListValue data) { @@ -182,7 +182,7 @@ int arraylist_index_of(ArrayList *arraylist, void arraylist_clear(ArrayList *arraylist) { /* To clear the list, simply set the length to zero */ - + arraylist->length = 0; } @@ -244,16 +244,16 @@ static void arraylist_sort_internal(ArrayListValue *list_data, list2_length = list_length - list1_length - 1; /* list_data[0..list1_length-1] now contains all items which are - * before the pivot. + * before the pivot. * list_data[list1_length..list_length-2] contains all items after * or equal to the pivot. */ - /* Move the pivot into place, by swapping it with the item + /* Move the pivot into place, by swapping it with the item * immediately following the end of list 1. */ list_data[list_length-1] = list_data[list1_length]; list_data[list1_length] = pivot; - + /* Recursively sort the sublists. */ arraylist_sort_internal(list_data, list1_length, compare_func); @@ -265,7 +265,7 @@ static void arraylist_sort_internal(ArrayListValue *list_data, void arraylist_sort(ArrayList *arraylist, ArrayListCompareFunc compare_func) { /* Perform the recursive sort */ - + arraylist_sort_internal(arraylist->data, arraylist->length, compare_func); } diff --git a/src/arraylist.h b/src/arraylist.h index 4f8f915..9042c01 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -2,34 +2,34 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/** +/** * @file arraylist.h * - * @brief Automatically resizing array + * @brief Automatically resizing array * - * ArrayLists are arrays of pointers which automatically increase in + * ArrayLists are arrays of pointers which automatically increase in * size. * * To create an ArrayList, use @ref arraylist_new. * To destroy an ArrayList, use @ref arraylist_free. * - * To add a value to an ArrayList, use @ref arraylist_prepend, + * To add a value to an ArrayList, use @ref arraylist_prepend, * @ref arraylist_append, or @ref arraylist_insert. * * To remove a value from an ArrayList, use @ref arraylist_remove @@ -50,26 +50,26 @@ extern "C" { typedef void *ArrayListValue; /** - * An ArrayList structure. New ArrayLists can be created using the + * An ArrayList structure. New ArrayLists can be created using the * arraylist_new function. * - * @see arraylist_new + * @see arraylist_new */ typedef struct _ArrayList ArrayList; /** * Definition of an @ref ArrayList. - */ + */ struct _ArrayList { /** Entries in the array */ - + ArrayListValue *data; /** Length of the array */ - + unsigned int length; /** Private data and should not be accessed */ @@ -134,7 +134,7 @@ void arraylist_free(ArrayList *arraylist); int arraylist_append(ArrayList *arraylist, ArrayListValue data); -/** +/** * Prepend a value to the beginning of an ArrayList. * * @param arraylist The ArrayList. @@ -168,14 +168,14 @@ void arraylist_remove_range(ArrayList *arraylist, unsigned int index, /** * Insert a value at the specified index in an ArrayList. - * The index where the new value can be inserted is limited by the + * The index where the new value can be inserted is limited by the * size of the ArrayList. * * @param arraylist The ArrayList. * @param index The index at which to insert the value. * @param data The value. - * @return Returns zero if unsuccessful, else non-zero - * if successful (due to an invalid index or + * @return Returns zero if unsuccessful, else non-zero + * if successful (due to an invalid index or * if it was impossible to allocate more memory). */ @@ -197,7 +197,7 @@ int arraylist_index_of(ArrayList *arraylist, ArrayListEqualFunc callback, ArrayListValue data); -/** +/** * Remove all entries from an ArrayList. * * @param arraylist The ArrayList. @@ -205,7 +205,7 @@ int arraylist_index_of(ArrayList *arraylist, void arraylist_clear(ArrayList *arraylist); -/** +/** * Sort the values in an ArrayList. * * @param arraylist The ArrayList. diff --git a/src/avl-tree.c b/src/avl-tree.c index 647bbc7..3ea2058 100644 --- a/src/avl-tree.c +++ b/src/avl-tree.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -51,9 +51,9 @@ AVLTree *avl_tree_new(AVLTreeCompareFunc compare_func) new_tree = (AVLTree *) malloc(sizeof(AVLTree)); if (new_tree == NULL) { - return NULL; + return NULL; } - + new_tree->root_node = NULL; new_tree->compare_func = compare_func; new_tree->num_nodes = 0; @@ -76,7 +76,7 @@ static void avl_tree_free_subtree(AVLTree *tree, AVLTreeNode *node) void avl_tree_free(AVLTree *tree) { /* Destroy all nodes */ - + avl_tree_free_subtree(tree, tree->root_node); /* Free back the main tree data structure */ @@ -163,7 +163,7 @@ static void avl_tree_node_replace(AVLTree *tree, AVLTreeNode *node1, * A D B E * / \ / \ * C E A C - + * is rotated to: is rotated to: * * D B @@ -182,9 +182,9 @@ static AVLTreeNode *avl_tree_rotate(AVLTree *tree, AVLTreeNode *node, for a left rotation, it is the right child, and vice versa. */ new_root = node->children[1-direction]; - + /* Make new_root the root, update parent pointers. */ - + avl_tree_node_replace(tree, node, new_root); /* Rearrange pointers */ @@ -232,7 +232,7 @@ static AVLTreeNode *avl_tree_node_balance(AVLTree *tree, AVLTreeNode *node) - avl_tree_subtree_height(left_subtree); if (diff >= 2) { - + /* Biased toward the right side too much. */ child = right_subtree; @@ -330,7 +330,7 @@ AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) if (new_node == NULL) { return NULL; } - + new_node->children[AVL_TREE_NODE_LEFT] = NULL; new_node->children[AVL_TREE_NODE_RIGHT] = NULL; new_node->parent = previous_node; @@ -353,7 +353,7 @@ AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value) return new_node; } -/* Find the nearest node to the given node, to replace it. +/* Find the nearest node to the given node, to replace it. * The node returned is unlinked from the tree. * Returns NULL if the node has no children. */ @@ -387,7 +387,7 @@ static AVLTreeNode *avl_tree_node_get_replacement(AVLTree *tree, } else { side = AVL_TREE_NODE_LEFT; } - + /* Search down the tree, back towards the center. */ result = node->children[side]; @@ -398,7 +398,7 @@ static AVLTreeNode *avl_tree_node_get_replacement(AVLTree *tree, /* Unlink the result node, and hook in its remaining child * (if it has one) to replace it. */ - + child = result->children[side]; avl_tree_node_replace(tree, result, child); @@ -490,7 +490,7 @@ int avl_tree_remove(AVLTree *tree, AVLTreeKey key) if (node == NULL) { /* Not found in tree */ - + return 0; } @@ -505,22 +505,22 @@ AVLTreeNode *avl_tree_lookup_node(AVLTree *tree, AVLTreeKey key) { AVLTreeNode *node; int diff; - - /* Search down the tree and attempt to find the node which + + /* Search down the tree and attempt to find the node which * has the specified key */ node = tree->root_node; while (node != NULL) { - + diff = tree->compare_func(key, node->key); if (diff == 0) { /* Keys are equal: return this node */ - + return node; - + } else if (diff < 0) { node = node->children[AVL_TREE_NODE_LEFT]; } else { @@ -582,21 +582,21 @@ unsigned int avl_tree_num_entries(AVLTree *tree) return tree->num_nodes; } -static void avl_tree_to_array_add_subtree(AVLTreeNode *subtree, - AVLTreeValue *array, +static void avl_tree_to_array_add_subtree(AVLTreeNode *subtree, + AVLTreeValue *array, int *index) { if (subtree == NULL) { return; } - + /* Add left subtree first */ avl_tree_to_array_add_subtree(subtree->children[AVL_TREE_NODE_LEFT], array, index); - + /* Add this node */ - + array[*index] = subtree->key; ++*index; diff --git a/src/avl-tree.h b/src/avl-tree.h index 0d4087c..4ae3dcd 100644 --- a/src/avl-tree.h +++ b/src/avl-tree.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -22,11 +22,11 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @brief Balanced binary tree * - * The AVL tree structure is a balanced binary tree which stores + * The AVL tree structure is a balanced binary tree which stores * a collection of nodes (see @ref AVLTreeNode). Each node has * a key and a value associated with it. The nodes are sorted * within the tree based on the order of their keys. Modifications - * to the tree are constructed such that the tree remains + * to the tree are constructed such that the tree remains * balanced at all times (there are always roughly equal numbers * of nodes on either side of the tree). * @@ -41,10 +41,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @ref avl_tree_insert. To remove an entry from an * AVL tree, use @ref avl_tree_remove or @ref avl_tree_remove_node. * - * To search an AVL tree, use @ref avl_tree_lookup or + * To search an AVL tree, use @ref avl_tree_lookup or * @ref avl_tree_lookup_node. * - * Tree nodes can be queried using the + * Tree nodes can be queried using the * @ref avl_tree_node_child, * @ref avl_tree_node_parent, * @ref avl_tree_node_key and @@ -90,7 +90,7 @@ typedef void *AVLTreeValue; * @see avl_tree_node_left_child * @see avl_tree_node_right_child * @see avl_tree_node_parent - * @see avl_tree_node_key + * @see avl_tree_node_key * @see avl_tree_node_value */ @@ -111,7 +111,7 @@ typedef enum { * @param value1 The first key. * @param value2 The second key. * @return A negative number if value1 should be sorted - * before value2, a positive number if value2 should + * before value2, a positive number if value2 should * be sorted before value1, zero if the two keys * are equal. */ @@ -122,7 +122,7 @@ typedef int (*AVLTreeCompareFunc)(AVLTreeValue value1, AVLTreeValue value2); * Create a new AVL tree. * * @param compare_func Function to use when comparing keys in the tree. - * @return A new AVL tree, or NULL if it was not possible + * @return A new AVL tree, or NULL if it was not possible * to allocate the memory. */ @@ -130,7 +130,7 @@ AVLTree *avl_tree_new(AVLTreeCompareFunc compare_func); /** * Destroy an AVL tree. - * + * * @param tree The tree to destroy. */ @@ -185,14 +185,14 @@ AVLTreeNode *avl_tree_lookup_node(AVLTree *tree, AVLTreeKey key); /** * Search an AVL tree for a value corresponding to a particular key. - * This uses the tree as a mapping. Note that this performs + * This uses the tree as a mapping. Note that this performs * identically to @ref avl_tree_lookup_node, except that the value * at the node is returned rather than the node itself. * * @param tree The AVL tree to search. * @param key The key to search for. - * @return The value associated with the given key, or - * @ref AVL_TREE_NULL if no entry with the given key is + * @return The value associated with the given key, or + * @ref AVL_TREE_NULL if no entry with the given key is * found. */ @@ -202,7 +202,7 @@ AVLTreeValue avl_tree_lookup(AVLTree *tree, AVLTreeKey key); * Find the root node of a tree. * * @param tree The tree. - * @return The root node of the tree, or NULL if the tree is + * @return The root node of the tree, or NULL if the tree is * empty. */ @@ -217,7 +217,7 @@ AVLTreeNode *avl_tree_root_node(AVLTree *tree); AVLTreeKey avl_tree_node_key(AVLTreeNode *node); -/** +/** * Retrieve the value at a given tree node. * * @param node The tree node. @@ -241,7 +241,7 @@ AVLTreeNode *avl_tree_node_child(AVLTreeNode *node, AVLTreeNodeSide side); * Find the parent node of a given tree node. * * @param node The tree node. - * @return The parent node of the tree node, or NULL if + * @return The parent node of the tree node, or NULL if * this is the root node. */ @@ -257,7 +257,7 @@ AVLTreeNode *avl_tree_node_parent(AVLTreeNode *node); int avl_tree_subtree_height(AVLTreeNode *node); /** - * Convert the keys in an AVL tree into a C array. This allows + * Convert the keys in an AVL tree into a C array. This allows * the tree to be used as an ordered set. * * @param tree The tree. diff --git a/src/binary-heap.c b/src/binary-heap.c index c071947..70f1fd2 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -55,11 +55,11 @@ BinaryHeap *binary_heap_new(BinaryHeapType heap_type, if (heap == NULL) { return NULL; } - + heap->heap_type = heap_type; heap->num_values = 0; heap->compare_func = compare_func; - + /* Initial size of 16 elements */ heap->alloced_size = 16; @@ -69,7 +69,7 @@ BinaryHeap *binary_heap_new(BinaryHeapType heap_type, free(heap); return NULL; } - + return heap; } @@ -119,7 +119,7 @@ int binary_heap_insert(BinaryHeap *heap, BinaryHeapValue value) /* Compare the node with its parent */ if (binary_heap_cmp(heap, heap->values[parent], value) < 0) { - + /* Ordered correctly - insertion is complete */ break; @@ -174,13 +174,13 @@ BinaryHeapValue binary_heap_pop(BinaryHeap *heap) for (;;) { /* Calculate the array indexes of the children of this node */ - + child1 = index * 2 + 1; child2 = index * 2 + 2; if (child1 < heap->num_values - && binary_heap_cmp(heap, - new_value, + && binary_heap_cmp(heap, + new_value, heap->values[child1]) > 0) { /* Left child is less than the node. We need to swap @@ -194,13 +194,13 @@ BinaryHeapValue binary_heap_pop(BinaryHeap *heap) } else { next_index = child1; } - + } else if (child2 < heap->num_values - && binary_heap_cmp(heap, - new_value, + && binary_heap_cmp(heap, + new_value, heap->values[child2]) > 0) { - /* Right child is less than the node. Swap with the + /* Right child is less than the node. Swap with the * right child. */ next_index = child2; diff --git a/src/binary-heap.h b/src/binary-heap.h index 7840ff1..2d54f60 100644 --- a/src/binary-heap.h +++ b/src/binary-heap.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -23,10 +23,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @brief Binary heap. * - * A binary heap is a heap data structure implemented using a + * A binary heap is a heap data structure implemented using a * binary tree. In a heap, values are ordered by priority. * - * To create a binary heap, use @ref binary_heap_new. To destroy a + * To create a binary heap, use @ref binary_heap_new. To destroy a * binary heap, use @ref binary_heap_free. * * To insert a value into a binary heap, use @ref binary_heap_insert. @@ -43,9 +43,9 @@ extern "C" { #endif /** - * Heap type. If a heap is a min heap (@ref BINARY_HEAP_TYPE_MIN), the + * Heap type. If a heap is a min heap (@ref BINARY_HEAP_TYPE_MIN), the * values with the lowest priority are stored at the top of the heap and - * will be the first returned. If a heap is a max heap + * will be the first returned. If a heap is a max heap * (@ref BINARY_HEAP_TYPE_MAX), the values with the greatest priority are * stored at the top of the heap. */ @@ -85,14 +85,14 @@ typedef void *BinaryHeapValue; typedef int (*BinaryHeapCompareFunc)(BinaryHeapValue value1, BinaryHeapValue value2); -/** +/** * A binary heap data structure. */ typedef struct _BinaryHeap BinaryHeap; /** - * Create a new @ref BinaryHeap. + * Create a new @ref BinaryHeap. * * @param heap_type The type of heap: min heap or max heap. * @param compare_func Pointer to a function used to compare the priority @@ -128,7 +128,7 @@ int binary_heap_insert(BinaryHeap *heap, BinaryHeapValue value); * Remove the first value from a binary heap. * * @param heap The heap. - * @return The first value in the heap, or + * @return The first value in the heap, or * @ref BINARY_HEAP_NULL if the heap is empty. */ diff --git a/src/binomial-heap.c b/src/binomial-heap.c index ec96646..4c2bf12 100644 --- a/src/binomial-heap.c +++ b/src/binomial-heap.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -49,8 +49,8 @@ struct _BinomialHeap unsigned int roots_length; }; -static int binomial_heap_cmp(BinomialHeap *heap, - BinomialHeapValue data1, +static int binomial_heap_cmp(BinomialHeap *heap, + BinomialHeapValue data1, BinomialHeapValue data2) { if (heap->heap_type == BINOMIAL_HEAP_TYPE_MIN) { @@ -74,7 +74,7 @@ static void binomial_tree_unref(BinomialTree *tree) if (tree == NULL) { return; } - + /* Subtract a reference */ --tree->refcount; @@ -138,7 +138,7 @@ static BinomialTree *binomial_tree_merge(BinomialHeap *heap, return NULL; } - memcpy(new_tree->subtrees, tree1->subtrees, + memcpy(new_tree->subtrees, tree1->subtrees, sizeof(BinomialTree *) * tree1->order); new_tree->subtrees[new_tree->order - 1] = tree2; @@ -147,11 +147,11 @@ static BinomialTree *binomial_tree_merge(BinomialHeap *heap, for (i=0; iorder; ++i) { binomial_tree_ref(new_tree->subtrees[i]); } - + return new_tree; } -/* Used to perform an "undo" when an error occurs during +/* Used to perform an "undo" when an error occurs during * binomial_heap_merge. Go through the list of roots so far and remove * references that have been added. */ @@ -167,7 +167,7 @@ static void binomial_heap_merge_undo(BinomialTree **new_roots, free(new_roots); } -/* Merge the data in the 'other' heap into the 'heap' heap. +/* Merge the data in the 'other' heap into the 'heap' heap. * Returns non-zero if successful. */ static int binomial_heap_merge(BinomialHeap *heap, BinomialHeap *other) @@ -205,7 +205,7 @@ static int binomial_heap_merge(BinomialHeap *heap, BinomialHeap *other) carry = NULL; for (i=0; iroots); heap->roots = new_roots; heap->roots_length = new_roots_length; @@ -321,7 +321,7 @@ BinomialHeap *binomial_heap_new(BinomialHeapType heap_type, BinomialHeap *new_heap; /* Allocate a new heap */ - + new_heap = calloc(1, sizeof(BinomialHeap)); if (new_heap == NULL) { @@ -346,7 +346,7 @@ void binomial_heap_free(BinomialHeap *heap) for (i=0; iroots_length; ++i) { binomial_tree_unref(heap->roots[i]); } - + /* Free the heap itself */ free(heap->roots); @@ -368,9 +368,9 @@ int binomial_heap_insert(BinomialHeap *heap, BinomialHeapValue value) } /* Fill in values. This has an initial reference count of 1 that - * the "fake" heap holds; this will be removed at the end of + * the "fake" heap holds; this will be removed at the end of * this function. */ - + new_tree->value = value; new_tree->order = 0; new_tree->refcount = 1; @@ -457,7 +457,7 @@ BinomialHeapValue binomial_heap_pop(BinomialHeap *heap) --heap->num_values; return result; - + } else { /* Add the least tree back */ diff --git a/src/binomial-heap.h b/src/binomial-heap.h index 5d3511b..59dd08e 100644 --- a/src/binomial-heap.h +++ b/src/binomial-heap.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -23,10 +23,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @brief Binomial heap. * - * A binomial heap is a heap data structure implemented using a + * A binomial heap is a heap data structure implemented using a * binomial tree. In a heap, values are ordered by priority. * - * To create a binomial heap, use @ref binomial_heap_new. To destroy a + * To create a binomial heap, use @ref binomial_heap_new. To destroy a * binomial heap, use @ref binomial_heap_free. * * To insert a value into a binomial heap, use @ref binomial_heap_insert. @@ -43,7 +43,7 @@ extern "C" { #endif /** - * Heap type. If a heap is a min heap (@ref BINOMIAL_HEAP_TYPE_MIN), the + * Heap type. If a heap is a min heap (@ref BINOMIAL_HEAP_TYPE_MIN), the * values with the lowest priority are stored at the top of the heap and * will be the first returned. If a heap is a max heap * (@ref BINOMIAL_HEAP_TYPE_MAX), the values with the greatest priority @@ -82,17 +82,17 @@ typedef void *BinomialHeapValue; * zero if the two are equal. */ -typedef int (*BinomialHeapCompareFunc)(BinomialHeapValue value1, +typedef int (*BinomialHeapCompareFunc)(BinomialHeapValue value1, BinomialHeapValue value2); -/** +/** * A binomial heap data structure. */ typedef struct _BinomialHeap BinomialHeap; /** - * Create a new @ref BinomialHeap. + * Create a new @ref BinomialHeap. * * @param heap_type The type of heap: min heap or max heap. * @param compare_func Pointer to a function used to compare the priority @@ -128,7 +128,7 @@ int binomial_heap_insert(BinomialHeap *heap, BinomialHeapValue value); * Remove the first value from a binomial heap. * * @param heap The heap. - * @return The first value in the heap, or + * @return The first value in the heap, or * @ref BINOMIAL_HEAP_NULL if the heap is empty. */ diff --git a/src/bloom-filter.c b/src/bloom-filter.c index 334cc56..8f9bd68 100644 --- a/src/bloom-filter.c +++ b/src/bloom-filter.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -68,13 +68,13 @@ static const unsigned int salts[] = { 0xa27e2a58, 0x66866fc5, 0x12519ce7, 0x437a8456, }; -BloomFilter *bloom_filter_new(unsigned int table_size, +BloomFilter *bloom_filter_new(unsigned int table_size, BloomFilterHashFunc hash_func, unsigned int num_functions) { BloomFilter *filter; - /* There is a limit on the number of functions which can be + /* There is a limit on the number of functions which can be * applied, due to the table size */ if (num_functions > sizeof(salts) / sizeof(*salts)) { @@ -138,7 +138,7 @@ void bloom_filter_insert(BloomFilter *bloomfilter, BloomFilterValue value) index = subhash % bloomfilter->table_size; - /* Insert into the table. + /* Insert into the table. * index / 8 finds the byte index of the table, * index % 8 gives the bit index within that byte to set. */ @@ -238,8 +238,8 @@ BloomFilter *bloom_filter_union(BloomFilter *filter1, BloomFilter *filter2) /* Create a new bloom filter for the result */ - result = bloom_filter_new(filter1->table_size, - filter1->hash_func, + result = bloom_filter_new(filter1->table_size, + filter1->hash_func, filter1->num_functions); if (result == NULL) { @@ -260,7 +260,7 @@ BloomFilter *bloom_filter_union(BloomFilter *filter1, BloomFilter *filter2) return result; } -BloomFilter *bloom_filter_intersection(BloomFilter *filter1, +BloomFilter *bloom_filter_intersection(BloomFilter *filter1, BloomFilter *filter2) { BloomFilter *result; @@ -278,8 +278,8 @@ BloomFilter *bloom_filter_intersection(BloomFilter *filter1, /* Create a new bloom filter for the result */ - result = bloom_filter_new(filter1->table_size, - filter1->hash_func, + result = bloom_filter_new(filter1->table_size, + filter1->hash_func, filter1->num_functions); if (result == NULL) { diff --git a/src/bloom-filter.h b/src/bloom-filter.h index 364d4f5..029e159 100644 --- a/src/bloom-filter.h +++ b/src/bloom-filter.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -25,15 +25,15 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * A bloom filter is a space efficient data structure that can be * used to test whether a given element is part of a set. Lookups - * will occasionally generate false positives, but never false - * negatives. + * will occasionally generate false positives, but never false + * negatives. * - * To create a bloom filter, use @ref bloom_filter_new. To destroy a + * To create a bloom filter, use @ref bloom_filter_new. To destroy a * bloom filter, use @ref bloom_filter_free. * * To insert a value into a bloom filter, use @ref bloom_filter_insert. * - * To query whether a value is part of the set, use + * To query whether a value is part of the set, use * @ref bloom_filter_query. */ @@ -44,7 +44,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif -/** +/** * A bloom filter structure. */ @@ -57,7 +57,7 @@ typedef struct _BloomFilter BloomFilter; typedef void *BloomFilterValue; /** - * Hash function used to generate hash values for values inserted into a + * Hash function used to generate hash values for values inserted into a * bloom filter. * * @param data The value to generate a hash value for. @@ -81,12 +81,12 @@ typedef unsigned int (*BloomFilterHashFunc)(BloomFilterValue data); * value. The more functions applied, the lesser * the chance of false positives. The maximum * number of functions is 64. - * @return A new hash table structure, or NULL if it + * @return A new hash table structure, or NULL if it * was not possible to allocate the new bloom * filter. */ -BloomFilter *bloom_filter_new(unsigned int table_size, +BloomFilter *bloom_filter_new(unsigned int table_size, BloomFilterHashFunc hash_func, unsigned int num_functions); @@ -112,7 +112,7 @@ void bloom_filter_insert(BloomFilter *bloomfilter, BloomFilterValue value); * * @param bloomfilter The bloom filter. * @param value The value to look up. - * @return Zero if the value was definitely not + * @return Zero if the value was definitely not * inserted into the filter. Non-zero * indicates that it either may or may not * have been inserted. @@ -125,7 +125,7 @@ int bloom_filter_query(BloomFilter *bloomfilter, BloomFilterValue value); * * @param bloomfilter The bloom filter. * @param array Pointer to the array to read into. This - * should be (table_size + 7) / 8 bytes in + * should be (table_size + 7) / 8 bytes in * length. */ @@ -138,19 +138,19 @@ void bloom_filter_read(BloomFilter *bloomfilter, unsigned char *array); * the original filter. * * @param bloomfilter The bloom filter. - * @param array Pointer to the array to load from. This - * should be (table_size + 7) / 8 bytes in + * @param array Pointer to the array to load from. This + * should be (table_size + 7) / 8 bytes in * length. */ void bloom_filter_load(BloomFilter *bloomfilter, unsigned char *array); -/** - * Find the union of two bloom filters. Values are present in the - * resulting filter if they are present in either of the original +/** + * Find the union of two bloom filters. Values are present in the + * resulting filter if they are present in either of the original * filters. * - * Both of the original filters must have been created using the + * Both of the original filters must have been created using the * same parameters to @ref bloom_filter_new. * * @param filter1 The first filter. @@ -159,18 +159,18 @@ void bloom_filter_load(BloomFilter *bloomfilter, unsigned char *array); * two filters, or NULL if it was not possible * to allocate memory for the new filter, or * if the two filters specified were created - * with different parameters. + * with different parameters. */ -BloomFilter *bloom_filter_union(BloomFilter *filter1, +BloomFilter *bloom_filter_union(BloomFilter *filter1, BloomFilter *filter2); -/** - * Find the intersection of two bloom filters. Values are only ever +/** + * Find the intersection of two bloom filters. Values are only ever * present in the resulting filter if they are present in both of the * original filters. * - * Both of the original filters must have been created using the + * Both of the original filters must have been created using the * same parameters to @ref bloom_filter_new. * * @param filter1 The first filter. @@ -179,10 +179,10 @@ BloomFilter *bloom_filter_union(BloomFilter *filter1, * two filters, or NULL if it was not possible * to allocate memory for the new filter, or * if the two filters specified were created - * with different parameters. + * with different parameters. */ -BloomFilter *bloom_filter_intersection(BloomFilter *filter1, +BloomFilter *bloom_filter_intersection(BloomFilter *filter1, BloomFilter *filter2); #ifdef __cplusplus diff --git a/src/compare-int.c b/src/compare-int.c index 38805e5..c1b41a0 100644 --- a/src/compare-int.c +++ b/src/compare-int.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ diff --git a/src/compare-int.h b/src/compare-int.h index 22269df..eac41bc 100644 --- a/src/compare-int.h +++ b/src/compare-int.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -23,8 +23,8 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Comparison functions for pointers to integers. * - * To find the difference between two values pointed at, use - * @ref int_compare. + * To find the difference between two values pointed at, use + * @ref int_compare. * * To find if two values pointed at are equal, use @ref int_equal. */ @@ -42,7 +42,7 @@ extern "C" { * * @param location1 Pointer to the first value to compare. * @param location2 Pointer to the second value to compare. - * @return Non-zero if the two values are equal, zero if the + * @return Non-zero if the two values are equal, zero if the * two values are not equal. */ @@ -53,7 +53,7 @@ int int_equal(void *location1, void *location2); * * @param location1 Pointer to the first value to compare. * @param location2 Pointer to the second value to compare. - * @return A negative value if the first value is less than + * @return A negative value if the first value is less than * the second value, a positive value if the first * value is greater than the second value, zero if * they are equal. diff --git a/src/compare-pointer.c b/src/compare-pointer.c index 94e1b28..3afde9d 100644 --- a/src/compare-pointer.c +++ b/src/compare-pointer.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ diff --git a/src/compare-pointer.h b/src/compare-pointer.h index 28a4009..b665748 100644 --- a/src/compare-pointer.h +++ b/src/compare-pointer.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -36,7 +36,7 @@ extern "C" { #endif /** - * Compare two pointers to determine if they are equal. + * Compare two pointers to determine if they are equal. * * @param location1 The first pointer. * @param location2 The second pointer. diff --git a/src/compare-string.c b/src/compare-string.c index 5d0e66c..95f9622 100644 --- a/src/compare-string.c +++ b/src/compare-string.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -36,7 +36,7 @@ int string_compare(void *string1, void *string2) int result; result = strcmp((char *) string1, (char *) string2); - + if (result < 0) { return -1; } else if (result > 0) { diff --git a/src/compare-string.h b/src/compare-string.h index 51826a4..05427db 100644 --- a/src/compare-string.h +++ b/src/compare-string.h @@ -2,25 +2,25 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /** * @file compare-string.h - * + * * Comparison functions for strings. * * To find the difference between two strings, use @ref string_compare. @@ -63,7 +63,7 @@ int string_equal(void *string1, void *string2); int string_compare(void *string1, void *string2); /** - * Compare two strings to determine if they are equal, ignoring the + * Compare two strings to determine if they are equal, ignoring the * case of letters. * * @param string1 The first string. diff --git a/src/hash-int.c b/src/hash-int.c index 70c0f04..47892b4 100644 --- a/src/hash-int.c +++ b/src/hash-int.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ diff --git a/src/hash-int.h b/src/hash-int.h index bb6e43f..f3101ff 100644 --- a/src/hash-int.h +++ b/src/hash-int.h @@ -2,23 +2,23 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/** +/** * @file hash-int.h * * Hash function for a pointer to an integer. See @ref int_hash. @@ -31,7 +31,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif -/** +/** * Generate a hash key for a pointer to an integer. The value pointed * at is used to generate the key. * diff --git a/src/hash-pointer.c b/src/hash-pointer.c index 3943353..3f66509 100644 --- a/src/hash-pointer.c +++ b/src/hash-pointer.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ diff --git a/src/hash-pointer.h b/src/hash-pointer.h index 6cc1657..6186a71 100644 --- a/src/hash-pointer.h +++ b/src/hash-pointer.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -31,7 +31,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif -/** +/** * Generate a hash key for a pointer. The value pointed at by the pointer * is not used, only the pointer itself. * diff --git a/src/hash-string.c b/src/hash-string.c index 313efff..a640e65 100644 --- a/src/hash-string.c +++ b/src/hash-string.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ diff --git a/src/hash-string.h b/src/hash-string.h index d81087d..d9b2890 100644 --- a/src/hash-string.h +++ b/src/hash-string.h @@ -2,26 +2,26 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /** * @file hash-string.h * - * Hash functions for text strings. For more information + * Hash functions for text strings. For more information * see @ref string_hash or @ref string_nocase_hash. */ diff --git a/src/hash-table.c b/src/hash-table.c index dce89a2..90ccfb5 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -60,7 +60,7 @@ static const unsigned int hash_table_primes[] = { 402653189, 805306457, 1610612741, }; -static const unsigned int hash_table_num_primes +static const unsigned int hash_table_num_primes = sizeof(hash_table_primes) / sizeof(int); /* Internal function used to allocate the table on hash table creation @@ -70,7 +70,7 @@ static int hash_table_allocate_table(HashTable *hash_table) { unsigned int new_table_size; - /* Determine the table size based on the current prime index. + /* Determine the table size based on the current prime index. * An attempt is made here to ensure sensible behavior if the * maximum prime is exceeded, but in practice other things are * likely to break long before that happens. */ @@ -85,7 +85,7 @@ static int hash_table_allocate_table(HashTable *hash_table) /* Allocate the table and initialise to NULL for all entries */ - hash_table->table = calloc(hash_table->table_size, + hash_table->table = calloc(hash_table->table_size, sizeof(HashTableEntry *)); return hash_table->table != NULL; @@ -97,7 +97,7 @@ static void hash_table_free_entry(HashTable *hash_table, HashTableEntry *entry) { /* If there is a function registered for freeing keys, use it to free * the key */ - + if (hash_table->key_free_func != NULL) { hash_table->key_free_func(entry->key); } @@ -109,23 +109,23 @@ static void hash_table_free_entry(HashTable *hash_table, HashTableEntry *entry) } /* Free the data structure */ - + free(entry); } -HashTable *hash_table_new(HashTableHashFunc hash_func, +HashTable *hash_table_new(HashTableHashFunc hash_func, HashTableEqualFunc equal_func) { HashTable *hash_table; /* Allocate a new hash table structure */ - + hash_table = (HashTable *) malloc(sizeof(HashTable)); if (hash_table == NULL) { return NULL; } - + hash_table->hash_func = hash_func; hash_table->equal_func = equal_func; hash_table->key_free_func = NULL; @@ -149,7 +149,7 @@ void hash_table_free(HashTable *hash_table) HashTableEntry *rover; HashTableEntry *next; unsigned int i; - + /* Free all entries in all chains */ for (i=0; itable_size; ++i) { @@ -160,11 +160,11 @@ void hash_table_free(HashTable *hash_table) rover = next; } } - + /* Free the table */ free(hash_table->table); - + /* Free the hash table structure */ free(hash_table); @@ -188,9 +188,9 @@ static int hash_table_enlarge(HashTable *hash_table) HashTableEntry *next; unsigned int index; unsigned int i; - + /* Store a copy of the old table */ - + old_table = hash_table->table; old_table_size = hash_table->table_size; old_prime_index = hash_table->prime_index; @@ -198,7 +198,7 @@ static int hash_table_enlarge(HashTable *hash_table) /* Allocate a new, larger table */ ++hash_table->prime_index; - + if (!hash_table_allocate_table(hash_table)) { /* Failed to allocate the new table */ @@ -219,14 +219,14 @@ static int hash_table_enlarge(HashTable *hash_table) next = rover->next; /* Find the index into the new table */ - + index = hash_table->hash_func(rover->key) % hash_table->table_size; - + /* Link this entry into the chain */ rover->next = hash_table->table[index]; hash_table->table[index] = rover; - + /* Advance to next in the chain */ rover = next; @@ -236,22 +236,22 @@ static int hash_table_enlarge(HashTable *hash_table) /* Free the old table */ free(old_table); - + return 1; } -int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue value) +int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue value) { HashTableEntry *rover; HashTableEntry *newentry; unsigned int index; - + /* If there are too many items in the table with respect to the table * size, the number of hash collisions increases and performance * decreases. Enlarge the table size to prevent this happening */ if ((hash_table->entries * 3) / hash_table->table_size > 0) { - + /* Table is more than 1/3 full */ if (!hash_table_enlarge(hash_table)) { @@ -283,7 +283,7 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue va hash_table->value_free_func(rover->value); } - /* Same with the key: use the new key value and free + /* Same with the key: use the new key value and free * the old one */ if (hash_table->key_free_func != NULL) { @@ -294,12 +294,12 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue va rover->value = value; /* Finished */ - + return 1; } rover = rover->next; } - + /* Not in the hash table yet. Create a new entry */ newentry = (HashTableEntry *) malloc(sizeof(HashTableEntry)); @@ -331,7 +331,7 @@ HashTableValue hash_table_lookup(HashTable *hash_table, HashTableKey key) unsigned int index; /* Generate the hash of the key and hence the index into the table */ - + index = hash_table->hash_func(key) % hash_table->table_size; /* Walk the chain at this index until the corresponding entry is @@ -362,7 +362,7 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key) int result; /* Generate the hash of the key and hence the index into the table */ - + index = hash_table->hash_func(key) % hash_table->table_size; /* Rover points at the pointer which points at the current entry @@ -397,7 +397,7 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key) break; } - + /* Advance to the next entry */ rover = &((*rover)->next); diff --git a/src/hash-table.h b/src/hash-table.h index ba5717f..b578500 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -23,11 +23,11 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @brief Hash table. * - * A hash table stores a set of values which can be addressed by a + * A hash table stores a set of values which can be addressed by a * key. Given the key, the corresponding value can be looked up * quickly. * - * To create a hash table, use @ref hash_table_new. To destroy a + * To create a hash table, use @ref hash_table_new. To destroy a * hash table, use @ref hash_table_free. * * To insert a value into a hash table, use @ref hash_table_insert. @@ -36,9 +36,9 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * To look up a value by its key, use @ref hash_table_lookup. * - * To iterate over all values in a hash table, use + * To iterate over all values in a hash table, use * @ref hash_table_iterate to initialise a @ref HashTableIterator - * structure. Each value can then be read in turn using + * structure. Each value can then be read in turn using * @ref hash_table_iter_next and @ref hash_table_iter_has_more. */ @@ -49,7 +49,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif -/** +/** * A hash table structure. */ @@ -90,7 +90,7 @@ struct _HashTableIterator { }; /** - * A null @ref HashTableValue. + * A null @ref HashTableValue. */ #define HASH_TABLE_NULL ((void *) 0) @@ -108,21 +108,21 @@ typedef unsigned int (*HashTableHashFunc)(HashTableKey value); /** * Function used to compare two keys for equality. * - * @return Non-zero if the two keys are equal, zero if the keys are + * @return Non-zero if the two keys are equal, zero if the keys are * not equal. */ typedef int (*HashTableEqualFunc)(HashTableKey value1, HashTableKey value2); /** - * Type of function used to free keys when entries are removed from a + * Type of function used to free keys when entries are removed from a * hash table. */ typedef void (*HashTableKeyFreeFunc)(HashTableKey value); /** - * Type of function used to free values when entries are removed from a + * Type of function used to free values when entries are removed from a * hash table. */ @@ -131,16 +131,16 @@ typedef void (*HashTableValueFreeFunc)(HashTableValue value); /** * Create a new hash table. * - * @param hash_func Function used to generate hash keys for the + * @param hash_func Function used to generate hash keys for the * keys used in the table. - * @param equal_func Function used to test keys used in the table + * @param equal_func Function used to test keys used in the table * for equality. - * @return A new hash table structure, or NULL if it + * @return A new hash table structure, or NULL if it * was not possible to allocate the new hash * table. */ -HashTable *hash_table_new(HashTableHashFunc hash_func, +HashTable *hash_table_new(HashTableHashFunc hash_func, HashTableEqualFunc equal_func); /** @@ -165,7 +165,7 @@ void hash_table_register_free_functions(HashTable *hash_table, HashTableValueFreeFunc value_free_func); /** - * Insert a value into a hash table, overwriting any existing entry + * Insert a value into a hash table, overwriting any existing entry * using the same key. * * @param hash_table The hash table. @@ -176,8 +176,8 @@ void hash_table_register_free_functions(HashTable *hash_table, * memory for the new entry. */ -int hash_table_insert(HashTable *hash_table, - HashTableKey key, +int hash_table_insert(HashTable *hash_table, + HashTableKey key, HashTableValue value); /** @@ -185,11 +185,11 @@ int hash_table_insert(HashTable *hash_table, * * @param hash_table The hash table. * @param key The key of the value to look up. - * @return The value, or @ref HASH_TABLE_NULL if there + * @return The value, or @ref HASH_TABLE_NULL if there * is no value with that key in the hash table. */ -HashTableValue hash_table_lookup(HashTable *hash_table, +HashTableValue hash_table_lookup(HashTable *hash_table, HashTableKey key); /** @@ -203,7 +203,7 @@ HashTableValue hash_table_lookup(HashTable *hash_table, int hash_table_remove(HashTable *hash_table, HashTableKey key); -/** +/** * Retrieve the number of entries in a hash table. * * @param hash_table The hash table. @@ -216,7 +216,7 @@ unsigned int hash_table_num_entries(HashTable *hash_table); * Initialise a @ref HashTableIterator to iterate over a hash table. * * @param hash_table The hash table. - * @param iter Pointer to an iterator structure to + * @param iter Pointer to an iterator structure to * initialise. */ @@ -224,11 +224,11 @@ void hash_table_iterate(HashTable *hash_table, HashTableIterator *iter); /** * Determine if there are more keys in the hash table to iterate - * over. + * over. * * @param iterator The hash table iterator. * @return Zero if there are no more values to iterate - * over, non-zero if there are more values to + * over, non-zero if there are more values to * iterate over. */ @@ -238,8 +238,8 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * Using a hash table iterator, retrieve the next key. * * @param iterator The hash table iterator. - * @return The next key from the hash table, or - * @ref HASH_TABLE_NULL if there are no more + * @return The next key from the hash table, or + * @ref HASH_TABLE_NULL if there are no more * keys to iterate over. */ diff --git a/src/libcalg.h b/src/libcalg.h index fc50a4c..59d8926 100644 --- a/src/libcalg.h +++ b/src/libcalg.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ diff --git a/src/list.c b/src/list.c index 04d9dee..1545ef3 100644 --- a/src/list.c +++ b/src/list.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -47,7 +47,7 @@ void list_free(ListEntry *list) while (entry != NULL) { ListEntry *next; - + next = entry->next; free(entry); @@ -67,7 +67,7 @@ ListEntry *list_prepend(ListEntry **list, ListValue data) if (newentry == NULL) { return NULL; } - + newentry->data = data; /* Hook into the list start */ @@ -94,10 +94,10 @@ ListEntry *list_append(ListEntry **list, ListValue data) if (newentry == NULL) { return NULL; } - + newentry->data = data; newentry->next = NULL; - + /* Hooking into the list is different if the list is empty */ if (*list == NULL) { @@ -237,7 +237,7 @@ int list_remove_entry(ListEntry **list, ListEntry *entry) if (*list == NULL || entry == NULL) { return 0; } - + /* Action to take is different if the entry is the first in the list */ if (entry->prev == NULL) { @@ -255,8 +255,8 @@ int list_remove_entry(ListEntry **list, ListEntry *entry) } else { - /* This is not the first in the list, so we must have a - * previous entry. Update its 'next' pointer to the new + /* This is not the first in the list, so we must have a + * previous entry. Update its 'next' pointer to the new * value */ entry->prev->next = entry->next; @@ -335,14 +335,14 @@ unsigned int list_remove_data(ListEntry **list, ListEqualFunc callback, /* Function used internally for sorting. Returns the last entry in the * new sorted list */ -static ListEntry *list_sort_internal(ListEntry **list, +static ListEntry *list_sort_internal(ListEntry **list, ListCompareFunc compare_func) { ListEntry *pivot; ListEntry *rover; ListEntry *less_list, *more_list; ListEntry *less_list_end, *more_list_end; - + /* If there are less than two entries in this list, it is * already sorted */ @@ -418,8 +418,8 @@ static ListEntry *list_sort_internal(ListEntry **list, more_list->prev = pivot; } - /* Work out what the last entry in the list is. If the more list was - * empty, the pivot was the last entry. Otherwise, the end of the + /* Work out what the last entry in the list is. If the more list was + * empty, the pivot was the last entry. Otherwise, the end of the * more list is the end of the total list. */ if (more_list == NULL) { @@ -447,7 +447,7 @@ ListEntry *list_find_data(ListEntry *list, return rover; } } - + /* Not found */ return NULL; @@ -476,8 +476,8 @@ int list_iter_has_more(ListIterator *iter) return *iter->prev_next != NULL; } else { - /* The current entry as not been deleted since the last - * call to list_iter_next: there is a next entry if + /* The current entry as not been deleted since the last + * call to list_iter_next: there is a next entry if * current->next is not NULL */ return iter->current->next != NULL; @@ -502,7 +502,7 @@ ListValue list_iter_next(ListIterator *iter) iter->prev_next = &iter->current->next; iter->current = iter->current->next; } - + /* Have we reached the end of the list? */ if (iter->current == NULL) { @@ -516,12 +516,12 @@ void list_iter_remove(ListIterator *iter) { if (iter->current == NULL || iter->current != *iter->prev_next) { - /* Either we have not yet read the first item, we have + /* Either we have not yet read the first item, we have * reached the end of the list, or we have already removed * the current value. Either way, do nothing. */ } else { - + /* Remove the current entry */ *iter->prev_next = iter->current->next; diff --git a/src/list.h b/src/list.h index af16f58..88796ff 100644 --- a/src/list.h +++ b/src/list.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -26,7 +26,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * A doubly-linked list stores a collection of values. Each entry in * the list (represented by a pointer a @ref ListEntry structure) * contains a link to the next entry and the previous entry. - * It is therefore possible to iterate over entries in the list in either + * It is therefore possible to iterate over entries in the list in either * direction. * * To create an empty list, create a new variable which is a pointer to @@ -35,12 +35,12 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * To add a value to a list, use @ref list_append or @ref list_prepend. * - * To remove a value from a list, use @ref list_remove_entry or + * To remove a value from a list, use @ref list_remove_entry or * @ref list_remove_data. * * To iterate over entries in a list, use @ref list_iterate to initialise * a @ref ListIterator structure, with @ref list_iter_next and - * @ref list_iter_has_more to retrieve each value in turn. + * @ref list_iter_has_more to retrieve each value in turn. * @ref list_iter_remove can be used to remove the current entry. * * To access an entry in the list by index, use @ref list_nth_entry or @@ -59,14 +59,14 @@ extern "C" { /** * Represents an entry in a doubly-linked list. The empty list is - * represented by a NULL pointer. To initialise a new doubly linked - * list, simply create a variable of this type + * represented by a NULL pointer. To initialise a new doubly linked + * list, simply create a variable of this type * containing a pointer to NULL. */ typedef struct _ListEntry ListEntry; -/** +/** * Structure used to iterate over a list. */ @@ -98,8 +98,8 @@ struct _ListIterator { * * @param value1 The first value to compare. * @param value2 The second value to compare. - * @return A negative value if value1 should be sorted before - * value2, a positive value if value1 should be sorted + * @return A negative value if value1 should be sorted before + * value2, a positive value if value1 should be sorted * after value2, zero if value1 and value2 are equal. */ @@ -147,17 +147,17 @@ ListEntry *list_prepend(ListEntry **list, ListValue data); ListEntry *list_append(ListEntry **list, ListValue data); -/** +/** * Retrieve the previous entry in a list. * * @param listentry Pointer to the list entry. - * @return The previous entry in the list, or NULL if this + * @return The previous entry in the list, or NULL if this * was the first entry in the list. */ ListEntry *list_prev(ListEntry *listentry); -/** +/** * Retrieve the next entry in a list. * * @param listentry Pointer to the list entry. @@ -176,7 +176,7 @@ ListEntry *list_next(ListEntry *listentry); ListValue list_data(ListEntry *listentry); -/** +/** * Retrieve the entry at a specified index in a list. * * @param list The list. @@ -186,18 +186,18 @@ ListValue list_data(ListEntry *listentry); ListEntry *list_nth_entry(ListEntry *list, unsigned int n); -/** +/** * Retrieve the value at a specified index in the list. * * @param list The list. * @param n The index into the list. - * @return The value at the specified index, or @ref LIST_NULL if + * @return The value at the specified index, or @ref LIST_NULL if * unsuccessful. */ ListValue list_nth_data(ListEntry *list, unsigned int n); -/** +/** * Find the length of a list. * * @param list The list. @@ -262,11 +262,11 @@ void list_sort(ListEntry **list, ListCompareFunc compare_func); * NULL if not found. */ -ListEntry *list_find_data(ListEntry *list, +ListEntry *list_find_data(ListEntry *list, ListEqualFunc callback, ListValue data); -/** +/** * Initialise a @ref ListIterator structure to iterate over a list. * * @param list A pointer to the list to iterate over. @@ -287,16 +287,16 @@ void list_iterate(ListEntry **list, ListIterator *iter); int list_iter_has_more(ListIterator *iterator); /** - * Using a list iterator, retrieve the next value from the list. + * Using a list iterator, retrieve the next value from the list. * * @param iterator The list iterator. - * @return The next value from the list, or @ref LIST_NULL if + * @return The next value from the list, or @ref LIST_NULL if * there are no more values in the list. */ - + ListValue list_iter_next(ListIterator *iterator); -/** +/** * Delete the current entry in the list (the value last returned from * list_iter_next) * diff --git a/src/queue.c b/src/queue.c index 4a94b6e..8372143 100644 --- a/src/queue.c +++ b/src/queue.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -52,7 +52,7 @@ Queue *queue_new(void) if (queue == NULL) { return NULL; } - + queue->head = NULL; queue->tail = NULL; @@ -62,7 +62,7 @@ Queue *queue_new(void) void queue_free(Queue *queue) { /* Empty the queue */ - + while (!queue_is_empty(queue)) { queue_pop_head(queue); } @@ -83,11 +83,11 @@ int queue_push_head(Queue *queue, QueueValue data) if (new_entry == NULL) { return 0; } - + new_entry->data = data; new_entry->prev = NULL; new_entry->next = queue->head; - + /* Insert into the queue */ if (queue->head == NULL) { @@ -146,8 +146,8 @@ QueueValue queue_pop_head(Queue *queue) /* Free back the queue entry structure */ free(entry); - - return result; + + return result; } QueueValue queue_peek_head(Queue *queue) @@ -170,11 +170,11 @@ int queue_push_tail(Queue *queue, QueueValue data) if (new_entry == NULL) { return 0; } - + new_entry->data = data; new_entry->prev = queue->tail; new_entry->next = NULL; - + /* Insert into the queue tail */ if (queue->tail == NULL) { @@ -234,8 +234,8 @@ QueueValue queue_pop_tail(Queue *queue) /* Free back the queue entry structure */ free(entry); - - return result; + + return result; } QueueValue queue_peek_tail(Queue *queue) diff --git a/src/queue.h b/src/queue.h index 5dbcad8..e9d7e21 100644 --- a/src/queue.h +++ b/src/queue.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -48,7 +48,7 @@ extern "C" { /** * A double-ended queue. */ - + typedef struct _Queue Queue; /** @@ -87,7 +87,7 @@ void queue_free(Queue *queue); * @param data The value to add. * @return Non-zero if the value was added successfully, or zero * if it was not possible to allocate the memory for the - * new entry. + * new entry. */ int queue_push_head(Queue *queue, QueueValue data); @@ -107,7 +107,7 @@ QueueValue queue_pop_head(Queue *queue); * the queue. * * @param queue The queue. - * @return Value at the head of the queue, or @ref QUEUE_NULL if the + * @return Value at the head of the queue, or @ref QUEUE_NULL if the * queue is empty. */ @@ -120,7 +120,7 @@ QueueValue queue_peek_head(Queue *queue); * @param data The value to add. * @return Non-zero if the value was added successfully, or zero * if it was not possible to allocate the memory for the - * new entry. + * new entry. */ int queue_push_tail(Queue *queue, QueueValue data); @@ -140,7 +140,7 @@ QueueValue queue_pop_tail(Queue *queue); * the queue. * * @param queue The queue. - * @return Value at the tail of the queue, or QUEUE_NULL if the + * @return Value at the tail of the queue, or QUEUE_NULL if the * queue is empty. */ diff --git a/src/rb-tree.h b/src/rb-tree.h index 1b23165..0e279c8 100644 --- a/src/rb-tree.h +++ b/src/rb-tree.h @@ -2,19 +2,19 @@ Copyright (c) 2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -22,11 +22,11 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @brief Balanced binary tree * - * The red-black tree structure is a balanced binary tree which stores + * The red-black tree structure is a balanced binary tree which stores * a collection of nodes (see @ref RBTreeNode). Each node has * a key and a value associated with it. The nodes are sorted * within the tree based on the order of their keys. Modifications - * to the tree are constructed such that the tree remains + * to the tree are constructed such that the tree remains * balanced at all times (there are always roughly equal numbers * of nodes on either side of the tree). * @@ -41,10 +41,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * @ref rb_tree_insert. To remove an entry from a * red-black tree, use @ref rb_tree_remove or @ref rb_tree_remove_node. * - * To search a red-black tree, use @ref rb_tree_lookup or + * To search a red-black tree, use @ref rb_tree_lookup or * @ref rb_tree_lookup_node. * - * Tree nodes can be queried using the + * Tree nodes can be queried using the * @ref rb_tree_node_left_child, * @ref rb_tree_node_right_child, * @ref rb_tree_node_parent, @@ -91,7 +91,7 @@ typedef void *RBTreeValue; * @see rb_tree_node_left_child * @see rb_tree_node_right_child * @see rb_tree_node_parent - * @see rb_tree_node_key + * @see rb_tree_node_key * @see rb_tree_node_value */ @@ -103,7 +103,7 @@ typedef struct _RBTreeNode RBTreeNode; * @param data1 The first key. * @param data2 The second key. * @return A negative number if data1 should be sorted - * before data2, a positive number if data2 should + * before data2, a positive number if data2 should * be sorted before data1, zero if the two keys * are equal. */ @@ -111,7 +111,7 @@ typedef struct _RBTreeNode RBTreeNode; typedef int (*RBTreeCompareFunc)(RBTreeValue data1, RBTreeValue data2); /** - * Each node in a red-black tree is either red or black. + * Each node in a red-black tree is either red or black. */ typedef enum { @@ -132,7 +132,7 @@ typedef enum { * Create a new red-black tree. * * @param compare_func Function to use when comparing keys in the tree. - * @return A new red-black tree, or NULL if it was not possible + * @return A new red-black tree, or NULL if it was not possible * to allocate the memory. */ @@ -140,7 +140,7 @@ RBTree *rb_tree_new(RBTreeCompareFunc compare_func); /** * Destroy a red-black tree. - * + * * @param tree The tree to destroy. */ @@ -195,14 +195,14 @@ RBTreeNode *rb_tree_lookup_node(RBTree *tree, RBTreeKey key); /** * Search a red-black tree for a value corresponding to a particular key. - * This uses the tree as a mapping. Note that this performs + * This uses the tree as a mapping. Note that this performs * identically to @ref rb_tree_lookup_node, except that the value * at the node is returned rather than the node itself. * * @param tree The red-black tree to search. * @param key The key to search for. - * @return The value associated with the given key, or - * RB_TREE_NULL if no entry with the given key is + * @return The value associated with the given key, or + * RB_TREE_NULL if no entry with the given key is * found. */ @@ -212,7 +212,7 @@ RBTreeValue rb_tree_lookup(RBTree *tree, RBTreeKey key); * Find the root node of a tree. * * @param tree The tree. - * @return The root node of the tree, or NULL if the tree is + * @return The root node of the tree, or NULL if the tree is * empty. */ @@ -227,7 +227,7 @@ RBTreeNode *rb_tree_root_node(RBTree *tree); RBTreeKey rb_tree_node_key(RBTreeNode *node); -/** +/** * Retrieve the value at a given tree node. * * @param node The tree node. @@ -251,7 +251,7 @@ RBTreeNode *rb_tree_node_child(RBTreeNode *node, RBTreeNodeSide side); * Find the parent node of a given tree node. * * @param node The tree node. - * @return The parent node of the tree node, or NULL if + * @return The parent node of the tree node, or NULL if * this is the root node. */ @@ -267,7 +267,7 @@ RBTreeNode *rb_tree_node_parent(RBTreeNode *node); int rb_tree_subtree_height(RBTreeNode *node); /** - * Convert the keys in a red-black tree into a C array. This allows + * Convert the keys in a red-black tree into a C array. This allows * the tree to be used as an ordered set. * * @param tree The tree. diff --git a/src/set.c b/src/set.c index 3e97882..45250bf 100644 --- a/src/set.c +++ b/src/set.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -61,7 +61,7 @@ static const unsigned int set_num_primes = sizeof(set_primes) / sizeof(int); static int set_allocate_table(Set *set) { - /* Determine the table size based on the current prime index. + /* Determine the table size based on the current prime index. * An attempt is made here to ensure sensible behavior if the * maximum prime is exceeded, but in practice other things are * likely to break long before that happens. */ @@ -79,11 +79,11 @@ static int set_allocate_table(Set *set) return set->table != NULL; } -static void set_free_entry(Set *set, SetEntry *entry) +static void set_free_entry(Set *set, SetEntry *entry) { - /* If there is a free function registered, call it to free the + /* If there is a free function registered, call it to free the * data for this entry first */ - + if (set->free_func != NULL) { set->free_func(entry->data); } @@ -104,15 +104,15 @@ Set *set_new(SetHashFunc hash_func, SetEqualFunc equal_func) if (new_set == NULL) { return NULL; } - + new_set->hash_func = hash_func; new_set->equal_func = equal_func; new_set->entries = 0; new_set->prime_index = 0; new_set->free_func = NULL; - + /* Allocate the table */ - + if (!set_allocate_table(new_set)) { free(new_set); return NULL; @@ -203,13 +203,13 @@ static int set_enlarge(Set *set) next = rover->next; /* Hook this entry into the new table */ - + index = set->hash_func(rover->data) % set->table_size; rover->next = set->table[index]; set->table[index] = rover; /* Advance to the next entry in the chain */ - + rover = next; } } @@ -241,7 +241,7 @@ int set_insert(Set *set, SetValue data) } } - /* Use the hash of the data to determine an index to insert into the + /* Use the hash of the data to determine an index to insert into the * table at. */ index = set->hash_func(data) % set->table_size; @@ -272,9 +272,9 @@ int set_insert(Set *set, SetValue data) if (newentry == NULL) { return 0; } - + newentry->data = data; - + /* Link into chain */ newentry->next = set->table[index]; @@ -423,7 +423,7 @@ Set *set_union(Set *set1, Set *set2) } /* Add all values from the first set */ - + set_iterate(set1, &iterator); while (set_iter_has_more(&iterator)) { @@ -437,14 +437,14 @@ Set *set_union(Set *set1, Set *set2) if (!set_insert(new_set, value)) { /* Failed to insert */ - + set_free(new_set); return NULL; } } - + /* Add all values from the second set */ - + set_iterate(set2, &iterator); while (set_iter_has_more(&iterator)) { @@ -453,7 +453,7 @@ Set *set_union(Set *set1, Set *set2) value = set_iter_next(&iterator); - /* Has this value been put into the new set already? + /* Has this value been put into the new set already? * If so, do not insert this again */ if (set_query(new_set, value) == 0) { @@ -492,12 +492,12 @@ Set *set_intersection(Set *set1, Set *set2) value = set_iter_next(&iterator); - /* Is this value in set 2 as well? If so, it should be + /* Is this value in set 2 as well? If so, it should be * in the new set. */ if (set_query(set2, value) != 0) { - /* Copy the value first before inserting, + /* Copy the value first before inserting, * if necessary */ if (!set_insert(new_set, value)) { diff --git a/src/set.h b/src/set.h index ffd08f8..3e41525 100644 --- a/src/set.h +++ b/src/set.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -23,10 +23,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @brief Set of values. * - * A set stores a collection of values. Each value can only exist once in + * A set stores a collection of values. Each value can only exist once in * the set. * - * To create a new set, use @ref set_new. To destroy a set, use + * To create a new set, use @ref set_new. To destroy a set, use * @ref set_free. * * To add a value to a set, use @ref set_insert. To remove a value @@ -37,7 +37,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * To query if a particular value is in a set, use @ref set_query. * * To iterate over all values in a set, use @ref set_iterate to initialise - * a @ref SetIterator structure, with @ref set_iter_next and + * a @ref SetIterator structure, with @ref set_iter_next and * @ref set_iter_has_more to read each value in turn. * * Two sets can be combined (union) using @ref set_union, while the @@ -94,13 +94,13 @@ struct _SetIterator { #define SET_NULL ((void *) 0) -/** +/** * Hash function. Generates a hash key for values to be stored in a set. */ typedef unsigned int (*SetHashFunc)(SetValue value); -/** +/** * Equality function. Compares two values to determine if they are * equivalent. */ @@ -120,7 +120,7 @@ typedef void (*SetFreeFunc)(SetValue value); * @param hash_func Hash function used on values in the set. * @param equal_func Compares two values in the set to determine * if they are equal. - * @return A new set, or NULL if it was not possible to + * @return A new set, or NULL if it was not possible to * allocate the memory for the set. */ @@ -135,7 +135,7 @@ Set *set_new(SetHashFunc hash_func, SetEqualFunc equal_func); void set_free(Set *set); /** - * Register a function to be called when values are removed from + * Register a function to be called when values are removed from * the set. * * @param set The set. @@ -151,7 +151,7 @@ void set_register_free_function(Set *set, SetFreeFunc free_func); * @param set The set. * @param data The value to add to the set. * @return Non-zero (true) if the value was added to the set, - * zero (false) if it already exists in the set, or + * zero (false) if it already exists in the set, or * if it was not possible to allocate memory for the * new entry. */ @@ -170,7 +170,7 @@ int set_insert(Set *set, SetValue data); int set_remove(Set *set, SetValue data); -/** +/** * Query if a particular value is in a set. * * @param set The set. @@ -202,11 +202,11 @@ unsigned int set_num_entries(Set *set); SetValue *set_to_array(Set *set); /** - * Perform a union of two sets. + * Perform a union of two sets. * * @param set1 The first set. * @param set2 The second set. - * @return A new set containing all values which are in the + * @return A new set containing all values which are in the * first or second sets, or NULL if it was not * possible to allocate memory for the new set. */ @@ -223,7 +223,7 @@ Set *set_union(Set *set1, Set *set2); * memory for the new set. */ -Set *set_intersection(Set *set1, Set *set2); +Set *set_intersection(Set *set1, Set *set2); /** * Initialise a @ref SetIterator structure to iterate over the values diff --git a/src/slist.c b/src/slist.c index 7fdac2d..028ca7d 100644 --- a/src/slist.c +++ b/src/slist.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -46,7 +46,7 @@ void slist_free(SListEntry *list) while (entry != NULL) { SListEntry *next; - + next = entry->next; free(entry); @@ -66,7 +66,7 @@ SListEntry *slist_prepend(SListEntry **list, SListValue data) if (newentry == NULL) { return NULL; } - + newentry->data = data; /* Hook into the list start */ @@ -89,10 +89,10 @@ SListEntry *slist_append(SListEntry **list, SListValue data) if (newentry == NULL) { return NULL; } - + newentry->data = data; newentry->next = NULL; - + /* Hooking into the list is different if the list is empty */ if (*list == NULL) { @@ -314,14 +314,14 @@ unsigned int slist_remove_data(SListEntry **list, SListEqualFunc callback, /* Function used internally for sorting. Returns the last entry in the * new sorted list */ -static SListEntry *slist_sort_internal(SListEntry **list, +static SListEntry *slist_sort_internal(SListEntry **list, SListCompareFunc compare_func) { SListEntry *pivot; SListEntry *rover; SListEntry *less_list, *more_list; SListEntry *less_list_end, *more_list_end; - + /* If there are less than two entries in this list, it is * already sorted */ @@ -385,8 +385,8 @@ static SListEntry *slist_sort_internal(SListEntry **list, pivot->next = more_list; - /* Work out what the last entry in the list is. If the more list was - * empty, the pivot was the last entry. Otherwise, the end of the + /* Work out what the last entry in the list is. If the more list was + * empty, the pivot was the last entry. Otherwise, the end of the * more list is the end of the total list. */ if (more_list == NULL) { @@ -414,7 +414,7 @@ SListEntry *slist_find_data(SListEntry *list, return rover; } } - + /* Not found */ return NULL; @@ -443,7 +443,7 @@ int slist_iter_has_more(SListIterator *iter) return *iter->prev_next != NULL; } else { - + /* The current entry has not been deleted. There * is a next entry if current->next is not NULL. */ @@ -482,13 +482,13 @@ SListValue slist_iter_next(SListIterator *iter) void slist_iter_remove(SListIterator *iter) { if (iter->current == NULL || iter->current != *iter->prev_next) { - - /* Either we have not yet read the first item, we have + + /* Either we have not yet read the first item, we have * reached the end of the list, or we have already removed * the current value. Either way, do nothing. */ - + } else { - + /* Remove the current entry */ *iter->prev_next = iter->current->next; diff --git a/src/slist.h b/src/slist.h index f135949..ee22811 100644 --- a/src/slist.h +++ b/src/slist.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -23,10 +23,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Singly-linked list. * - * A singly-linked list stores a collection of values. Each + * A singly-linked list stores a collection of values. Each * entry in the list (represented by a pointer to a @ref SListEntry - * structure) contains a link to the next entry. It is only - * possible to iterate over entries in a singly linked list in one + * structure) contains a link to the next entry. It is only + * possible to iterate over entries in a singly linked list in one * direction. * * To create a new singly-linked list, create a variable which is @@ -39,20 +39,20 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * To find the length of a list, use @ref slist_length. * - * To access a value in a list by its index in the list, use + * To access a value in a list by its index in the list, use * @ref slist_nth_data. * * To search a list for a value, use @ref slist_find_data. * * To sort a list into an order, use @ref slist_sort. * - * To find a particular entry in a list by its index, use + * To find a particular entry in a list by its index, use * @ref slist_nth_entry. * - * To iterate over each value in a list, use @ref slist_iterate to + * To iterate over each value in a list, use @ref slist_iterate to * initialise a @ref SListIterator structure, with @ref slist_iter_next * and @ref slist_iter_has_more to retrieve each value in turn. - * @ref slist_iter_remove can be used to efficiently remove the + * @ref slist_iter_remove can be used to efficiently remove the * current entry from the list. * * Given a particular entry in a list (@ref SListEntry): @@ -72,8 +72,8 @@ extern "C" { /** * Represents an entry in a singly-linked list. The empty list is - * represented by a NULL pointer. To initialise a new singly linked - * list, simply create a variable of this type + * represented by a NULL pointer. To initialise a new singly linked + * list, simply create a variable of this type * containing a pointer to NULL. */ @@ -109,8 +109,8 @@ struct _SListIterator { /** * Callback function used to compare values in a list when sorting. * - * @return A negative value if value1 should be sorted before value2, - * a positive value if value1 should be sorted after value2, + * @return A negative value if value1 should be sorted before value2, + * a positive value if value1 should be sorted after value2, * zero if value1 and value2 are equal. */ @@ -156,7 +156,7 @@ SListEntry *slist_prepend(SListEntry **list, SListValue data); SListEntry *slist_append(SListEntry **list, SListValue data); -/** +/** * Retrieve the next entry in a list. * * @param listentry Pointer to the list entry. @@ -174,7 +174,7 @@ SListEntry *slist_next(SListEntry *listentry); SListValue slist_data(SListEntry *listentry); -/** +/** * Retrieve the entry at a specified index in a list. * * @param list The list. @@ -184,7 +184,7 @@ SListValue slist_data(SListEntry *listentry); SListEntry *slist_nth_entry(SListEntry *list, unsigned int n); -/** +/** * Retrieve the value stored at a specified index in the list. * * @param list The list. @@ -195,7 +195,7 @@ SListEntry *slist_nth_entry(SListEntry *list, unsigned int n); SListValue slist_nth_data(SListEntry *list, unsigned int n); -/** +/** * Find the length of a list. * * @param list The list. @@ -209,8 +209,8 @@ unsigned int slist_length(SListEntry *list); * * @param list The list. * @return A newly-allocated C array containing all values in the - * list, or NULL if it was not possible to allocate the - * memory for the array. The length of the array is + * list, or NULL if it was not possible to allocate the + * memory for the array. The length of the array is * equal to the length of the list (see @ref slist_length). */ @@ -262,11 +262,11 @@ void slist_sort(SListEntry **list, SListCompareFunc compare_func); * NULL if not found. */ -SListEntry *slist_find_data(SListEntry *list, +SListEntry *slist_find_data(SListEntry *list, SListEqualFunc callback, SListValue data); -/** +/** * Initialise a @ref SListIterator structure to iterate over a list. * * @param list Pointer to the list to iterate over. @@ -288,16 +288,16 @@ void slist_iterate(SListEntry **list, SListIterator *iter); int slist_iter_has_more(SListIterator *iterator); /** - * Using a list iterator, retrieve the next value from the list. + * Using a list iterator, retrieve the next value from the list. * * @param iterator The list iterator. - * @return The next value from the list, or SLIST_NULL if + * @return The next value from the list, or SLIST_NULL if * there are no more values in the list. */ - + SListValue slist_iter_next(SListIterator *iterator); -/** +/** * Delete the current entry in the list (the value last returned from * @ref slist_iter_next) * diff --git a/src/trie.c b/src/trie.c index 2aa2b65..d1e4dfa 100644 --- a/src/trie.c +++ b/src/trie.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -52,7 +52,7 @@ Trie *trie_new(void) if (new_trie == NULL) { return NULL; } - + new_trie->root_node = NULL; return new_trie; @@ -88,7 +88,7 @@ void trie_free(Trie *trie) trie_free_list_push(&free_list, trie->root_node); } - /* Go through the free list, freeing nodes. We add new nodes as + /* Go through the free list, freeing nodes. We add new nodes as * we encounter them; in this way, all the nodes are freed * non-recursively. */ @@ -180,7 +180,7 @@ static void trie_insert_rollback(Trie *trie, unsigned char *key) TrieNode **next_prev_ptr; unsigned char *p; - /* Follow the chain along. We know that we will never reach the + /* Follow the chain along. We know that we will never reach the * end of the string because trie_insert never got that far. As a * result, it is not necessary to check for the end of string * delimiter (NUL) */ @@ -197,7 +197,7 @@ static void trie_insert_rollback(Trie *trie, unsigned char *key) next_node = *next_prev_ptr; ++p; - /* Decrease the use count and free the node if it + /* Decrease the use count and free the node if it * reaches zero. */ --node->use_count; @@ -231,12 +231,12 @@ int trie_insert(Trie *trie, char *key, TrieValue value) if (value == TRIE_NULL) { return 0; } - + /* Search to see if this is already in the tree */ node = trie_find_end(trie, key); - /* Already in the tree? If so, replace the existing value and + /* Already in the tree? If so, replace the existing value and * return success. */ if (node != NULL && node->data != TRIE_NULL) { @@ -261,12 +261,12 @@ int trie_insert(Trie *trie, char *key, TrieValue value) node = (TrieNode *) calloc(1, sizeof(TrieNode)); if (node == NULL) { - + /* Allocation failed. Go back and undo * what we have done so far. */ trie_insert_rollback(trie, (unsigned char *) key); - + return 0; } @@ -318,12 +318,12 @@ int trie_insert_binary(Trie *trie, unsigned char *key, int key_length, if (value == TRIE_NULL) { return 0; } - + /* Search to see if this is already in the tree */ node = trie_find_end_binary(trie, key, key_length); - /* Already in the tree? If so, replace the existing value and + /* Already in the tree? If so, replace the existing value and * return success. */ if (node != NULL && node->data != TRIE_NULL) { @@ -348,7 +348,7 @@ int trie_insert_binary(Trie *trie, unsigned char *key, int key_length, node = (TrieNode *) calloc(1, sizeof(TrieNode)); if (node == NULL) { - + /* Allocation failed. Go back and undo * what we have done so far. */ @@ -398,7 +398,7 @@ int trie_remove_binary(Trie *trie, unsigned char *key, int key_length) TrieNode *next; TrieNode **last_next_ptr; int p, c; - + /* Find the end node and remove the value */ node = trie_find_end_binary(trie, key, key_length); @@ -440,7 +440,7 @@ int trie_remove_binary(Trie *trie, unsigned char *key, int key_length) last_next_ptr = NULL; } } - + /* Go to the next character or finish */ if (p == key_length) { break; @@ -455,7 +455,7 @@ int trie_remove_binary(Trie *trie, unsigned char *key, int key_length) if (last_next_ptr != NULL) { last_next_ptr = &node->next[c]; } - + /* Jump to the next node */ node = next; @@ -473,7 +473,7 @@ int trie_remove(Trie *trie, char *key) TrieNode **last_next_ptr; char *p; int c; - + /* Find the end node and remove the value */ node = trie_find_end(trie, key); @@ -494,7 +494,7 @@ int trie_remove(Trie *trie, char *key) for (;;) { /* Find the next node */ - + c = (unsigned char) *p; next = node->next[c]; @@ -516,7 +516,7 @@ int trie_remove(Trie *trie, char *key) last_next_ptr = NULL; } } - + /* Go to the next character or finish */ if (c == '\0') { @@ -532,7 +532,7 @@ int trie_remove(Trie *trie, char *key) if (last_next_ptr != NULL) { last_next_ptr = &node->next[c]; } - + /* Jump to the next node */ node = next; diff --git a/src/trie.h b/src/trie.h index 22ebe97..e51c775 100644 --- a/src/trie.h +++ b/src/trie.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -30,7 +30,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * use @ref trie_free. * * To insert a value into a trie, use @ref trie_insert. To remove a value - * from a trie, use @ref trie_remove. + * from a trie, use @ref trie_remove. * * To look up a value from its key, use @ref trie_lookup. * @@ -72,7 +72,7 @@ typedef void *TrieValue; Trie *trie_new(void); -/** +/** * Destroy a trie. * * @param trie The trie to destroy. @@ -88,7 +88,7 @@ void trie_free(Trie *trie); * @param key The key to access the new value. * @param value The value. * @return Non-zero if the value was inserted successfully, - * or zero if it was not possible to allocate + * or zero if it was not possible to allocate * memory for the new entry. */ @@ -103,7 +103,7 @@ int trie_insert(Trie *trie, char *key, TrieValue value); * @param key_length The key length in bytes. * @param value The value. * @return Non-zero if the value was inserted successfully, - * or zero if it was not possible to allocate + * or zero if it was not possible to allocate * memory for the new entry. */ @@ -112,12 +112,12 @@ int trie_insert_binary(Trie *trie, unsigned char *key, /** * Look up a value from its key in a trie. - * The key is a NUL-terminated string; for binary strings, use + * The key is a NUL-terminated string; for binary strings, use * @ref trie_lookup_binary. * * @param trie The trie. * @param key The key. - * @return The value associated with the key, or + * @return The value associated with the key, or * @ref TRIE_NULL if not found in the trie. */ @@ -131,7 +131,7 @@ TrieValue trie_lookup(Trie *trie, char *key); * @param trie The trie. * @param key The key. * @param key_length The key length in bytes. - * @return The value associated with the key, or + * @return The value associated with the key, or * @ref TRIE_NULL if not found in the trie. */ @@ -139,7 +139,7 @@ TrieValue trie_lookup_binary(Trie *trie, unsigned char *key, int key_length); /** * Remove an entry from a trie. - * The key is a NUL-terminated string; for binary strings, use + * The key is a NUL-terminated string; for binary strings, use * @ref trie_lookup_binary. * * @param trie The trie. @@ -164,7 +164,7 @@ int trie_remove(Trie *trie, char *key); int trie_remove_binary(Trie *trie, unsigned char *key, int key_length); -/** +/** * Find the number of entries in a trie. * * @param trie The trie. diff --git a/test/alloc-testing.c b/test/alloc-testing.c index 87a01d4..7398f24 100644 --- a/test/alloc-testing.c +++ b/test/alloc-testing.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -33,7 +33,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define ALLOC_TEST_MAGIC 0x72ec82d2 /* This value is written to memory after it is freshly allocated, to ensure - * that code under test does not rely on memory being initialised by + * that code under test does not rely on memory being initialised by * malloc(). */ #define MALLOC_PATTERN 0xBAADF00D @@ -76,7 +76,7 @@ static BlockHeader *alloc_test_get_header(void *ptr) result = ((BlockHeader *) ptr) - 1; assert(result->magic_number == ALLOC_TEST_MAGIC); - + return result; } @@ -122,7 +122,7 @@ void *alloc_test_malloc(size_t bytes) header->magic_number = ALLOC_TEST_MAGIC; header->bytes = bytes; - + /* Fill memory with MALLOC_PATTERN, to ensure that code under test * does not rely on memory being initialised to zero. */ @@ -163,7 +163,7 @@ void alloc_test_free(void *ptr) block_size = header->bytes; assert(allocated_bytes >= block_size); - /* Trash the allocated block to foil any code that relies on memory + /* Trash the allocated block to foil any code that relies on memory * that has been freed. */ alloc_test_overwrite(ptr, header->bytes, FREE_PATTERN); @@ -238,7 +238,7 @@ void *alloc_test_calloc(size_t nmemb, size_t bytes) char *alloc_test_strdup(const char *string) { char *result; - + result = alloc_test_malloc(strlen(string) + 1); if (result == NULL) { diff --git a/test/alloc-testing.h b/test/alloc-testing.h index 1d3ffef..e60d8e5 100644 --- a/test/alloc-testing.h +++ b/test/alloc-testing.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -23,10 +23,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @brief Memory allocation testing framework. * - * This file uses the preprocessor to redefine the standard C dynamic memory - * allocation functions for testing purposes. This allows checking that - * code under test correctly frees back all memory allocated, as well as - * the ability to impose artificial limits on allocation, to test that + * This file uses the preprocessor to redefine the standard C dynamic memory + * allocation functions for testing purposes. This allows checking that + * code under test correctly frees back all memory allocated, as well as + * the ability to impose artificial limits on allocation, to test that * code correctly handles out-of-memory scenarios. */ @@ -80,7 +80,7 @@ void alloc_test_free(void *ptr); void *alloc_test_realloc(void *ptr, size_t bytes); /** - * Allocate a block of memory for an array of structures, initialising + * Allocate a block of memory for an array of structures, initialising * the contents to zero. * * @param nmemb Number of structures to allocate for. @@ -104,13 +104,13 @@ void *alloc_test_calloc(size_t nmemb, size_t bytes); char *alloc_test_strdup(const char *string); /** - * Set an artificial limit on the amount of memory that can be - * allocated. + * Set an artificial limit on the amount of memory that can be + * allocated. * * @param alloc_count Number of allocations that are possible after - * this call. For example, if this has a value - * of 3, malloc() can be called successfully - * three times, but all allocation attempts + * this call. For example, if this has a value + * of 3, malloc() can be called successfully + * three times, but all allocation attempts * after this will fail. If this has a negative * value, the allocation limit is disabled. */ diff --git a/test/framework.c b/test/framework.c index 469f388..1684e13 100644 --- a/test/framework.c +++ b/test/framework.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ diff --git a/test/framework.h b/test/framework.h index bfc92b2..f7fc162 100644 --- a/test/framework.h +++ b/test/framework.h @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ diff --git a/test/test-alloc-testing.c b/test/test-alloc-testing.c index bfdd039..19ee5f9 100644 --- a/test/test-alloc-testing.c +++ b/test/test-alloc-testing.c @@ -3,19 +3,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ diff --git a/test/test-arraylist.c b/test/test-arraylist.c index 84dba36..e4d5fb1 100644 --- a/test/test-arraylist.c +++ b/test/test-arraylist.c @@ -2,19 +2,19 @@ Copyright (c) 2005-2008, Simon Howard -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice appear -in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ @@ -319,7 +319,7 @@ void test_arraylist_index_of(void) int i; int index; int val; - + /* Generate an arraylist containing the entries in the array */ num_entries = sizeof(entries) / sizeof(int); @@ -332,9 +332,9 @@ void test_arraylist_index_of(void) /* Check all values get found correctly */ for (i=0; i counter); counter = *key; - + right_height = validate_subtree(right_node); - /* Check that the returned height value matches the + /* Check that the returned height value matches the * result of avl_tree_subtree_height(). */ assert(avl_tree_subtree_height(left_node) == left_height); @@ -167,7 +167,7 @@ AVLTree *create_tree(void) test_array[i] = i; avl_tree_insert(tree, &test_array[i], &test_array[i]); } - + return tree; } @@ -200,7 +200,7 @@ void test_avl_tree_insert_lookup(void) unsigned int i; int *value; - /* Create a tree containing some values. Validate the + /* Create a tree containing some values. Validate the * tree is consistent at all stages. */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); @@ -244,7 +244,7 @@ void test_avl_tree_child(void) int *p; int i; - /* Create a tree containing some values. Validate the + /* Create a tree containing some values. Validate the * tree is consistent at all stages. */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); @@ -303,7 +303,7 @@ void test_out_of_memory(void) void test_avl_tree_free(void) { AVLTree *tree; - + /* Try freeing an empty tree */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); @@ -365,7 +365,7 @@ void test_avl_tree_remove(void) expected_entries = NUM_TEST_VALUES; - /* This looping arrangement causes nodes to be removed in a + /* This looping arrangement causes nodes to be removed in a * randomish fashion from all over the tree. */ for (x=0; x<10; ++x) { @@ -398,13 +398,13 @@ void test_avl_tree_to_array(void) int **array; /* Add all entries to the tree */ - + tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i Date: Sun, 26 Apr 2015 00:26:35 -0400 Subject: [PATCH 132/250] Reflow code to keep 80 column limit. --- src/arraylist.c | 16 +++++++++------- src/arraylist.h | 3 ++- src/avl-tree.h | 3 ++- src/binary-heap.c | 11 +++++++---- src/hash-table.c | 9 ++++++--- src/queue.c | 8 ++++---- src/set.c | 3 ++- src/slist.c | 4 ++-- src/trie.c | 3 ++- test/alloc-testing.c | 3 ++- test/test-avl-tree.c | 3 ++- test/test-binary-heap.c | 4 +++- test/test-binomial-heap.c | 3 ++- test/test-hash-functions.c | 3 ++- test/test-hash-table.c | 3 ++- test/test-trie.c | 6 ++++-- 16 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/arraylist.c b/src/arraylist.c index 0cb7f17..e4ce449 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -153,7 +153,8 @@ void arraylist_remove_range(ArrayList *arraylist, unsigned int index, memmove(&arraylist->data[index], &arraylist->data[index + length], - (arraylist->length - (index + length)) * sizeof(ArrayListValue)); + (arraylist->length - (index + length)) + * sizeof(ArrayListValue)); /* Decrease the counter */ @@ -223,9 +224,9 @@ static void arraylist_sort_internal(ArrayListValue *list_data, if (compare_func(list_data[i], pivot) < 0) { - /* This should be in list 1. Therefore it is in the wrong - * position. Swap the data immediately following the last - * item in list 1 with this data. */ + /* This should be in list 1. Therefore it is in the + * wrong position. Swap the data immediately following + * the last item in list 1 with this data. */ tmp = list_data[i]; list_data[i] = list_data[list1_length]; @@ -234,8 +235,8 @@ static void arraylist_sort_internal(ArrayListValue *list_data, ++list1_length; } else { - /* This should be in list 2. This is already in the right - * position. */ + /* This should be in list 2. This is already in the + * right position. */ } } @@ -266,6 +267,7 @@ void arraylist_sort(ArrayList *arraylist, ArrayListCompareFunc compare_func) { /* Perform the recursive sort */ - arraylist_sort_internal(arraylist->data, arraylist->length, compare_func); + arraylist_sort_internal(arraylist->data, arraylist->length, + compare_func); } diff --git a/src/arraylist.h b/src/arraylist.h index 9042c01..725b570 100644 --- a/src/arraylist.h +++ b/src/arraylist.h @@ -83,7 +83,8 @@ struct _ArrayList { * @return Non-zero if the values are equal, zero if they are not equal. */ -typedef int (*ArrayListEqualFunc)(ArrayListValue value1, ArrayListValue value2); +typedef int (*ArrayListEqualFunc)(ArrayListValue value1, + ArrayListValue value2); /** * Compare two values in an arraylist. Used by @ref arraylist_sort diff --git a/src/avl-tree.h b/src/avl-tree.h index 4ae3dcd..0634258 100644 --- a/src/avl-tree.h +++ b/src/avl-tree.h @@ -147,7 +147,8 @@ void avl_tree_free(AVLTree *tree); * to allocate the new memory. */ -AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, AVLTreeValue value); +AVLTreeNode *avl_tree_insert(AVLTree *tree, AVLTreeKey key, + AVLTreeValue value); /** * Remove a node from a tree. diff --git a/src/binary-heap.c b/src/binary-heap.c index 70f1fd2..40198fb 100644 --- a/src/binary-heap.c +++ b/src/binary-heap.c @@ -36,7 +36,8 @@ struct _BinaryHeap { BinaryHeapCompareFunc compare_func; }; -static int binary_heap_cmp(BinaryHeap *heap, BinaryHeapValue data1, BinaryHeapValue data2) +static int binary_heap_cmp(BinaryHeap *heap, BinaryHeapValue data1, + BinaryHeapValue data2) { if (heap->heap_type == BINARY_HEAP_TYPE_MIN) { return heap->compare_func(data1, data2); @@ -93,7 +94,8 @@ int binary_heap_insert(BinaryHeap *heap, BinaryHeapValue value) /* Double the table size */ new_size = heap->alloced_size * 2; - new_values = realloc(heap->values, sizeof(BinaryHeapValue) * new_size); + new_values = realloc(heap->values, + sizeof(BinaryHeapValue) * new_size); if (new_values == NULL) { return 0; @@ -206,8 +208,9 @@ BinaryHeapValue binary_heap_pop(BinaryHeap *heap) next_index = child2; } else { - /* Node is less than both its children. The heap condition - * is satisfied. We can stop percolating down. */ + /* Node is less than both its children. The heap + * condition is satisfied. * We can stop percolating + * down. */ heap->values[index] = new_value; break; diff --git a/src/hash-table.c b/src/hash-table.c index 90ccfb5..3e7480e 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -220,7 +220,8 @@ static int hash_table_enlarge(HashTable *hash_table) /* Find the index into the new table */ - index = hash_table->hash_func(rover->key) % hash_table->table_size; + index = hash_table->hash_func(rover->key) + % hash_table->table_size; /* Link this entry into the chain */ @@ -240,7 +241,8 @@ static int hash_table_enlarge(HashTable *hash_table) return 1; } -int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue value) +int hash_table_insert(HashTable *hash_table, HashTableKey key, + HashTableValue value) { HashTableEntry *rover; HashTableEntry *newentry; @@ -481,7 +483,8 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) /* Is there anything in this chain? */ if (hash_table->table[chain] != NULL) { - iterator->next_entry = hash_table->table[chain]; + iterator->next_entry = + hash_table->table[chain]; break; } diff --git a/src/queue.c b/src/queue.c index 8372143..4997edd 100644 --- a/src/queue.c +++ b/src/queue.c @@ -92,8 +92,8 @@ int queue_push_head(Queue *queue, QueueValue data) if (queue->head == NULL) { - /* If the queue was previously empty, both the head and tail must - * be pointed at the new entry */ + /* If the queue was previously empty, both the head and + * tail must be pointed at the new entry */ queue->head = new_entry; queue->tail = new_entry; @@ -179,8 +179,8 @@ int queue_push_tail(Queue *queue, QueueValue data) if (queue->tail == NULL) { - /* If the queue was previously empty, both the head and tail must - * be pointed at the new entry */ + /* If the queue was previously empty, both the head and + * tail must be pointed at the new entry */ queue->head = new_entry; queue->tail = new_entry; diff --git a/src/set.c b/src/set.c index 45250bf..35b5237 100644 --- a/src/set.c +++ b/src/set.c @@ -234,7 +234,8 @@ int set_insert(Set *set, SetValue data) if ((set->entries * 3) / set->table_size > 0) { - /* The table is more than 1/3 full and must be increased in size */ + /* The table is more than 1/3 full and must be increased + * in size */ if (!set_enlarge(set)) { return 0; diff --git a/src/slist.c b/src/slist.c index 028ca7d..fa81d3a 100644 --- a/src/slist.c +++ b/src/slist.c @@ -254,8 +254,8 @@ int slist_remove_entry(SListEntry **list, SListEntry *entry) } else { - /* rover->next now points at entry, so rover is the preceding - * entry. Unlink the entry from the list. */ + /* rover->next now points at entry, so rover is the + * preceding entry. Unlink the entry from the list. */ rover->next = entry->next; } diff --git a/src/trie.c b/src/trie.c index d1e4dfa..ee06bf6 100644 --- a/src/trie.c +++ b/src/trie.c @@ -265,7 +265,8 @@ int trie_insert(Trie *trie, char *key, TrieValue value) /* Allocation failed. Go back and undo * what we have done so far. */ - trie_insert_rollback(trie, (unsigned char *) key); + trie_insert_rollback(trie, + (unsigned char *) key); return 0; } diff --git a/test/alloc-testing.c b/test/alloc-testing.c index 7398f24..3999d8c 100644 --- a/test/alloc-testing.c +++ b/test/alloc-testing.c @@ -82,7 +82,8 @@ static BlockHeader *alloc_test_get_header(void *ptr) /* Overwrite a block of memory with a repeated pattern. */ -static void alloc_test_overwrite(void *ptr, size_t length, unsigned int pattern) +static void alloc_test_overwrite(void *ptr, size_t length, + unsigned int pattern) { unsigned char *byte_ptr; int pattern_seq; diff --git a/test/test-avl-tree.c b/test/test-avl-tree.c index 04de6c8..f0f7102 100644 --- a/test/test-avl-tree.c +++ b/test/test-avl-tree.c @@ -127,7 +127,8 @@ int validate_subtree(AVLTreeNode *node) /* Check this node is balanced */ - assert(left_height - right_height < 2 && right_height - left_height < 2); + assert(left_height - right_height < 2 && + right_height - left_height < 2); /* Calculate the height of this node */ diff --git a/test/test-binary-heap.c b/test/test-binary-heap.c index 3c5f7bf..c840b31 100644 --- a/test/test-binary-heap.c +++ b/test/test-binary-heap.c @@ -136,7 +136,9 @@ void test_out_of_memory(void) { BinaryHeap *heap; int *value; - int values[] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + int values[] = { + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + }; int i; /* Allocate a heap and fill to the default limit */ diff --git a/test/test-binomial-heap.c b/test/test-binomial-heap.c index 1ff9de6..9a07405 100644 --- a/test/test-binomial-heap.c +++ b/test/test-binomial-heap.c @@ -149,7 +149,8 @@ static BinomialHeap *generate_heap(void) for (i=0; i Date: Sun, 26 Apr 2015 05:27:37 +0000 Subject: [PATCH 133/250] Tweak configure.ac to work with older automake versions. Use AC_CONFIG_MACRO_DIR instead of AC_CONFIG_MACRO_DIRS, and add the AM_PROG_CC_C_O macro as well. --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index efcc830..6557ed9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,12 @@ AC_INIT(C Algorithms, 1.2.0, fraggle@removethisbit.gmail.com, c-algorithms) AC_CONFIG_AUX_DIR(autotools) AC_CONFIG_SRCDIR([src/arraylist.c]) -AC_CONFIG_MACRO_DIRS([m4]) +AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE AC_PROG_CC +AM_PROG_CC_C_O AC_PROG_CXX AC_PROG_LIBTOOL AC_PROG_INSTALL From d06c4f65a22757cd624344f8d40cf739020b6e57 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 26 Apr 2015 05:29:17 +0000 Subject: [PATCH 134/250] Add Travis build file. --- .travis.yml | 8 ++++++++ src/gencov | 2 ++ 2 files changed, 10 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..0fb80a1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: c + +compiler: + - clang + - gcc + +script: ./autogen.sh --enable-coverage && make && make check && bash src/gencov + diff --git a/src/gencov b/src/gencov index 9ef02df..5eb721f 100755 --- a/src/gencov +++ b/src/gencov @@ -3,6 +3,8 @@ # Simple shell script to generate a coverage report. # +cd $(dirname $0) + for d in *.c; do obj=`echo $d | sed "s/^/libcalgtest_a-/" | sed "s/.c$/.o/"` From 6eebb979bf33df98d79f690c92400eee7b4d902b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 26 Apr 2015 05:37:59 +0000 Subject: [PATCH 135/250] Remove clang from Travis config. Coverage analysis currently fails with the Clang build, so just build with gcc for now. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0fb80a1..b69afa8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: c compiler: - - clang - gcc script: ./autogen.sh --enable-coverage && make && make check && bash src/gencov From b7301585b4978adbf26292e4d42a4741f7b50bb7 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 26 Apr 2015 05:51:15 +0000 Subject: [PATCH 136/250] Add a .gitignore file. I think the Subversion repository had the svn:ignore property correctly set but this wasn't preserved in the Git conversion. --- .gitignore | 25 +++++++++++++++++++++++++ test/.gitignore | 16 ++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 .gitignore create mode 100644 test/.gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cf53d92 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +.deps +.gitignore +.libs +INSTALL +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +autotools +config.h +config.h.in +config.log +config.status +configure +libtool +m4 +stamp-h1 +*.a +*.gcda +*.gcno +*.gcov +*.la +*.lo +*.o +*.pc diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..b93661d --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,16 @@ +test-alloc-testing +test-arraylist +test-avl-tree +test-binary-heap +test-binomial-heap +test-bloom-filter +test-compare-functions +test-cpp +test-hash-functions +test-hash-table +test-list +test-queue +test-rb-tree +test-set +test-slist +test-trie From bbfd4d730397a9ed92072b7b95ddbde53f09ae05 Mon Sep 17 00:00:00 2001 From: losintikfos Date: Tue, 7 Jul 2015 09:57:51 +0100 Subject: [PATCH 137/250] Extended hash_table_iter_next to return either KEY, VALUE or KEY_VALUE pair depending on flag passed as argument. --- src/hash-table.c | 21 +++++++++++++++++++-- src/hash-table.h | 10 +++++++++- test/test-hash-table.c | 33 +++++++++++++++++++++++++++++---- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index 3e7480e..7071b37 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -440,11 +440,12 @@ int hash_table_iter_has_more(HashTableIterator *iterator) return iterator->next_entry != NULL; } -HashTableValue hash_table_iter_next(HashTableIterator *iterator) +HashTableValue hash_table_iter_next(HashTableIterator *iterator, int flag) { HashTableEntry *current_entry; HashTable *hash_table; HashTableValue result; + void* res[2]; unsigned int chain; hash_table = iterator->hash_table; @@ -458,7 +459,23 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) /* Result is immediately available */ current_entry = iterator->next_entry; - result = current_entry->value; + + switch (flag) { + case VALUE: + result = current_entry->value; + break; + case KEY: + result = current_entry->key; + break; + case KEY_VALUE: + res[0] = current_entry->key; + res[1] = current_entry->value; + result = res; + break; + default: + result = current_entry->value; + break; + } /* Find the next entry */ diff --git a/src/hash-table.h b/src/hash-table.h index b578500..fbf9920 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -45,6 +45,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef ALGORITHM_HASH_TABLE_H #define ALGORITHM_HASH_TABLE_H +#define KEY 1 +#define VALUE 2 +#define KEY_VALUE 3 + #ifdef __cplusplus extern "C" { #endif @@ -238,12 +242,16 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * Using a hash table iterator, retrieve the next key. * * @param iterator The hash table iterator. + * @param flag Flag to determine whether the return value should + * either be the Key, Value or Both KeyValue held in + * array[2] where array[0] is Key and array[1] is value. + * * @return The next key from the hash table, or * @ref HASH_TABLE_NULL if there are no more * keys to iterate over. */ -HashTableValue hash_table_iter_next(HashTableIterator *iterator); +HashTableValue hash_table_iter_next(HashTableIterator *iterator, int flag); #ifdef __cplusplus } diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 6ba7a9d..1ec6ee5 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -194,7 +194,7 @@ void test_hash_table_iterating(void) hash_table_iterate(hash_table, &iterator); while (hash_table_iter_has_more(&iterator)) { - hash_table_iter_next(&iterator); + hash_table_iter_next(&iterator, VALUE); ++count; } @@ -202,8 +202,8 @@ void test_hash_table_iterating(void) assert(count == NUM_TEST_VALUES); /* Test iter_next after iteration has completed. */ - - assert(hash_table_iter_next(&iterator) == HASH_TABLE_NULL); + assert(hash_table_iter_next(&iterator, KEY) == HASH_TABLE_NULL); + assert(hash_table_iter_next(&iterator, VALUE) == HASH_TABLE_NULL); hash_table_free(hash_table); @@ -245,7 +245,7 @@ void test_hash_table_iterating_remove(void) /* Read the next value */ - val = hash_table_iter_next(&iterator); + val = hash_table_iter_next(&iterator, VALUE); /* Remove every hundredth entry */ @@ -428,6 +428,31 @@ void test_hash_table_out_of_memory(void) hash_table_free(hash_table); } +void test_hash_iterator_returning_KeyValue_pair(){ + + HashTable *hash_table; + HashTableIterator iterator; + int** kv_pair; + + hash_table = hash_table_new(int_hash, int_equal); + + /* Add some values */ + + hash_table_insert(hash_table, &value1, &value1); + hash_table_insert(hash_table, &value2, &value2); + + hash_table_iterate(hash_table, &iterator); + + while (hash_table_iter_has_more(&iterator)) { + + // Retrieve both Key and Value + kv_pair = (int**) hash_table_iter_next(&iterator, KEY_VALUE); + + assert(*((int*)kv_pair[0]) == *((int*)kv_pair[1])); + } + hash_table_free(hash_table); +} + static UnitTestFunction tests[] = { test_hash_table_new_free, test_hash_table_insert_lookup, From 7c60d3e78f6d002a5f0dbe85728ba330cde34689 Mon Sep 17 00:00:00 2001 From: losintikfos Date: Tue, 7 Jul 2015 09:57:51 +0100 Subject: [PATCH 138/250] Extended hash_table_iter_next to return either KEY, VALUE or KEY_VALUE pair depending on flag passed as argument. --- src/hash-table.c | 21 +++++++++++++++++++-- src/hash-table.h | 10 +++++++++- test/test-hash-table.c | 34 ++++++++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index 3e7480e..7071b37 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -440,11 +440,12 @@ int hash_table_iter_has_more(HashTableIterator *iterator) return iterator->next_entry != NULL; } -HashTableValue hash_table_iter_next(HashTableIterator *iterator) +HashTableValue hash_table_iter_next(HashTableIterator *iterator, int flag) { HashTableEntry *current_entry; HashTable *hash_table; HashTableValue result; + void* res[2]; unsigned int chain; hash_table = iterator->hash_table; @@ -458,7 +459,23 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) /* Result is immediately available */ current_entry = iterator->next_entry; - result = current_entry->value; + + switch (flag) { + case VALUE: + result = current_entry->value; + break; + case KEY: + result = current_entry->key; + break; + case KEY_VALUE: + res[0] = current_entry->key; + res[1] = current_entry->value; + result = res; + break; + default: + result = current_entry->value; + break; + } /* Find the next entry */ diff --git a/src/hash-table.h b/src/hash-table.h index b578500..fbf9920 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -45,6 +45,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef ALGORITHM_HASH_TABLE_H #define ALGORITHM_HASH_TABLE_H +#define KEY 1 +#define VALUE 2 +#define KEY_VALUE 3 + #ifdef __cplusplus extern "C" { #endif @@ -238,12 +242,16 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * Using a hash table iterator, retrieve the next key. * * @param iterator The hash table iterator. + * @param flag Flag to determine whether the return value should + * either be the Key, Value or Both KeyValue held in + * array[2] where array[0] is Key and array[1] is value. + * * @return The next key from the hash table, or * @ref HASH_TABLE_NULL if there are no more * keys to iterate over. */ -HashTableValue hash_table_iter_next(HashTableIterator *iterator); +HashTableValue hash_table_iter_next(HashTableIterator *iterator, int flag); #ifdef __cplusplus } diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 6ba7a9d..cdf03c5 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -194,7 +194,7 @@ void test_hash_table_iterating(void) hash_table_iterate(hash_table, &iterator); while (hash_table_iter_has_more(&iterator)) { - hash_table_iter_next(&iterator); + hash_table_iter_next(&iterator, VALUE); ++count; } @@ -202,8 +202,8 @@ void test_hash_table_iterating(void) assert(count == NUM_TEST_VALUES); /* Test iter_next after iteration has completed. */ - - assert(hash_table_iter_next(&iterator) == HASH_TABLE_NULL); + assert(hash_table_iter_next(&iterator, KEY) == HASH_TABLE_NULL); + assert(hash_table_iter_next(&iterator, VALUE) == HASH_TABLE_NULL); hash_table_free(hash_table); @@ -245,7 +245,7 @@ void test_hash_table_iterating_remove(void) /* Read the next value */ - val = hash_table_iter_next(&iterator); + val = hash_table_iter_next(&iterator, VALUE); /* Remove every hundredth entry */ @@ -428,6 +428,31 @@ void test_hash_table_out_of_memory(void) hash_table_free(hash_table); } +void test_hash_iterator_returning_KeyValue_pair(){ + + HashTable *hash_table; + HashTableIterator iterator; + int** kv_pair; + + hash_table = hash_table_new(int_hash, int_equal); + + /* Add some values */ + + hash_table_insert(hash_table, &value1, &value1); + hash_table_insert(hash_table, &value2, &value2); + + hash_table_iterate(hash_table, &iterator); + + while (hash_table_iter_has_more(&iterator)) { + + // Retrieve both Key and Value + kv_pair = (int**) hash_table_iter_next(&iterator, KEY_VALUE); + + assert(*((int*)kv_pair[0]) == *((int*)kv_pair[1])); + } + hash_table_free(hash_table); +} + static UnitTestFunction tests[] = { test_hash_table_new_free, test_hash_table_insert_lookup, @@ -436,6 +461,7 @@ static UnitTestFunction tests[] = { test_hash_table_iterating_remove, test_hash_table_free_functions, test_hash_table_out_of_memory, + test_hash_iterator_returning_KeyValue_pair, NULL }; From 27330ee533d7d85dbb8ab7e9a0a2427576d4aa13 Mon Sep 17 00:00:00 2001 From: losintikfos Date: Tue, 7 Jul 2015 17:03:06 +0100 Subject: [PATCH 139/250] - Added function hash_table_value to make it flexible to retrieve HashTable value held by current iterator handle. - Removed the previous flag implementation. - Added test coverage also. --- src/hash-table.c | 37 ++++++++++++++++++------------------- src/hash-table.h | 21 ++++++++++++--------- test/test-hash-table.c | 23 ++++++++++++++--------- 3 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index 7071b37..d086d59 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -440,12 +440,27 @@ int hash_table_iter_has_more(HashTableIterator *iterator) return iterator->next_entry != NULL; } -HashTableValue hash_table_iter_next(HashTableIterator *iterator, int flag) +HashTableValue hash_table_value(HashTableIterator *iterator) { + HashTableValue result = HASH_TABLE_NULL; + + /* Iterator has handle on a valid HashTable? */ + if (iterator == NULL || iterator->hash_table == NULL) { + return HASH_TABLE_NULL; + } + + unsigned int cursor = (iterator->next_chain - 1); + HashTableEntry* current_handle = iterator->hash_table->table[cursor]; + result = current_handle->key; + + return result; +} + +HashTableValue hash_table_iter_next(HashTableIterator *iterator) { HashTableEntry *current_entry; HashTable *hash_table; HashTableValue result; - void* res[2]; + unsigned int chain; hash_table = iterator->hash_table; @@ -459,23 +474,7 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator, int flag) /* Result is immediately available */ current_entry = iterator->next_entry; - - switch (flag) { - case VALUE: - result = current_entry->value; - break; - case KEY: - result = current_entry->key; - break; - case KEY_VALUE: - res[0] = current_entry->key; - res[1] = current_entry->value; - result = res; - break; - default: - result = current_entry->value; - break; - } + result = current_entry->key; /* Find the next entry */ diff --git a/src/hash-table.h b/src/hash-table.h index fbf9920..cc98ddb 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -45,10 +45,6 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef ALGORITHM_HASH_TABLE_H #define ALGORITHM_HASH_TABLE_H -#define KEY 1 -#define VALUE 2 -#define KEY_VALUE 3 - #ifdef __cplusplus extern "C" { #endif @@ -242,16 +238,23 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * Using a hash table iterator, retrieve the next key. * * @param iterator The hash table iterator. - * @param flag Flag to determine whether the return value should - * either be the Key, Value or Both KeyValue held in - * array[2] where array[0] is Key and array[1] is value. - * * @return The next key from the hash table, or * @ref HASH_TABLE_NULL if there are no more * keys to iterate over. */ -HashTableValue hash_table_iter_next(HashTableIterator *iterator, int flag); +HashTableValue hash_table_iter_next(HashTableIterator *iterator); + +/** + * Using a hash table iterator, retrieve @ref HashTable value + * held by existing iterator handle. + * + * @param iterator The hash table iterator. + * @return @ref HashTable value currently placed under + * iterator handle, else @ref HASH_TABLE_NULL. + */ + +HashTableValue hash_table_value(HashTableIterator *iterator); #ifdef __cplusplus } diff --git a/test/test-hash-table.c b/test/test-hash-table.c index cdf03c5..172a9d4 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -194,7 +194,7 @@ void test_hash_table_iterating(void) hash_table_iterate(hash_table, &iterator); while (hash_table_iter_has_more(&iterator)) { - hash_table_iter_next(&iterator, VALUE); + hash_table_iter_next(&iterator); ++count; } @@ -202,8 +202,7 @@ void test_hash_table_iterating(void) assert(count == NUM_TEST_VALUES); /* Test iter_next after iteration has completed. */ - assert(hash_table_iter_next(&iterator, KEY) == HASH_TABLE_NULL); - assert(hash_table_iter_next(&iterator, VALUE) == HASH_TABLE_NULL); + assert(hash_table_iter_next(&iterator) == HASH_TABLE_NULL); hash_table_free(hash_table); @@ -245,7 +244,7 @@ void test_hash_table_iterating_remove(void) /* Read the next value */ - val = hash_table_iter_next(&iterator, VALUE); + val = hash_table_iter_next(&iterator); /* Remove every hundredth entry */ @@ -428,11 +427,13 @@ void test_hash_table_out_of_memory(void) hash_table_free(hash_table); } -void test_hash_iterator_returning_KeyValue_pair(){ +void test_hash_iterator_KeyValue_pair() { HashTable *hash_table; HashTableIterator iterator; - int** kv_pair; + int* key; + int* value; + int* l_value; hash_table = hash_table_new(int_hash, int_equal); @@ -446,10 +447,14 @@ void test_hash_iterator_returning_KeyValue_pair(){ while (hash_table_iter_has_more(&iterator)) { // Retrieve both Key and Value - kv_pair = (int**) hash_table_iter_next(&iterator, KEY_VALUE); + key = (int*) hash_table_iter_next(&iterator); + value = (int*) hash_table_value(&iterator); - assert(*((int*)kv_pair[0]) == *((int*)kv_pair[1])); + l_value = hash_table_lookup(hash_table, key); + assert(*key == *value); + assert(*value == *l_value); } + hash_table_free(hash_table); } @@ -461,7 +466,7 @@ static UnitTestFunction tests[] = { test_hash_table_iterating_remove, test_hash_table_free_functions, test_hash_table_out_of_memory, - test_hash_iterator_returning_KeyValue_pair, + test_hash_iterator_KeyValue_pair, NULL }; From e41e47c23fd0a254dabfff3f8b075ab0157d51dd Mon Sep 17 00:00:00 2001 From: bright Date: Tue, 7 Jul 2015 17:06:41 +0100 Subject: [PATCH 140/250] - Removed hash_table_lookup added to test converage. --- test/test-hash-table.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 172a9d4..5a1eafc 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -433,7 +433,6 @@ void test_hash_iterator_KeyValue_pair() { HashTableIterator iterator; int* key; int* value; - int* l_value; hash_table = hash_table_new(int_hash, int_equal); @@ -450,9 +449,7 @@ void test_hash_iterator_KeyValue_pair() { key = (int*) hash_table_iter_next(&iterator); value = (int*) hash_table_value(&iterator); - l_value = hash_table_lookup(hash_table, key); assert(*key == *value); - assert(*value == *l_value); } hash_table_free(hash_table); From 607b48d4b3df24968d5eed4f87ff9639f4dfd972 Mon Sep 17 00:00:00 2001 From: bright Date: Tue, 7 Jul 2015 18:30:51 +0100 Subject: [PATCH 141/250] Return HashTable value instead of HashTable key. --- src/hash-table.c | 11 +++++++---- test/test-hash-table.c | 10 +++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index d086d59..bf19eb5 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -441,7 +441,7 @@ int hash_table_iter_has_more(HashTableIterator *iterator) } HashTableValue hash_table_value(HashTableIterator *iterator) { - HashTableValue result = HASH_TABLE_NULL; + HashTableEntry* current_handle; /* Iterator has handle on a valid HashTable? */ if (iterator == NULL || iterator->hash_table == NULL) { @@ -449,10 +449,13 @@ HashTableValue hash_table_value(HashTableIterator *iterator) { } unsigned int cursor = (iterator->next_chain - 1); - HashTableEntry* current_handle = iterator->hash_table->table[cursor]; - result = current_handle->key; + current_handle = iterator->hash_table->table[cursor]; - return result; + if(current_handle == NULL){ + return HASH_TABLE_NULL; + } + + return current_handle->value; } HashTableValue hash_table_iter_next(HashTableIterator *iterator) diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 5a1eafc..449ade0 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -202,6 +202,7 @@ void test_hash_table_iterating(void) assert(count == NUM_TEST_VALUES); /* Test iter_next after iteration has completed. */ + assert(hash_table_iter_next(&iterator) == HASH_TABLE_NULL); hash_table_free(hash_table); @@ -431,9 +432,6 @@ void test_hash_iterator_KeyValue_pair() { HashTable *hash_table; HashTableIterator iterator; - int* key; - int* value; - hash_table = hash_table_new(int_hash, int_equal); /* Add some values */ @@ -446,10 +444,8 @@ void test_hash_iterator_KeyValue_pair() { while (hash_table_iter_has_more(&iterator)) { // Retrieve both Key and Value - key = (int*) hash_table_iter_next(&iterator); - value = (int*) hash_table_value(&iterator); - - assert(*key == *value); + int* key = (int*) hash_table_iter_next(&iterator); + int* value = (int*) hash_table_value(&iterator); } hash_table_free(hash_table); From c1d2867ce67ad63a3be7a7e0b4b69a3e4f10b314 Mon Sep 17 00:00:00 2001 From: losintikfos Date: Tue, 7 Jul 2015 23:25:18 +0100 Subject: [PATCH 142/250] Made changes `to hash_table_iter_next` to return key of HashTableEntry. This key can then be used to lookup the HashTableEntry value. --- src/hash-table.c | 26 ++++---------------------- src/hash-table.h | 13 +------------ test/test-hash-table.c | 6 ++++-- 3 files changed, 9 insertions(+), 36 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index bf19eb5..58a2bea 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -440,29 +440,11 @@ int hash_table_iter_has_more(HashTableIterator *iterator) return iterator->next_entry != NULL; } -HashTableValue hash_table_value(HashTableIterator *iterator) { - HashTableEntry* current_handle; - - /* Iterator has handle on a valid HashTable? */ - if (iterator == NULL || iterator->hash_table == NULL) { - return HASH_TABLE_NULL; - } - - unsigned int cursor = (iterator->next_chain - 1); - current_handle = iterator->hash_table->table[cursor]; - - if(current_handle == NULL){ - return HASH_TABLE_NULL; - } - - return current_handle->value; -} - -HashTableValue hash_table_iter_next(HashTableIterator *iterator) +HashTableKey hash_table_iter_next(HashTableIterator *iterator) { HashTableEntry *current_entry; HashTable *hash_table; - HashTableValue result; + HashTableKey key; unsigned int chain; @@ -477,7 +459,7 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) /* Result is immediately available */ current_entry = iterator->next_entry; - result = current_entry->key; + key = current_entry->key; /* Find the next entry */ @@ -515,6 +497,6 @@ HashTableValue hash_table_iter_next(HashTableIterator *iterator) iterator->next_chain = chain; } - return result; + return key; } diff --git a/src/hash-table.h b/src/hash-table.h index cc98ddb..2ad7594 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -243,18 +243,7 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * keys to iterate over. */ -HashTableValue hash_table_iter_next(HashTableIterator *iterator); - -/** - * Using a hash table iterator, retrieve @ref HashTable value - * held by existing iterator handle. - * - * @param iterator The hash table iterator. - * @return @ref HashTable value currently placed under - * iterator handle, else @ref HASH_TABLE_NULL. - */ - -HashTableValue hash_table_value(HashTableIterator *iterator); +HashTableKey hash_table_iter_next(HashTableIterator *iterator); #ifdef __cplusplus } diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 449ade0..b4a3bd2 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -444,8 +444,10 @@ void test_hash_iterator_KeyValue_pair() { while (hash_table_iter_has_more(&iterator)) { // Retrieve both Key and Value - int* key = (int*) hash_table_iter_next(&iterator); - int* value = (int*) hash_table_value(&iterator); + HashTableKey key = hash_table_iter_next(&iterator); + int* value = (int*) hash_table_lookup(hash_table, key); + + assert((int* ) key == (int* )value); } hash_table_free(hash_table); From 76b41a45592bd61fe36f897563b0f357849578da Mon Sep 17 00:00:00 2001 From: bright Date: Wed, 8 Jul 2015 08:57:14 +0100 Subject: [PATCH 143/250] + Renamed test_hash_iterator_KeyValue_pair to test_hash_iterator_key_value_pair. + ANSI C comment style used instead. --- test/test-hash-table.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/test-hash-table.c b/test/test-hash-table.c index b4a3bd2..d850cc1 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -428,7 +428,7 @@ void test_hash_table_out_of_memory(void) hash_table_free(hash_table); } -void test_hash_iterator_KeyValue_pair() { +void test_hash_iterator_key_value_pair() { HashTable *hash_table; HashTableIterator iterator; @@ -443,7 +443,8 @@ void test_hash_iterator_KeyValue_pair() { while (hash_table_iter_has_more(&iterator)) { - // Retrieve both Key and Value + /* Retrieve both Key and Value */ + HashTableKey key = hash_table_iter_next(&iterator); int* value = (int*) hash_table_lookup(hash_table, key); @@ -461,7 +462,7 @@ static UnitTestFunction tests[] = { test_hash_table_iterating_remove, test_hash_table_free_functions, test_hash_table_out_of_memory, - test_hash_iterator_KeyValue_pair, + test_hash_iterator_key_value_pair, NULL }; From 23bed06c0deb8a77f2e578bbd38c5b50ea3d6ce0 Mon Sep 17 00:00:00 2001 From: losintinfos Date: Fri, 17 Jul 2015 12:44:43 +0100 Subject: [PATCH 144/250] Refactor HashTableEntry to hold its Key and Value in a struct pointer object KeyValuePair. The reason for this is to: - Return both the Key and Value in composite - Have function hash_table_iter_next return KeyValuePair object holding the composite of Key and Value without the extra call to lookup the value using HashTableKey. - Makes the interface cleaner. --- src/hash-table.c | 141 +++++++++++++++++++++++++++-------------- src/hash-table.h | 17 ++++- test/test-hash-table.c | 17 +++-- 3 files changed, 119 insertions(+), 56 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index 58a2bea..baebdb8 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -32,8 +32,9 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif struct _HashTableEntry { - HashTableKey key; - HashTableValue value; +// HashTableKey key; +// HashTableValue value; + KeyValuePair* value_pair; HashTableEntry *next; }; @@ -95,17 +96,26 @@ static int hash_table_allocate_table(HashTable *hash_table) static void hash_table_free_entry(HashTable *hash_table, HashTableEntry *entry) { - /* If there is a function registered for freeing keys, use it to free - * the key */ + KeyValuePair *value_pair; - if (hash_table->key_free_func != NULL) { - hash_table->key_free_func(entry->key); - } + value_pair = entry->value_pair; + + if(value_pair != NULL){ + + /* If there is a function registered for freeing keys, use it to free + * the key */ + + if (hash_table->key_free_func != NULL) { + hash_table->key_free_func(value_pair->key); + } + + /* Likewise with the value */ - /* Likewise with the value */ + if (hash_table->value_free_func != NULL) { + hash_table->value_free_func(value_pair->value); + } - if (hash_table->value_free_func != NULL) { - hash_table->value_free_func(entry->value); + free(value_pair); } /* Free the data structure */ @@ -185,6 +195,7 @@ static int hash_table_enlarge(HashTable *hash_table) unsigned int old_table_size; unsigned int old_prime_index; HashTableEntry *rover; + KeyValuePair *value_pair; HashTableEntry *next; unsigned int index; unsigned int i; @@ -218,9 +229,13 @@ static int hash_table_enlarge(HashTable *hash_table) while (rover != NULL) { next = rover->next; + /* Fetch rover KeyValuePair */ + + value_pair = rover->value_pair; + /* Find the index into the new table */ - index = hash_table->hash_func(rover->key) + index = hash_table->hash_func(value_pair->key) % hash_table->table_size; /* Link this entry into the chain */ @@ -245,7 +260,9 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue value) { HashTableEntry *rover; + KeyValuePair *value_pair; HashTableEntry *newentry; + KeyValuePair *newvalue_pair; unsigned int index; /* If there are too many items in the table with respect to the table @@ -274,31 +291,40 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, rover = hash_table->table[index]; while (rover != NULL) { - if (hash_table->equal_func(rover->key, key) != 0) { - /* Same key: overwrite this entry with new data */ + /* Fetch rover's KeyValuePair entry */ - /* If there is a value free function, free the old data - * before adding in the new data */ + value_pair = rover->value_pair; - if (hash_table->value_free_func != NULL) { - hash_table->value_free_func(rover->value); - } + if(value_pair != NULL){ - /* Same with the key: use the new key value and free - * the old one */ + if (hash_table->equal_func(value_pair->key, key) != 0) { - if (hash_table->key_free_func != NULL) { - hash_table->key_free_func(rover->key); - } + /* Same key: overwrite this entry with new data */ + + /* If there is a value free function, free the old data + * before adding in the new data */ - rover->key = key; - rover->value = value; + if (hash_table->value_free_func != NULL) { + hash_table->value_free_func(value_pair->value); + } - /* Finished */ + /* Same with the key: use the new key value and free + * the old one */ - return 1; + if (hash_table->key_free_func != NULL) { + hash_table->key_free_func(value_pair->key); + } + + value_pair->key = key; + value_pair->value = value; + + /* Finished */ + + return 1; + } } + rover = rover->next; } @@ -310,8 +336,17 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, return 0; } - newentry->key = key; - newentry->value = value; + newvalue_pair = (KeyValuePair *) malloc(sizeof(KeyValuePair)); + + if(newvalue_pair == NULL){ + return 0; + } + + + newvalue_pair->key = key; + newvalue_pair->value = value; + + newentry->value_pair = newvalue_pair; /* Link into the list */ @@ -330,6 +365,7 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue hash_table_lookup(HashTable *hash_table, HashTableKey key) { HashTableEntry *rover; + KeyValuePair *value_pair; unsigned int index; /* Generate the hash of the key and hence the index into the table */ @@ -342,11 +378,16 @@ HashTableValue hash_table_lookup(HashTable *hash_table, HashTableKey key) rover = hash_table->table[index]; while (rover != NULL) { - if (hash_table->equal_func(key, rover->key) != 0) { + value_pair = rover->value_pair; + + if (value_pair != NULL){ - /* Found the entry. Return the data. */ + if (hash_table->equal_func(key, value_pair->key) != 0) { - return rover->value; + /* Found the entry. Return the data. */ + + return value_pair->value; + } } rover = rover->next; } @@ -360,6 +401,7 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key) { HashTableEntry **rover; HashTableEntry *entry; + KeyValuePair *value_pair; unsigned int index; int result; @@ -377,27 +419,32 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key) while (*rover != NULL) { - if (hash_table->equal_func(key, (*rover)->key) != 0) { + value_pair = (*rover)->value_pair; - /* This is the entry to remove */ + if (value_pair != NULL){ - entry = *rover; + if (hash_table->equal_func(key, value_pair->key) != 0){ - /* Unlink from the list */ + /* This is the entry to remove */ - *rover = entry->next; + entry = *rover; - /* Destroy the entry structure */ + /* Unlink from the list */ - hash_table_free_entry(hash_table, entry); + *rover = entry->next; - /* Track count of entries */ + /* Destroy the entry structure */ - --hash_table->entries; + hash_table_free_entry(hash_table, entry); - result = 1; + /* Track count of entries */ - break; + --hash_table->entries; + + result = 1; + + break; + } } /* Advance to the next entry */ @@ -440,11 +487,11 @@ int hash_table_iter_has_more(HashTableIterator *iterator) return iterator->next_entry != NULL; } -HashTableKey hash_table_iter_next(HashTableIterator *iterator) +KeyValuePair *hash_table_iter_next(HashTableIterator *iterator) { HashTableEntry *current_entry; HashTable *hash_table; - HashTableKey key; + KeyValuePair *value_pair; unsigned int chain; @@ -459,7 +506,7 @@ HashTableKey hash_table_iter_next(HashTableIterator *iterator) /* Result is immediately available */ current_entry = iterator->next_entry; - key = current_entry->key; + value_pair = current_entry->value_pair; /* Find the next entry */ @@ -497,6 +544,6 @@ HashTableKey hash_table_iter_next(HashTableIterator *iterator) iterator->next_chain = chain; } - return key; + return value_pair; } diff --git a/src/hash-table.h b/src/hash-table.h index 2ad7594..803ac1e 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -67,6 +67,7 @@ typedef struct _HashTableIterator HashTableIterator; typedef struct _HashTableEntry HashTableEntry; + /** * A key to look up a value in a @ref HashTable. */ @@ -79,6 +80,16 @@ typedef void *HashTableKey; typedef void *HashTableValue; +/** + * Internal structure representing an entry in hash table + * used as @ref HashTableIterator next result. + */ + +typedef struct _KeyValuePair{ + HashTableKey key; + HashTableValue value; +} KeyValuePair; + /** * Definition of a @ref HashTableIterator. */ @@ -235,15 +246,15 @@ void hash_table_iterate(HashTable *hash_table, HashTableIterator *iter); int hash_table_iter_has_more(HashTableIterator *iterator); /** - * Using a hash table iterator, retrieve the next key. + * Using a hash table iterator, retrieve the next @ref KeyValuePair. * * @param iterator The hash table iterator. - * @return The next key from the hash table, or + * @return The next @ref KeyValuePair from the hash table, or * @ref HASH_TABLE_NULL if there are no more * keys to iterate over. */ -HashTableKey hash_table_iter_next(HashTableIterator *iterator); +KeyValuePair *hash_table_iter_next(HashTableIterator *iterator); #ifdef __cplusplus } diff --git a/test/test-hash-table.c b/test/test-hash-table.c index d850cc1..5d8ff1a 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -228,6 +228,7 @@ void test_hash_table_iterating_remove(void) HashTableIterator iterator; char buf[10]; char *val; + KeyValuePair *value_pair; int count; unsigned int removed; int i; @@ -245,7 +246,8 @@ void test_hash_table_iterating_remove(void) /* Read the next value */ - val = hash_table_iter_next(&iterator); + value_pair = hash_table_iter_next(&iterator); + val = value_pair->value; /* Remove every hundredth entry */ @@ -404,7 +406,8 @@ void test_hash_table_out_of_memory(void) /* Test failure when increasing table size. * The initial table size is 193 entries. The table increases in * size when 1/3 full, so the 66th entry should cause the insert - * to fail. */ + * to fail. + */ for (i=0; i<65; ++i) { values[i] = (int) i; @@ -432,6 +435,7 @@ void test_hash_iterator_key_value_pair() { HashTable *hash_table; HashTableIterator iterator; + KeyValuePair *value_pair; hash_table = hash_table_new(int_hash, int_equal); /* Add some values */ @@ -443,12 +447,13 @@ void test_hash_iterator_key_value_pair() { while (hash_table_iter_has_more(&iterator)) { - /* Retrieve both Key and Value */ + // Retrieve both Key and Value + value_pair = hash_table_iter_next(&iterator); - HashTableKey key = hash_table_iter_next(&iterator); - int* value = (int*) hash_table_lookup(hash_table, key); + int* key = (int*) value_pair->key; + int* val = (int*) value_pair->value; - assert((int* ) key == (int* )value); + assert(*key == *val); } hash_table_free(hash_table); From 02b098e4b876c625cd0c3bc8d460886d823d9749 Mon Sep 17 00:00:00 2001 From: bright Date: Mon, 20 Jul 2015 14:24:03 +0100 Subject: [PATCH 145/250] + Rectified non ANSI-C comment in test/test-hash-table.c + Renamed KeyValuePair to HashTablePair + hash_table_iter_next(..) now returns a copy of HashTablePair to avoid possible mess with the table internal structure. --- src/hash-table.c | 154 +++++++++++++++++------------------------ src/hash-table.h | 19 +++-- test/test-hash-table.c | 20 +++--- 3 files changed, 84 insertions(+), 109 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index baebdb8..1baff9b 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -32,9 +32,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif struct _HashTableEntry { -// HashTableKey key; -// HashTableValue value; - KeyValuePair* value_pair; + HashTablePair pair; HashTableEntry *next; }; @@ -96,26 +94,21 @@ static int hash_table_allocate_table(HashTable *hash_table) static void hash_table_free_entry(HashTable *hash_table, HashTableEntry *entry) { - KeyValuePair *value_pair; + HashTablePair *pair; - value_pair = entry->value_pair; + pair = &(entry->pair); - if(value_pair != NULL){ + /* If there is a function registered for freeing keys, use it to free + * the key */ - /* If there is a function registered for freeing keys, use it to free - * the key */ - - if (hash_table->key_free_func != NULL) { - hash_table->key_free_func(value_pair->key); - } - - /* Likewise with the value */ + if (hash_table->key_free_func != NULL) { + hash_table->key_free_func(pair->key); + } - if (hash_table->value_free_func != NULL) { - hash_table->value_free_func(value_pair->value); - } + /* Likewise with the value */ - free(value_pair); + if (hash_table->value_free_func != NULL) { + hash_table->value_free_func(pair->value); } /* Free the data structure */ @@ -195,7 +188,7 @@ static int hash_table_enlarge(HashTable *hash_table) unsigned int old_table_size; unsigned int old_prime_index; HashTableEntry *rover; - KeyValuePair *value_pair; + HashTablePair *pair; HashTableEntry *next; unsigned int index; unsigned int i; @@ -229,14 +222,13 @@ static int hash_table_enlarge(HashTable *hash_table) while (rover != NULL) { next = rover->next; - /* Fetch rover KeyValuePair */ + /* Fetch rover HashTablePair */ - value_pair = rover->value_pair; + pair = &(rover->pair); /* Find the index into the new table */ - index = hash_table->hash_func(value_pair->key) - % hash_table->table_size; + index = hash_table->hash_func(pair->key) % hash_table->table_size; /* Link this entry into the chain */ @@ -260,9 +252,9 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue value) { HashTableEntry *rover; - KeyValuePair *value_pair; + HashTablePair *pair; HashTableEntry *newentry; - KeyValuePair *newvalue_pair; + HashTablePair newpair; unsigned int index; /* If there are too many items in the table with respect to the table @@ -292,37 +284,34 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, while (rover != NULL) { - /* Fetch rover's KeyValuePair entry */ - - value_pair = rover->value_pair; + /* Fetch rover's HashTablePair entry */ - if(value_pair != NULL){ + pair = &(rover->pair); - if (hash_table->equal_func(value_pair->key, key) != 0) { + if (hash_table->equal_func(pair->key, key) != 0) { - /* Same key: overwrite this entry with new data */ + /* Same key: overwrite this entry with new data */ - /* If there is a value free function, free the old data - * before adding in the new data */ + /* If there is a value free function, free the old data + * before adding in the new data */ - if (hash_table->value_free_func != NULL) { - hash_table->value_free_func(value_pair->value); - } + if (hash_table->value_free_func != NULL) { + hash_table->value_free_func(pair->value); + } - /* Same with the key: use the new key value and free - * the old one */ + /* Same with the key: use the new key value and free + * the old one */ - if (hash_table->key_free_func != NULL) { - hash_table->key_free_func(value_pair->key); - } + if (hash_table->key_free_func != NULL) { + hash_table->key_free_func(pair->key); + } - value_pair->key = key; - value_pair->value = value; + pair->key = key; + pair->value = value; - /* Finished */ + /* Finished */ - return 1; - } + return 1; } rover = rover->next; @@ -336,17 +325,10 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, return 0; } - newvalue_pair = (KeyValuePair *) malloc(sizeof(KeyValuePair)); - - if(newvalue_pair == NULL){ - return 0; - } - - - newvalue_pair->key = key; - newvalue_pair->value = value; + newpair.key = key; + newpair.value = value; - newentry->value_pair = newvalue_pair; + newentry->pair = newpair; /* Link into the list */ @@ -365,7 +347,7 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue hash_table_lookup(HashTable *hash_table, HashTableKey key) { HashTableEntry *rover; - KeyValuePair *value_pair; + HashTablePair *pair; unsigned int index; /* Generate the hash of the key and hence the index into the table */ @@ -378,17 +360,15 @@ HashTableValue hash_table_lookup(HashTable *hash_table, HashTableKey key) rover = hash_table->table[index]; while (rover != NULL) { - value_pair = rover->value_pair; - - if (value_pair != NULL){ + pair = &(rover->pair); - if (hash_table->equal_func(key, value_pair->key) != 0) { + if (hash_table->equal_func(key, pair->key) != 0) { - /* Found the entry. Return the data. */ + /* Found the entry. Return the data. */ - return value_pair->value; - } + return pair->value; } + rover = rover->next; } @@ -401,7 +381,7 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key) { HashTableEntry **rover; HashTableEntry *entry; - KeyValuePair *value_pair; + HashTablePair *pair; unsigned int index; int result; @@ -419,32 +399,29 @@ int hash_table_remove(HashTable *hash_table, HashTableKey key) while (*rover != NULL) { - value_pair = (*rover)->value_pair; - - if (value_pair != NULL){ + pair = &((*rover)->pair); - if (hash_table->equal_func(key, value_pair->key) != 0){ + if (hash_table->equal_func(key, pair->key) != 0) { - /* This is the entry to remove */ + /* This is the entry to remove */ - entry = *rover; + entry = *rover; - /* Unlink from the list */ + /* Unlink from the list */ - *rover = entry->next; + *rover = entry->next; - /* Destroy the entry structure */ + /* Destroy the entry structure */ - hash_table_free_entry(hash_table, entry); + hash_table_free_entry(hash_table, entry); - /* Track count of entries */ + /* Track count of entries */ - --hash_table->entries; + --hash_table->entries; - result = 1; + result = 1; - break; - } + break; } /* Advance to the next entry */ @@ -487,26 +464,20 @@ int hash_table_iter_has_more(HashTableIterator *iterator) return iterator->next_entry != NULL; } -KeyValuePair *hash_table_iter_next(HashTableIterator *iterator) +HashTablePair hash_table_iter_next(HashTableIterator *iterator) { HashTableEntry *current_entry; HashTable *hash_table; - KeyValuePair *value_pair; + HashTablePair pair; unsigned int chain; hash_table = iterator->hash_table; - /* No more entries? */ - - if (iterator->next_entry == NULL) { - return HASH_TABLE_NULL; - } - /* Result is immediately available */ current_entry = iterator->next_entry; - value_pair = current_entry->value_pair; + pair = current_entry->pair; /* Find the next entry */ @@ -531,8 +502,7 @@ KeyValuePair *hash_table_iter_next(HashTableIterator *iterator) /* Is there anything in this chain? */ if (hash_table->table[chain] != NULL) { - iterator->next_entry = - hash_table->table[chain]; + iterator->next_entry = hash_table->table[chain]; break; } @@ -544,6 +514,6 @@ KeyValuePair *hash_table_iter_next(HashTableIterator *iterator) iterator->next_chain = chain; } - return value_pair; + return pair; } diff --git a/src/hash-table.h b/src/hash-table.h index 803ac1e..43a49f9 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -85,10 +85,10 @@ typedef void *HashTableValue; * used as @ref HashTableIterator next result. */ -typedef struct _KeyValuePair{ +typedef struct _HashTablePair{ HashTableKey key; HashTableValue value; -} KeyValuePair; +} HashTablePair; /** * Definition of a @ref HashTableIterator. @@ -246,15 +246,20 @@ void hash_table_iterate(HashTable *hash_table, HashTableIterator *iter); int hash_table_iter_has_more(HashTableIterator *iterator); /** - * Using a hash table iterator, retrieve the next @ref KeyValuePair. + * Using a hash table iterator, retrieve the next @ref HashTablePair. + * + * Note: To avoid @ref HashTableEntry internal @ref HashTablePair + * from been temperd with, and potentially messing with + * internal table structure, the function returns a copy + * of @ref HashTablePair stored internally. * * @param iterator The hash table iterator. - * @return The next @ref KeyValuePair from the hash table, or - * @ref HASH_TABLE_NULL if there are no more - * keys to iterate over. + * @return The next @ref HashTablePair from the hash table, or + * @ref HASH_TABLE_NULL if there are no more keys to + * iterate over. */ -KeyValuePair *hash_table_iter_next(HashTableIterator *iterator); +HashTablePair hash_table_iter_next(HashTableIterator *iterator); #ifdef __cplusplus } diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 5d8ff1a..309b666 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -228,7 +228,7 @@ void test_hash_table_iterating_remove(void) HashTableIterator iterator; char buf[10]; char *val; - KeyValuePair *value_pair; + HashTablePair pair; int count; unsigned int removed; int i; @@ -246,8 +246,8 @@ void test_hash_table_iterating_remove(void) /* Read the next value */ - value_pair = hash_table_iter_next(&iterator); - val = value_pair->value; + pair = hash_table_iter_next(&iterator); + val = pair.value; /* Remove every hundredth entry */ @@ -431,11 +431,11 @@ void test_hash_table_out_of_memory(void) hash_table_free(hash_table); } -void test_hash_iterator_key_value_pair() { +void test_hash_iterator_key_pair() { HashTable *hash_table; HashTableIterator iterator; - KeyValuePair *value_pair; + HashTablePair pair; hash_table = hash_table_new(int_hash, int_equal); /* Add some values */ @@ -447,11 +447,11 @@ void test_hash_iterator_key_value_pair() { while (hash_table_iter_has_more(&iterator)) { - // Retrieve both Key and Value - value_pair = hash_table_iter_next(&iterator); + /* Retrieve both Key and Value */ + pair = hash_table_iter_next(&iterator); - int* key = (int*) value_pair->key; - int* val = (int*) value_pair->value; + int* key = (int*) pair.key; + int* val = (int*) pair.value; assert(*key == *val); } @@ -467,7 +467,7 @@ static UnitTestFunction tests[] = { test_hash_table_iterating_remove, test_hash_table_free_functions, test_hash_table_out_of_memory, - test_hash_iterator_key_value_pair, + test_hash_iterator_key_pair, NULL }; From 5c8cf16569f4971991835d20953f9b6afbf20a80 Mon Sep 17 00:00:00 2001 From: bright Date: Mon, 20 Jul 2015 14:34:28 +0100 Subject: [PATCH 146/250] + Resolved test coverage error - Removed comment no more applicable to hash_table_iter_next(..) --- src/hash-table.h | 5 ++--- test/test-hash-table.c | 4 ---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/hash-table.h b/src/hash-table.h index 43a49f9..03af57c 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -254,9 +254,8 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * of @ref HashTablePair stored internally. * * @param iterator The hash table iterator. - * @return The next @ref HashTablePair from the hash table, or - * @ref HASH_TABLE_NULL if there are no more keys to - * iterate over. + * @return The next @ref HashTablePair from the hash table + * if there are no more keys to iterate over. */ HashTablePair hash_table_iter_next(HashTableIterator *iterator); diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 309b666..89bad99 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -201,10 +201,6 @@ void test_hash_table_iterating(void) assert(count == NUM_TEST_VALUES); - /* Test iter_next after iteration has completed. */ - - assert(hash_table_iter_next(&iterator) == HASH_TABLE_NULL); - hash_table_free(hash_table); /* Test iterating over an empty table */ From a9a78b21d6bffcd6ea5752b489136eb43b6739a8 Mon Sep 17 00:00:00 2001 From: bright Date: Mon, 20 Jul 2015 15:05:08 +0100 Subject: [PATCH 147/250] + Added back the condition to ensure iterator has next item else return HashTablePair of both Key and Value set to NULL. --- src/hash-table.c | 7 ++++++- src/hash-table.h | 5 +++-- test/test-hash-table.c | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index 1baff9b..cefa3d5 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -468,12 +468,17 @@ HashTablePair hash_table_iter_next(HashTableIterator *iterator) { HashTableEntry *current_entry; HashTable *hash_table; - HashTablePair pair; + + HashTablePair pair = {NULL, NULL}; unsigned int chain; hash_table = iterator->hash_table; + if (iterator->next_entry == NULL) { + return pair; + } + /* Result is immediately available */ current_entry = iterator->next_entry; diff --git a/src/hash-table.h b/src/hash-table.h index 03af57c..01f02b3 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -254,8 +254,9 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * of @ref HashTablePair stored internally. * * @param iterator The hash table iterator. - * @return The next @ref HashTablePair from the hash table - * if there are no more keys to iterate over. + * @return The next @ref HashTablePair from the hash table, or + * @ref HASH_TABLE_NULL of Key and Value if there are + * no more keys to iterate over. */ HashTablePair hash_table_iter_next(HashTableIterator *iterator); diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 89bad99..856d412 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -201,6 +201,10 @@ void test_hash_table_iterating(void) assert(count == NUM_TEST_VALUES); + /* Test iter_next after iteration has completed. */ + HashTablePair pair = hash_table_iter_next(&iterator); + assert(pair.value == HASH_TABLE_NULL); + hash_table_free(hash_table); /* Test iterating over an empty table */ From 8bee436572c3eae39baa099dbcb73c8f32e94667 Mon Sep 17 00:00:00 2001 From: bright Date: Mon, 20 Jul 2015 15:14:06 +0100 Subject: [PATCH 148/250] + Added new line after comment --- test/test-hash-table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 856d412..1495437 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -202,6 +202,7 @@ void test_hash_table_iterating(void) assert(count == NUM_TEST_VALUES); /* Test iter_next after iteration has completed. */ + HashTablePair pair = hash_table_iter_next(&iterator); assert(pair.value == HASH_TABLE_NULL); From 17924023fc223bb1613e8835bda41789f90f515e Mon Sep 17 00:00:00 2001 From: bright Date: Mon, 20 Jul 2015 21:19:59 +0100 Subject: [PATCH 149/250] + Comments kept within 80 columns + Moved pointer symbol next to variable in test/test-hash-table.c --- src/hash-table.h | 9 +++++---- test/test-hash-table.c | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hash-table.h b/src/hash-table.h index 01f02b3..d8be331 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -249,14 +249,15 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * Using a hash table iterator, retrieve the next @ref HashTablePair. * * Note: To avoid @ref HashTableEntry internal @ref HashTablePair - * from been temperd with, and potentially messing with + * from been tampered with, and potentially messing with * internal table structure, the function returns a copy * of @ref HashTablePair stored internally. * * @param iterator The hash table iterator. - * @return The next @ref HashTablePair from the hash table, or - * @ref HASH_TABLE_NULL of Key and Value if there are - * no more keys to iterate over. + * @return The next @ref HashTablePair from the hash + * table, or @ref HASH_TABLE_NULL of Key and + * Value if there are no more keys to iterate + * over. */ HashTablePair hash_table_iter_next(HashTableIterator *iterator); diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 1495437..6cdd869 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -449,10 +449,11 @@ void test_hash_iterator_key_pair() { while (hash_table_iter_has_more(&iterator)) { /* Retrieve both Key and Value */ + pair = hash_table_iter_next(&iterator); - int* key = (int*) pair.key; - int* val = (int*) pair.value; + int *key = (int*) pair.key; + int *val = (int*) pair.value; assert(*key == *val); } From 858a07e4ca9ca68fdd047dcc13b651ed16a76d13 Mon Sep 17 00:00:00 2001 From: bright Date: Wed, 22 Jul 2015 21:31:31 +0100 Subject: [PATCH 150/250] + Replaced word been with being in comment for function hash_table_iter_next(..) + Variable newpair is removed and value and key set directly to newentry->pair.key and newentry->pair.value + Unwanted empty lines removed + Brace placed onto a new line for function test_hash_iterator_key_pair(..) --- src/hash-table.c | 8 ++------ src/hash-table.h | 3 +-- test/test-hash-table.c | 4 ++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/hash-table.c b/src/hash-table.c index cefa3d5..2f3119c 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -254,7 +254,6 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableEntry *rover; HashTablePair *pair; HashTableEntry *newentry; - HashTablePair newpair; unsigned int index; /* If there are too many items in the table with respect to the table @@ -325,10 +324,8 @@ int hash_table_insert(HashTable *hash_table, HashTableKey key, return 0; } - newpair.key = key; - newpair.value = value; - - newentry->pair = newpair; + newentry->pair.key = key; + newentry->pair.value = value; /* Link into the list */ @@ -468,7 +465,6 @@ HashTablePair hash_table_iter_next(HashTableIterator *iterator) { HashTableEntry *current_entry; HashTable *hash_table; - HashTablePair pair = {NULL, NULL}; unsigned int chain; diff --git a/src/hash-table.h b/src/hash-table.h index d8be331..a11c6d8 100644 --- a/src/hash-table.h +++ b/src/hash-table.h @@ -67,7 +67,6 @@ typedef struct _HashTableIterator HashTableIterator; typedef struct _HashTableEntry HashTableEntry; - /** * A key to look up a value in a @ref HashTable. */ @@ -249,7 +248,7 @@ int hash_table_iter_has_more(HashTableIterator *iterator); * Using a hash table iterator, retrieve the next @ref HashTablePair. * * Note: To avoid @ref HashTableEntry internal @ref HashTablePair - * from been tampered with, and potentially messing with + * from being tampered with, and potentially messing with * internal table structure, the function returns a copy * of @ref HashTablePair stored internally. * diff --git a/test/test-hash-table.c b/test/test-hash-table.c index 6cdd869..126d2b2 100644 --- a/test/test-hash-table.c +++ b/test/test-hash-table.c @@ -432,8 +432,8 @@ void test_hash_table_out_of_memory(void) hash_table_free(hash_table); } -void test_hash_iterator_key_pair() { - +void test_hash_iterator_key_pair() +{ HashTable *hash_table; HashTableIterator iterator; HashTablePair pair; From 3a9b0608a98f578e1a6214ec548f3ca387822dc9 Mon Sep 17 00:00:00 2001 From: bright Date: Wed, 22 Jul 2015 21:40:36 +0100 Subject: [PATCH 151/250] + Removed unwanted new line --- src/hash-table.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hash-table.c b/src/hash-table.c index 2f3119c..21cd429 100644 --- a/src/hash-table.c +++ b/src/hash-table.c @@ -466,7 +466,6 @@ HashTablePair hash_table_iter_next(HashTableIterator *iterator) HashTableEntry *current_entry; HashTable *hash_table; HashTablePair pair = {NULL, NULL}; - unsigned int chain; hash_table = iterator->hash_table; From 925fa229796a45718ffe0c603258727ac8b89580 Mon Sep 17 00:00:00 2001 From: Bao Hexing Date: Sat, 16 Jan 2016 11:11:56 +0800 Subject: [PATCH 152/250] Add validation check of input parameters --- src/list.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/list.c b/src/list.c index 1545ef3..c8f407b 100644 --- a/src/list.c +++ b/src/list.c @@ -60,6 +60,13 @@ ListEntry *list_prepend(ListEntry **list, ListValue data) { ListEntry *newentry; + if (list == NULL) { + + /* not a valid list */ + + return NULL; + } + /* Create new entry */ newentry = malloc(sizeof(ListEntry)); @@ -87,6 +94,10 @@ ListEntry *list_append(ListEntry **list, ListValue data) ListEntry *rover; ListEntry *newentry; + if (list == NULL) { + return NULL; + } + /* Create new list entry */ newentry = malloc(sizeof(ListEntry)); @@ -124,16 +135,28 @@ ListEntry *list_append(ListEntry **list, ListValue data) ListValue list_data(ListEntry *listentry) { + if (listentry == NULL) { + return LIST_NULL; + } + return listentry->data; } ListEntry *list_prev(ListEntry *listentry) { + if (listentry == NULL) { + return NULL; + } + return listentry->prev; } ListEntry *list_next(ListEntry *listentry) { + if (listentry == NULL) { + return NULL; + } + return listentry->next; } @@ -234,7 +257,7 @@ int list_remove_entry(ListEntry **list, ListEntry *entry) { /* If the list is empty, or entry is NULL, always fail */ - if (*list == NULL || entry == NULL) { + if (list == NULL || *list == NULL || entry == NULL) { return 0; } @@ -285,6 +308,10 @@ unsigned int list_remove_data(ListEntry **list, ListEqualFunc callback, ListEntry *rover; ListEntry *next; + if (list == NULL || callback == NULL) { + return 0; + } + entries_removed = 0; /* Iterate over the entries in the list */ @@ -343,6 +370,10 @@ static ListEntry *list_sort_internal(ListEntry **list, ListEntry *less_list, *more_list; ListEntry *less_list_end, *more_list_end; + if (list == NULL || compare_func == NULL) { + return NULL; + } + /* If there are less than two entries in this list, it is * already sorted */ From f52db07cb67039dadad38d3794f2c6d02a24a03a Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Sat, 9 Apr 2016 19:59:03 +0200 Subject: [PATCH 153/250] Adding SortedArray Feature. Included header, implementation and testing. Files have been added to Makefile.am Fixed sortedarray_index_of zero length failure. Removed -1 from initialising right edge. Refactoring: Replaced // comments with /* ... */ style comments Removed some debug code which was still present. Refactor: removed unnecessary function prototypes, removed full doc comments for static function Refactor: indentation style while keeping 80 flow limit. Refactoring, array syntax instead of pointers and some minor fixes. Rename variables to be clearer. Restructured tests around integers and fixed bugs detected by new tests. --- src/Makefile.am | 4 +- src/sortedarray.c | 269 ++++++++++++++++++++++++++++++++++++++++ src/sortedarray.h | 193 ++++++++++++++++++++++++++++ test/Makefile.am | 3 +- test/test-sortedarray.c | 245 ++++++++++++++++++++++++++++++++++++ 5 files changed, 711 insertions(+), 3 deletions(-) create mode 100644 src/sortedarray.c create mode 100644 src/sortedarray.h create mode 100644 test/test-sortedarray.c diff --git a/src/Makefile.am b/src/Makefile.am index 1f87723..06c9ab8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,13 +8,13 @@ CALG_HEADERFILES=\ arraylist.h compare-int.h hash-int.h hash-table.h set.h \ avl-tree.h compare-pointer.h hash-pointer.h list.h slist.h \ queue.h compare-string.h hash-string.h trie.h binary-heap.h \ -bloom-filter.h binomial-heap.h rb-tree.h +bloom-filter.h binomial-heap.h rb-tree.h sortedarray.h SRC=\ arraylist.c compare-pointer.c hash-pointer.c list.c slist.c \ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ -bloom-filter.c binomial-heap.c rb-tree.c +bloom-filter.c binomial-heap.c rb-tree.c sortedarray.c libcalgtest_a_CFLAGS=$(TEST_CFLAGS) -DALLOC_TESTING -I../test -g libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) diff --git a/src/sortedarray.c b/src/sortedarray.c new file mode 100644 index 0000000..fcd4aa6 --- /dev/null +++ b/src/sortedarray.c @@ -0,0 +1,269 @@ +/* + +Copyright (c) 2016, Stefan Cloudt + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +/** + * @file sortedarray.c + * + * @brief File containing the implementation of sortedarray.h + */ + +#include +#include +#include + +#include "sortedarray.h" + +#ifdef ALLOC_TESTING +#include "alloc-testing.h" +#endif + +/* Function for finding first index of range which equals data. An equal value + must be present. */ +static unsigned int sortedarray_first_index(SortedArray *sortedarray, + SortedArrayValue data, unsigned int left, + unsigned int right) +{ + unsigned int index = 0; + + while (left < right) { + index = (left + right) / 2; + + int order = sortedarray->cmp_func(data, + sortedarray->data[index]); + if (order > 0) { + left = index + 1; + } + else { + right = index; + } + } + + return index; +} + +/* Function for finding last index of range which equals data. An equal value + must be present. */ +static unsigned int sortedarray_last_index(SortedArray *sortedarray, + SortedArrayValue data, unsigned int left, + unsigned int right) +{ + unsigned int index = 0; + + while (left < right) { + index = (left + right) / 2; + + int order = sortedarray->cmp_func(data, + sortedarray->data[index]); + if (order <= 0) { + left = index + 1; + } + else { + right = index; + } + } + + return (index > 0) ? index - 1 : 0; +} + + SortedArray *sortedarray_new(unsigned int length, + SortedArrayEqualFunc equ_func, + SortedArrayCompareFunc cmp_func) +{ + /* check input requirements */ + if (equ_func == NULL || cmp_func == NULL) { + return NULL; + } + + /* If length is 0, set it to a default. */ + if (length == 0) { + length = 16; + } + + SortedArrayValue *array = malloc(sizeof(SortedArrayValue) * length); + + /* on failure, return null */ + if (array == NULL) { + return NULL; + } + + SortedArray *sortedarray = malloc(sizeof(SortedArray)); + + /* check for failure */ + if (sortedarray == NULL) { + free(array); + return NULL; + } + + /* init */ + sortedarray->data = array; + sortedarray->length = 0; + sortedarray->_alloced = length; + sortedarray->equ_func = equ_func; + sortedarray->cmp_func = cmp_func; + return sortedarray; +} + +void sortedarray_free(SortedArray *sortedarray) +{ + if (sortedarray != NULL) { + free(sortedarray->data); + free(sortedarray); + } +} + +void sortedarray_remove(SortedArray *sortedarray, unsigned int index) +{ + /* same as remove range of length 1 */ + sortedarray_remove_range(sortedarray, index, 1); +} + +void sortedarray_remove_range(SortedArray *sortedarray, unsigned int index, + unsigned int length) +{ + /* removal does not violate sorted property */ + + /* check if valid range */ + if (index > sortedarray->length || index + length > sortedarray->length) { + return; + } + + /* move entries back */ + memmove(&sortedarray->data[index], + &sortedarray->data[index + length], + (sortedarray->length - (index + length)) + * sizeof(SortedArrayValue)); + + sortedarray->length -= length; +} + +int sortedarray_insert(SortedArray *sortedarray, SortedArrayValue data) +{ + /* do a binary search like loop to find right position */ + unsigned int left = 0; + unsigned int right = sortedarray->length; + unsigned int index = 0; + + right = (right > 1) ? right : 0; + + while (left != right) { + index = (left + right) / 2; + + int order = sortedarray->cmp_func(data, + sortedarray->data[index]); + if (order < 0) { + /* value should be left of index */ + right = index; + } + else if (order > 0) { + /* value should be right of index */ + left = index + 1; + } + else { + /* value should be at index */ + left = right = index; + break; + } + } + + if (sortedarray->length > 0 && sortedarray->cmp_func(data, sortedarray->data[index]) > 0) { + index++; + } + + /* insert element at r */ + if (sortedarray->length + 1 > sortedarray->_alloced) { + /* enlarge the array */ + unsigned int newsize; + SortedArrayValue *data; + + newsize = sortedarray->_alloced * 2; + data = realloc(sortedarray->data, sizeof(SortedArrayValue) * newsize); + + if (data == NULL) { + return 0; + } + else { + sortedarray->data = data; + sortedarray->_alloced = newsize; + } + } + + /* move all other elements */ + memmove(&sortedarray->data[index + 1], + &sortedarray->data[index], + (sortedarray->length - index) * sizeof(SortedArrayValue)); + + /* insert entry */ + sortedarray->data[index] = data; + ++(sortedarray->length); + + return 1; +} + +int sortedarray_index_of(SortedArray *sortedarray, SortedArrayValue data) +{ + /* do a binary search */ + unsigned int left = 0; + unsigned int right = sortedarray->length; + unsigned int index = 0; + + /* safe subtract 1 of right without going negative */ + right = (right > 1) ? right : 0; + + while (left != right) { + index = (left + right) / 2; + + int order = sortedarray->cmp_func(data, + sortedarray->data[index]); + if (order < 0) { + /* value should be left */ + right = index; + } + else if (order > 0) { + /* value should be right */ + left = index + 1; + } + else { + /* no binary search can be done anymore, + search linear now */ + left = sortedarray_first_index(sortedarray, data, left, + index); + right = sortedarray_last_index(sortedarray, data, + index, right); + + for (index = left; index <= right; index++) { + if (sortedarray->equ_func(data, + sortedarray->data[index])) { + return (int) index; + } + } + + /* nothing is found */ + return -1; + } + } + + return -1; +} + +void sortedarray_clear(SortedArray *sortedarray) +{ + /* set length to 0 */ + sortedarray->length = 0; +} diff --git a/src/sortedarray.h b/src/sortedarray.h new file mode 100644 index 0000000..7c2bd41 --- /dev/null +++ b/src/sortedarray.h @@ -0,0 +1,193 @@ +/* + +Copyright (c) 2016, Stefan Cloudt + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +/** + * @file sortedarray.h + * + * @brief Automatically sorted and resizing array + * + * SortedArrays are encapsulated ArrayLists which are sorted. + * + * To create a SortedArray, use @ref sortedarray_new + * To destroy a SortedArray, use @ref sortedarray_free + * + * To add a value to a SortedArray, use @ref sortedarray_prepend, + * @ref sortedarray_append, or @ref sortedarray_insert. + * + * To remove a value from a SortedArray, use @ref sortedarray_remove + * or @ref sortedarray_remove_range. + */ + +#ifndef ALGORITHM_SORTEDARRAY_H +#define ALGORITHM_SORTEDARRAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A value to store in @ref SortedArray. + */ +typedef void *SortedArrayValue; + +/** + * A SortedArray structure. Use @ref sortedarray_new to create one. + * + * The SortedArray is an automatically resizing array which stores its + * elements in sorted order. Userdefined functions determine the sorting order. + * All operations on a SortedArray maintain the sorted property. Most + * operations are done in O(n) time, but searching can be done in O(log n) + * worst case. + * + * @see sortedarray_new + */ +typedef struct _SortedArray SortedArray; + +/** + * Compare two values in a SortedArray to determine if they are equal. + * + * @param value1 The first value to compare. + * @param value2 The second value to compare. + * @return Non-zero if value1 equals value2, zero if they do not + * equal. + * + */ +typedef int (*SortedArrayEqualFunc)(SortedArrayValue value1, + SortedArrayValue value2); + +/** + * Compare two values in a SortedArray to determine their order. + * + * @param value1 The first value to compare. + * @param value2 The second value to compare. + * @return Less than zero if value1 is compared smaller than + * value2, zero if they compare equal, or greater than + * zero if value1 compares greate than value2. + */ +typedef int (*SortedArrayCompareFunc)(SortedArrayValue value1, + SortedArrayValue value2); + +/** + * Definition of a @ref SortedArray + */ +struct _SortedArray { + /** + * This field contains the actual array. The array always has a length + * of value of field length. + */ + SortedArrayValue *data; + + /** + * The length of the sorted array. + */ + unsigned int length; + + /** + * Field for internal usage only indicating how much memory already has + * been allocated for *data. + */ + unsigned int _alloced; + + /** + * The callback used to determine if two values equal. + */ + SortedArrayEqualFunc equ_func; + + /** + * The callback use to determine the order of two values. + */ + SortedArrayCompareFunc cmp_func; +}; + +/** + * Allocate a new SortedArray for use. + * + * @param length Indication to the amount of memory that should be + * allocated. If 0 is given, then a default is used. + * @param equ_func The function used to determine if two values in the + * SortedArray equal. This may not be NULL. + * @param cmp_func The function used to determine the relative order of + * two values in the SortedArray. This may not be NULL. + * + * @return A new SortedArray or NULL if it was not possible to + * allocate one. + */ +SortedArray *sortedarray_new(unsigned int length, + SortedArrayEqualFunc equ_func, + SortedArrayCompareFunc cmp_func); + +/** + * Frees a SortedArray from memory. + * + * @param sortedarray The SortedArray to free. + */ +void sortedarray_free(SortedArray *sortedarray); + +/** + * Remove a value from a SortedArray at a specified index while maintaining the + * sorted property. + * + * @param sortedarray The SortedArray to remove a value from. + * @param index The index to remove from the array. + */ +void sortedarray_remove(SortedArray *sortedarray, unsigned int index); + +/** + * Remove a range of entities from a SortedArray while maintaining the sorted + * property. + * + * @param sortedarray The SortedArray to remove the range of values from. + * @param index The starting index of the range to remove. + * @param length The length of the range to remove. + */ +void sortedarray_remove_range(SortedArray *sortedarray, unsigned int index, + unsigned int length); + +/** + * Insert a value into a SortedArray while maintaining the sorted property. + * + * @param sortedarray The SortedArray to insert into. + * @param data The data to insert. + * + * @return Zero on failure, or a non-zero value if successfull. + */ +int sortedarray_insert(SortedArray *sortedarray, SortedArrayValue data); + +/** + * Find the index of a value in a SortedArray. + * + * @param sortedarray The SortedArray to find in. + * @param data The value to find. + * @return The index of the value or -1 if the value is not found. + */ +int sortedarray_index_of(SortedArray *sortedarray, SortedArrayValue data); + +/** + * Remove all values from a SortedArray. + * + * @param sortedarray The SortedArray to clear. + */ +void sortedarray_clear(SortedArray *sortedarray); + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef ALGORITHM_SORTEDARRAY_H diff --git a/test/Makefile.am b/test/Makefile.am index f34da95..d01cd7d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -23,7 +23,8 @@ TESTS = \ test-hash-table \ test-rb-tree \ test-set \ - test-trie + test-trie \ + test-sortedarray check_PROGRAMS = $(TESTS) check_LIBRARIES = libtestframework.a diff --git a/test/test-sortedarray.c b/test/test-sortedarray.c new file mode 100644 index 0000000..7912fdd --- /dev/null +++ b/test/test-sortedarray.c @@ -0,0 +1,245 @@ +/* + +Copyright (c) 2016, Stefan Cloudt + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice appear +in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + */ + +#include +#include +#include +#include + +#include "alloc-testing.h" +#include "framework.h" + +#include "sortedarray.h" + +#define TEST_SIZE 100 + +static int cmp_int(SortedArrayValue v1, SortedArrayValue v2) +{ + int *i1 = (int*) v1; + int *i2 = (int*) v2; + + if (i1 == i2) { + return 0; + } + + if (i1 == NULL || i2 == NULL) { + return (i1 == NULL) ? 1 : -1; + } + + /* discard last 2 digits, for testing difference between elements with + same order but which are not equal. See index_of */ + int a = (*i1)/10; + int b = (*i2)/10; + + int r = 0; + + if (a == b) { + r = 0; + } + else { + r = (a > b) ? 1 : -1; + } + + return r; +} + +static int equ_int(SortedArrayValue v1, SortedArrayValue v2) +{ + int *i1 = (int*) v1; + int *i2 = (int*) v2; + + if (i1 == i2) { + return 1; + } + + if (i1 == NULL || i2 == NULL) { + return 0; + } + + return *i1 == *i2; +} + +void check_sorted_prop(SortedArray *sortedarray) +{ + unsigned int i; + for (i = 1; i < sortedarray->length; i++) { + assert(cmp_int( + sortedarray->data[i - 1], + sortedarray->data[i]) <= 0); + } +} + +void free_sorted_ints(SortedArray *sortedarray) +{ + unsigned int i; + for (i = 0; i < sortedarray->length; i++) { + int *pi = sortedarray->data[i]; + free(pi); + } + + sortedarray_free(sortedarray); +} + +SortedArray *generate_sortedarray(void) +{ + /* generate a sorted array of length TEST_SIZE, filled with random + numbers. */ + SortedArray *sortedarray; + unsigned int i; + + sortedarray = sortedarray_new(0, equ_int, cmp_int); + + /* set random seed */ + srand((unsigned int) time(NULL)); + + /* fill with random numbers */ + for (i = 0; i < TEST_SIZE; ++i) { + int r = rand(); + r = (int) (((float) r)/((float) RAND_MAX) * 100); + int *pi = malloc(sizeof(int)); + *pi = r; + sortedarray_insert(sortedarray, pi); + } + + return sortedarray; +} + +void test_sortedarray_new_free(void) +{ + SortedArray *sortedarray; + + /* test normal */ + sortedarray = sortedarray_new(0, equ_int, cmp_int); + assert(sortedarray != NULL); + sortedarray_free(sortedarray); + + /* freeing null */ + sortedarray_free(NULL); + + /* low memory */ + alloc_test_set_limit(0); + sortedarray = sortedarray_new(0, equ_int, cmp_int); + assert(sortedarray == NULL); + + alloc_test_set_limit(-1); +} + +void test_sortedarray_insert(void) +{ + SortedArray *sortedarray = generate_sortedarray(); + unsigned int i; + + /* insert a few random numbers, then check if everything is sorted */ + for (i = 0; i < 20; i++) { + int i = (int) (((float) rand())/((float) RAND_MAX) * 100); + int *pi = malloc(sizeof(int)); + *pi = i; + sortedarray_insert(sortedarray, pi); + } + + check_sorted_prop(sortedarray); + free_sorted_ints(sortedarray); +} + +void test_sortedarray_remove(void) +{ + SortedArray *sortedarray = generate_sortedarray(); + + /* remove index 24 */ + int *ip25 = sortedarray->data[25]; + int i25 = *ip25; + free(sortedarray->data[24]); + sortedarray_remove(sortedarray, 24); + assert(*((int*) sortedarray->data[24]) == i25); + + check_sorted_prop(sortedarray); + free_sorted_ints(sortedarray); +} + +void test_sortedarray_remove_range(void) +{ + SortedArray *sortedarray = generate_sortedarray(); + + /* remove 66 -> 70 */ + int i70 = *((int*) sortedarray->data[70]); + int i71 = *((int*) sortedarray->data[71]); + int i72 = *((int*) sortedarray->data[72]); + int i73 = *((int*) sortedarray->data[73]); + free(sortedarray->data[66]); + free(sortedarray->data[67]); + free(sortedarray->data[68]); + free(sortedarray->data[69]); + sortedarray_remove_range(sortedarray, 66, 4); + assert(*((int*) sortedarray->data[66]) == i70); + assert(*((int*) sortedarray->data[67]) == i71); + assert(*((int*) sortedarray->data[68]) == i72); + assert(*((int*) sortedarray->data[69]) == i73); + + check_sorted_prop(sortedarray); + free_sorted_ints(sortedarray); +} + +void test_sortedarray_index_of(void) +{ + SortedArray *sortedarray = generate_sortedarray(); + unsigned int i; + + /* insert 10 values with different fractional part */ + int base = (int) ((((float) rand())/((float) RAND_MAX)) * 100); + for (i = 0; i < 10; i++) { + int i = base + (int) (((float) rand())/((float) RAND_MAX)); + int *ip = malloc(sizeof(int)); + *ip = i; + sortedarray_insert(sortedarray, ip); + } + + /* find starting index */ + unsigned int start = 0; + for (i = 0; i < sortedarray->length; i++) { + if ((int) *((int*) sortedarray->data[i]) == base) { + start = i; + break; + } + } + + /* search for 5th number */ + int index = sortedarray_index_of(sortedarray, sortedarray->data[start + 5]); + int number = *((int*) sortedarray->data[index]); + int searched = *((int*) sortedarray->data[start + 5]); + assert(index == (int) start + 5 || number == searched); + + free_sorted_ints(sortedarray); +} + +static UnitTestFunction tests[] = { + test_sortedarray_new_free, + test_sortedarray_insert, + test_sortedarray_remove, + test_sortedarray_remove_range, + test_sortedarray_index_of, + NULL +}; + +int main(int argc, char *argv[]) +{ + run_tests(tests); + + return 0; +} From 49fb9b35744b7034f5f8d40a32895b3dfabc554b Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Sun, 10 Apr 2016 22:00:47 +0200 Subject: [PATCH 154/250] Improved documentation. --- src/sortedarray.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sortedarray.h b/src/sortedarray.h index 7c2bd41..5032dab 100644 --- a/src/sortedarray.h +++ b/src/sortedarray.h @@ -23,7 +23,11 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @brief Automatically sorted and resizing array * - * SortedArrays are encapsulated ArrayLists which are sorted. + * An SortedArray is an automatically resizing sorted array. Most operations + * run O(n) worst case running time. Some operations run in O(log n). + * + * To retrieve a value use the sortedarray structure by accessing the data + * field. * * To create a SortedArray, use @ref sortedarray_new * To destroy a SortedArray, use @ref sortedarray_free From 65b0017f049faf6b92ca6a9866cb9c57e88f23c4 Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Mon, 11 Apr 2016 15:36:13 +0200 Subject: [PATCH 155/250] Added sortedarray to libcalg.h --- src/libcalg.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcalg.h b/src/libcalg.h index 59d8926..62a5ede 100644 --- a/src/libcalg.h +++ b/src/libcalg.h @@ -41,6 +41,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #endif /* #ifndef LIBCALG_H */ From d48c382fe5643c04c873270f503748701ca9a4d3 Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Thu, 14 Apr 2016 12:35:25 +0200 Subject: [PATCH 156/250] Added NULL input check. --- src/sortedarray.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sortedarray.c b/src/sortedarray.c index fcd4aa6..1e878cb 100644 --- a/src/sortedarray.c +++ b/src/sortedarray.c @@ -218,6 +218,10 @@ int sortedarray_insert(SortedArray *sortedarray, SortedArrayValue data) int sortedarray_index_of(SortedArray *sortedarray, SortedArrayValue data) { + if (sortedarray == NULL) { + return -1; + } + /* do a binary search */ unsigned int left = 0; unsigned int right = sortedarray->length; From e175ec045bac92375dafe4315936689a9cfee3ae Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Fri, 15 Apr 2016 21:27:43 +0200 Subject: [PATCH 157/250] Restructured tests. Solved discovered bugs. Tests are now on fixed test set. --- src/sortedarray.c | 8 +- test/test-sortedarray.c | 162 ++++++++++++++++------------------------ 2 files changed, 68 insertions(+), 102 deletions(-) diff --git a/src/sortedarray.c b/src/sortedarray.c index 1e878cb..977e2e4 100644 --- a/src/sortedarray.c +++ b/src/sortedarray.c @@ -40,7 +40,7 @@ static unsigned int sortedarray_first_index(SortedArray *sortedarray, SortedArrayValue data, unsigned int left, unsigned int right) { - unsigned int index = 0; + unsigned int index = left; while (left < right) { index = (left + right) / 2; @@ -64,7 +64,7 @@ static unsigned int sortedarray_last_index(SortedArray *sortedarray, SortedArrayValue data, unsigned int left, unsigned int right) { - unsigned int index = 0; + unsigned int index = right; while (left < right) { index = (left + right) / 2; @@ -79,10 +79,10 @@ static unsigned int sortedarray_last_index(SortedArray *sortedarray, } } - return (index > 0) ? index - 1 : 0; + return index; } - SortedArray *sortedarray_new(unsigned int length, +SortedArray *sortedarray_new(unsigned int length, SortedArrayEqualFunc equ_func, SortedArrayCompareFunc cmp_func) { diff --git a/test/test-sortedarray.c b/test/test-sortedarray.c index 7912fdd..1d028e7 100644 --- a/test/test-sortedarray.c +++ b/test/test-sortedarray.c @@ -26,61 +26,21 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "alloc-testing.h" #include "framework.h" +#include "compare-int.h" #include "sortedarray.h" -#define TEST_SIZE 100 - -static int cmp_int(SortedArrayValue v1, SortedArrayValue v2) -{ - int *i1 = (int*) v1; - int *i2 = (int*) v2; - - if (i1 == i2) { - return 0; - } - - if (i1 == NULL || i2 == NULL) { - return (i1 == NULL) ? 1 : -1; - } - - /* discard last 2 digits, for testing difference between elements with - same order but which are not equal. See index_of */ - int a = (*i1)/10; - int b = (*i2)/10; - - int r = 0; - - if (a == b) { - r = 0; - } - else { - r = (a > b) ? 1 : -1; - } - - return r; -} - -static int equ_int(SortedArrayValue v1, SortedArrayValue v2) -{ - int *i1 = (int*) v1; - int *i2 = (int*) v2; - - if (i1 == i2) { - return 1; - } - - if (i1 == NULL || i2 == NULL) { - return 0; - } - - return *i1 == *i2; -} +#define TEST_SIZE 20 +#define TEST_ARRAY {10, 12, 12, 1, 2, 3, 6, 7, 2, 23, 13, 23, 23, 34, 31, 9,\ + 21, -2, -12, -4} +#define TEST_REMOVE_EL 15 +#define TEST_REMOVE_RANGE 7 +#define TEST_REMOVE_RANGE_LENGTH 4 void check_sorted_prop(SortedArray *sortedarray) { unsigned int i; for (i = 1; i < sortedarray->length; i++) { - assert(cmp_int( + assert(int_compare( sortedarray->data[i - 1], sortedarray->data[i]) <= 0); } @@ -104,17 +64,13 @@ SortedArray *generate_sortedarray(void) SortedArray *sortedarray; unsigned int i; - sortedarray = sortedarray_new(0, equ_int, cmp_int); + int array[TEST_SIZE] = TEST_ARRAY; - /* set random seed */ - srand((unsigned int) time(NULL)); + sortedarray = sortedarray_new(0, int_equal, int_compare); - /* fill with random numbers */ for (i = 0; i < TEST_SIZE; ++i) { - int r = rand(); - r = (int) (((float) r)/((float) RAND_MAX) * 100); int *pi = malloc(sizeof(int)); - *pi = r; + *pi = array[i]; sortedarray_insert(sortedarray, pi); } @@ -126,7 +82,7 @@ void test_sortedarray_new_free(void) SortedArray *sortedarray; /* test normal */ - sortedarray = sortedarray_new(0, equ_int, cmp_int); + sortedarray = sortedarray_new(0, int_equal, int_compare); assert(sortedarray != NULL); sortedarray_free(sortedarray); @@ -135,7 +91,7 @@ void test_sortedarray_new_free(void) /* low memory */ alloc_test_set_limit(0); - sortedarray = sortedarray_new(0, equ_int, cmp_int); + sortedarray = sortedarray_new(0, int_equal, int_compare); assert(sortedarray == NULL); alloc_test_set_limit(-1); @@ -163,11 +119,11 @@ void test_sortedarray_remove(void) SortedArray *sortedarray = generate_sortedarray(); /* remove index 24 */ - int *ip25 = sortedarray->data[25]; - int i25 = *ip25; - free(sortedarray->data[24]); - sortedarray_remove(sortedarray, 24); - assert(*((int*) sortedarray->data[24]) == i25); + int *ip = sortedarray->data[TEST_REMOVE_EL + 1]; + int i = *ip; + free(sortedarray->data[TEST_REMOVE_EL]); + sortedarray_remove(sortedarray, TEST_REMOVE_EL); + assert(*((int*) sortedarray->data[TEST_REMOVE_EL]) == i); check_sorted_prop(sortedarray); free_sorted_ints(sortedarray); @@ -177,54 +133,63 @@ void test_sortedarray_remove_range(void) { SortedArray *sortedarray = generate_sortedarray(); - /* remove 66 -> 70 */ - int i70 = *((int*) sortedarray->data[70]); - int i71 = *((int*) sortedarray->data[71]); - int i72 = *((int*) sortedarray->data[72]); - int i73 = *((int*) sortedarray->data[73]); - free(sortedarray->data[66]); - free(sortedarray->data[67]); - free(sortedarray->data[68]); - free(sortedarray->data[69]); - sortedarray_remove_range(sortedarray, 66, 4); - assert(*((int*) sortedarray->data[66]) == i70); - assert(*((int*) sortedarray->data[67]) == i71); - assert(*((int*) sortedarray->data[68]) == i72); - assert(*((int*) sortedarray->data[69]) == i73); + /* get values in test range */ + int new[TEST_REMOVE_RANGE_LENGTH]; + int i; + for (i = 0; i < TEST_REMOVE_RANGE_LENGTH; i++) { + new[i] = *((int*) sortedarray->data[TEST_REMOVE_RANGE + TEST_REMOVE_RANGE_LENGTH + i]); + } + + /* free removed elements */ + for (i = 0; i < TEST_REMOVE_RANGE_LENGTH; i++) { + free(sortedarray->data[TEST_REMOVE_RANGE + i]); + } + + /* remove */ + sortedarray_remove_range(sortedarray, TEST_REMOVE_RANGE, + TEST_REMOVE_RANGE_LENGTH); + + /* assert */ + for (i = 0; i < TEST_REMOVE_RANGE_LENGTH; i++) { + assert(*((int*) sortedarray->data[TEST_REMOVE_RANGE + i]) == new[i]); + } check_sorted_prop(sortedarray); free_sorted_ints(sortedarray); } -void test_sortedarray_index_of(void) +void test_sortedarray_index_of(void) { + SortedArray *sortedarray = generate_sortedarray(); + + int i; + for (i = 0; i < TEST_SIZE; i++) { + int r = sortedarray_index_of(sortedarray, sortedarray->data[i]); + assert(r >= 0); + assert(*((int*) sortedarray->data[r]) == *((int*) sortedarray->data[i])); + } + + free_sorted_ints(sortedarray); +} + +static int ptr_equal(SortedArrayValue v1, SortedArrayValue v2) { + return v1 == v2; +} + +void test_sortedarray_index_of_equ_key(void) { SortedArray *sortedarray = generate_sortedarray(); unsigned int i; - /* insert 10 values with different fractional part */ - int base = (int) ((((float) rand())/((float) RAND_MAX)) * 100); - for (i = 0; i < 10; i++) { - int i = base + (int) (((float) rand())/((float) RAND_MAX)); - int *ip = malloc(sizeof(int)); - *ip = i; - sortedarray_insert(sortedarray, ip); - } + /* replace equal function by function which checks pointers */ + sortedarray->equ_func = ptr_equal; - /* find starting index */ - unsigned int start = 0; - for (i = 0; i < sortedarray->length; i++) { - if ((int) *((int*) sortedarray->data[i]) == base) { - start = i; - break; - } + /* check if all search value return the same index */ + for (i = 0; i < TEST_SIZE; i++) { + int r = sortedarray_index_of(sortedarray, sortedarray->data[i]); + assert(r >= 0); + assert(i == r); } - /* search for 5th number */ - int index = sortedarray_index_of(sortedarray, sortedarray->data[start + 5]); - int number = *((int*) sortedarray->data[index]); - int searched = *((int*) sortedarray->data[start + 5]); - assert(index == (int) start + 5 || number == searched); - free_sorted_ints(sortedarray); } @@ -234,6 +199,7 @@ static UnitTestFunction tests[] = { test_sortedarray_remove, test_sortedarray_remove_range, test_sortedarray_index_of, + test_sortedarray_index_of_equ_key, NULL }; From 123ef5fdd0a1202ed02de5d7f311d51849515cc1 Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Sat, 16 Apr 2016 12:15:24 +0200 Subject: [PATCH 158/250] Added Macro to retrieve elements. --- src/sortedarray.h | 13 +++++++++++++ test/test-sortedarray.c | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/sortedarray.h b/src/sortedarray.h index 5032dab..2687816 100644 --- a/src/sortedarray.h +++ b/src/sortedarray.h @@ -120,6 +120,19 @@ struct _SortedArray { SortedArrayCompareFunc cmp_func; }; +/** + * @brief Macro to retrieve an element of type T at index I from sortedarray A. + * + * @param A Type: SortedArray*. The sortedarray to retrieve the + * element from. + * @param T The type of the element to retrieve. + * @param I Type: unsigned int. The index to retrieve from. + * @return The element of type T at index I of array A. If A is NULL + * then NULL is returned. + */ +#define SORTEDARRAY_GET(A, T, I) (((SortedArray*) A) != NULL ? \ + ((T) (((SortedArray*) A)->data[(unsigned int) I])) : NULL) + /** * Allocate a new SortedArray for use. * diff --git a/test/test-sortedarray.c b/test/test-sortedarray.c index 1d028e7..476299f 100644 --- a/test/test-sortedarray.c +++ b/test/test-sortedarray.c @@ -178,7 +178,7 @@ static int ptr_equal(SortedArrayValue v1, SortedArrayValue v2) { void test_sortedarray_index_of_equ_key(void) { SortedArray *sortedarray = generate_sortedarray(); - unsigned int i; + int i; /* replace equal function by function which checks pointers */ sortedarray->equ_func = ptr_equal; @@ -193,6 +193,19 @@ void test_sortedarray_index_of_equ_key(void) free_sorted_ints(sortedarray); } +void test_sortedarray_get(void) { + unsigned int i; + + SortedArray *arr = generate_sortedarray(); + + for (i = 0; i < arr->length; i++) { + assert(arr->data[i] == SORTEDARRAY_GET(arr, SortedArrayValue, i)); + assert(*((int*) arr->data[i]) == *SORTEDARRAY_GET(arr, int*, i)); + } + + free_sorted_ints(arr); +} + static UnitTestFunction tests[] = { test_sortedarray_new_free, test_sortedarray_insert, @@ -200,6 +213,7 @@ static UnitTestFunction tests[] = { test_sortedarray_remove_range, test_sortedarray_index_of, test_sortedarray_index_of_equ_key, + test_sortedarray_get, NULL }; From d826f8f4bbafdcc4e63b269f5b73055704e1b16d Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Mon, 6 Jun 2016 14:10:41 +0200 Subject: [PATCH 159/250] Moved SortedArray struct to .c file so it is hidden. --- src/sortedarray.c | 48 +++++++++++++++++++++++++++++++ src/sortedarray.h | 50 +++++++------------------------- test/test-sortedarray.c | 63 +++++++++++++++++++++++------------------ 3 files changed, 95 insertions(+), 66 deletions(-) diff --git a/src/sortedarray.c b/src/sortedarray.c index 977e2e4..40f2530 100644 --- a/src/sortedarray.c +++ b/src/sortedarray.c @@ -34,6 +34,38 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "alloc-testing.h" #endif +/** + * Definition of a @ref SortedArray + */ +struct _SortedArray { + /** + * This field contains the actual array. The array always has a length + * of value of field length. + */ + SortedArrayValue *data; + + /** + * The length of the sorted array. + */ + unsigned int length; + + /** + * Field for internal usage only indicating how much memory already has + * been allocated for *data. + */ + unsigned int _alloced; + + /** + * The callback used to determine if two values equal. + */ + SortedArrayEqualFunc equ_func; + + /** + * The callback use to determine the order of two values. + */ + SortedArrayCompareFunc cmp_func; +}; + /* Function for finding first index of range which equals data. An equal value must be present. */ static unsigned int sortedarray_first_index(SortedArray *sortedarray, @@ -82,6 +114,22 @@ static unsigned int sortedarray_last_index(SortedArray *sortedarray, return index; } +SortedArrayValue *sortedarray_get(SortedArray *array, unsigned int i) +{ + //check if array is NULL + if (array == NULL) { + return NULL; + } + + //otherwise just return the element + return array->data[i]; +} + +unsigned int sortedarray_length(SortedArray *array) +{ + return array->length; +} + SortedArray *sortedarray_new(unsigned int length, SortedArrayEqualFunc equ_func, SortedArrayCompareFunc cmp_func) diff --git a/src/sortedarray.h b/src/sortedarray.h index 2687816..daee929 100644 --- a/src/sortedarray.h +++ b/src/sortedarray.h @@ -89,49 +89,21 @@ typedef int (*SortedArrayCompareFunc)(SortedArrayValue value1, SortedArrayValue value2); /** - * Definition of a @ref SortedArray + * @brief Function to retrieve element at index i from array + * + * @param array The pointer to the sortedarray to retrieve the element from. + * @param i The index of the element to retrieve. + * @return The i-th element of the array, or NULL if array was NULL. */ -struct _SortedArray { - /** - * This field contains the actual array. The array always has a length - * of value of field length. - */ - SortedArrayValue *data; - - /** - * The length of the sorted array. - */ - unsigned int length; - - /** - * Field for internal usage only indicating how much memory already has - * been allocated for *data. - */ - unsigned int _alloced; - - /** - * The callback used to determine if two values equal. - */ - SortedArrayEqualFunc equ_func; - - /** - * The callback use to determine the order of two values. - */ - SortedArrayCompareFunc cmp_func; -}; +SortedArrayValue *sortedarray_get(SortedArray *array, unsigned int i); /** - * @brief Macro to retrieve an element of type T at index I from sortedarray A. - * - * @param A Type: SortedArray*. The sortedarray to retrieve the - * element from. - * @param T The type of the element to retrieve. - * @param I Type: unsigned int. The index to retrieve from. - * @return The element of type T at index I of array A. If A is NULL - * then NULL is returned. + * @brief Function to retrieve the length of the SortedArray array. + * + * @param array The array to retrieve the length from. + * @return The lenght of the SortedArray. */ -#define SORTEDARRAY_GET(A, T, I) (((SortedArray*) A) != NULL ? \ - ((T) (((SortedArray*) A)->data[(unsigned int) I])) : NULL) +unsigned int sortedarray_length(SortedArray *array); /** * Allocate a new SortedArray for use. diff --git a/test/test-sortedarray.c b/test/test-sortedarray.c index 476299f..4af82e6 100644 --- a/test/test-sortedarray.c +++ b/test/test-sortedarray.c @@ -15,7 +15,7 @@ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +) */ #include @@ -39,25 +39,25 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. void check_sorted_prop(SortedArray *sortedarray) { unsigned int i; - for (i = 1; i < sortedarray->length; i++) { + for (i = 1; i < sortedarray_length(sortedarray); i++) { assert(int_compare( - sortedarray->data[i - 1], - sortedarray->data[i]) <= 0); + sortedarray_get(sortedarray, i-1), + sortedarray_get(sortedarray, i)) <= 0); } } void free_sorted_ints(SortedArray *sortedarray) { unsigned int i; - for (i = 0; i < sortedarray->length; i++) { - int *pi = sortedarray->data[i]; + for (i = 0; i < sortedarray_length(sortedarray); i++) { + int *pi = (int*) sortedarray_get(sortedarray, i); free(pi); } sortedarray_free(sortedarray); } -SortedArray *generate_sortedarray(void) +SortedArray *generate_sortedarray_equ(SortedArrayEqualFunc equ_func) { /* generate a sorted array of length TEST_SIZE, filled with random numbers. */ @@ -66,7 +66,7 @@ SortedArray *generate_sortedarray(void) int array[TEST_SIZE] = TEST_ARRAY; - sortedarray = sortedarray_new(0, int_equal, int_compare); + sortedarray = sortedarray_new(0, equ_func, int_compare); for (i = 0; i < TEST_SIZE; ++i) { int *pi = malloc(sizeof(int)); @@ -77,6 +77,11 @@ SortedArray *generate_sortedarray(void) return sortedarray; } +SortedArray *generate_sortedarray(void) +{ + return generate_sortedarray_equ(int_equal); +} + void test_sortedarray_new_free(void) { SortedArray *sortedarray; @@ -119,11 +124,11 @@ void test_sortedarray_remove(void) SortedArray *sortedarray = generate_sortedarray(); /* remove index 24 */ - int *ip = sortedarray->data[TEST_REMOVE_EL + 1]; + int *ip = (int*) sortedarray_get(sortedarray, TEST_REMOVE_EL + 1); int i = *ip; - free(sortedarray->data[TEST_REMOVE_EL]); + free((int*) sortedarray_get(sortedarray, TEST_REMOVE_EL)); sortedarray_remove(sortedarray, TEST_REMOVE_EL); - assert(*((int*) sortedarray->data[TEST_REMOVE_EL]) == i); + assert(*((int*) sortedarray_get(sortedarray, TEST_REMOVE_EL)) == i); check_sorted_prop(sortedarray); free_sorted_ints(sortedarray); @@ -135,14 +140,15 @@ void test_sortedarray_remove_range(void) /* get values in test range */ int new[TEST_REMOVE_RANGE_LENGTH]; - int i; + unsigned int i; for (i = 0; i < TEST_REMOVE_RANGE_LENGTH; i++) { - new[i] = *((int*) sortedarray->data[TEST_REMOVE_RANGE + TEST_REMOVE_RANGE_LENGTH + i]); + new[i] = *((int*) sortedarray_get(sortedarray, TEST_REMOVE_RANGE + + TEST_REMOVE_RANGE_LENGTH + i)); } /* free removed elements */ for (i = 0; i < TEST_REMOVE_RANGE_LENGTH; i++) { - free(sortedarray->data[TEST_REMOVE_RANGE + i]); + free((int*) sortedarray_get(sortedarray, TEST_REMOVE_RANGE + i)); } /* remove */ @@ -151,7 +157,8 @@ void test_sortedarray_remove_range(void) /* assert */ for (i = 0; i < TEST_REMOVE_RANGE_LENGTH; i++) { - assert(*((int*) sortedarray->data[TEST_REMOVE_RANGE + i]) == new[i]); + assert(*((int*) sortedarray_get(sortedarray, TEST_REMOVE_RANGE + i)) == + new[i]); } check_sorted_prop(sortedarray); @@ -161,11 +168,13 @@ void test_sortedarray_remove_range(void) void test_sortedarray_index_of(void) { SortedArray *sortedarray = generate_sortedarray(); - int i; + unsigned int i; for (i = 0; i < TEST_SIZE; i++) { - int r = sortedarray_index_of(sortedarray, sortedarray->data[i]); + int r = sortedarray_index_of(sortedarray, + sortedarray_get(sortedarray, i)); assert(r >= 0); - assert(*((int*) sortedarray->data[r]) == *((int*) sortedarray->data[i])); + assert(*((int*) sortedarray_get(sortedarray,(unsigned int) r)) == + *((int*) sortedarray_get(sortedarray, i))); } free_sorted_ints(sortedarray); @@ -177,17 +186,16 @@ static int ptr_equal(SortedArrayValue v1, SortedArrayValue v2) { void test_sortedarray_index_of_equ_key(void) { - SortedArray *sortedarray = generate_sortedarray(); - int i; - /* replace equal function by function which checks pointers */ - sortedarray->equ_func = ptr_equal; + SortedArray *sortedarray = generate_sortedarray_equ(ptr_equal); + unsigned int i; /* check if all search value return the same index */ for (i = 0; i < TEST_SIZE; i++) { - int r = sortedarray_index_of(sortedarray, sortedarray->data[i]); + int r = sortedarray_index_of(sortedarray, + sortedarray_get(sortedarray, i)); assert(r >= 0); - assert(i == r); + assert(i == (unsigned int) r); } free_sorted_ints(sortedarray); @@ -198,9 +206,10 @@ void test_sortedarray_get(void) { SortedArray *arr = generate_sortedarray(); - for (i = 0; i < arr->length; i++) { - assert(arr->data[i] == SORTEDARRAY_GET(arr, SortedArrayValue, i)); - assert(*((int*) arr->data[i]) == *SORTEDARRAY_GET(arr, int*, i)); + for (i = 0; i < sortedarray_length(arr); i++) { + assert(sortedarray_get(arr, i) == sortedarray_get(arr, i)); + assert(*((int*) sortedarray_get(arr, i)) == + *((int*) sortedarray_get(arr, i))); } free_sorted_ints(arr); From 34512064ef3e01c0e1b86893639bdca4eaa3ba79 Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Mon, 6 Jun 2016 15:14:09 +0200 Subject: [PATCH 160/250] Put else on same line as } --- src/sortedarray.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/sortedarray.c b/src/sortedarray.c index 40f2530..c50c22b 100644 --- a/src/sortedarray.c +++ b/src/sortedarray.c @@ -81,8 +81,7 @@ static unsigned int sortedarray_first_index(SortedArray *sortedarray, sortedarray->data[index]); if (order > 0) { left = index + 1; - } - else { + } else { right = index; } } @@ -105,8 +104,7 @@ static unsigned int sortedarray_last_index(SortedArray *sortedarray, sortedarray->data[index]); if (order <= 0) { left = index + 1; - } - else { + } else { right = index; } } @@ -218,19 +216,18 @@ int sortedarray_insert(SortedArray *sortedarray, SortedArrayValue data) if (order < 0) { /* value should be left of index */ right = index; - } - else if (order > 0) { + } else if (order > 0) { /* value should be right of index */ left = index + 1; - } - else { + } else { /* value should be at index */ left = right = index; break; } } - if (sortedarray->length > 0 && sortedarray->cmp_func(data, sortedarray->data[index]) > 0) { + if (sortedarray->length > 0 && sortedarray->cmp_func(data, + sortedarray->data[index]) > 0) { index++; } @@ -245,8 +242,7 @@ int sortedarray_insert(SortedArray *sortedarray, SortedArrayValue data) if (data == NULL) { return 0; - } - else { + } else { sortedarray->data = data; sortedarray->_alloced = newsize; } @@ -286,12 +282,10 @@ int sortedarray_index_of(SortedArray *sortedarray, SortedArrayValue data) if (order < 0) { /* value should be left */ right = index; - } - else if (order > 0) { + } else if (order > 0) { /* value should be right */ left = index + 1; - } - else { + } else { /* no binary search can be done anymore, search linear now */ left = sortedarray_first_index(sortedarray, data, left, From daba8a5e7ad17a49c59fc8355fb674aa1ff0d146 Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Mon, 6 Jun 2016 15:19:43 +0200 Subject: [PATCH 161/250] Added some comments --- src/sortedarray.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sortedarray.c b/src/sortedarray.c index c50c22b..d94fe8a 100644 --- a/src/sortedarray.c +++ b/src/sortedarray.c @@ -206,6 +206,7 @@ int sortedarray_insert(SortedArray *sortedarray, SortedArrayValue data) unsigned int right = sortedarray->length; unsigned int index = 0; + /* When length is 1 set right to 0 so that the loop is not entered */ right = (right > 1) ? right : 0; while (left != right) { @@ -221,17 +222,17 @@ int sortedarray_insert(SortedArray *sortedarray, SortedArrayValue data) left = index + 1; } else { /* value should be at index */ - left = right = index; break; } } + /* look whether the item should be put before or after the index */ if (sortedarray->length > 0 && sortedarray->cmp_func(data, sortedarray->data[index]) > 0) { index++; } - /* insert element at r */ + /* insert element at index */ if (sortedarray->length + 1 > sortedarray->_alloced) { /* enlarge the array */ unsigned int newsize; From c1b6e26836eb26b0d35b4ff8af64c4be4d5aa183 Mon Sep 17 00:00:00 2001 From: Waldir Pimenta Date: Thu, 30 Jun 2016 08:22:01 +0100 Subject: [PATCH 162/250] Add license title It's not strictly required, but it's useful metadata, and part of the recommended license template text (see http://choosealicense.com/licenses/isc/ and https://opensource.org/licenses/isc-license) --- COPYING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYING b/COPYING index 5136703..e9d8aed 100644 --- a/COPYING +++ b/COPYING @@ -1,3 +1,4 @@ +ISC License Copyright (c) 2005-2008, Simon Howard @@ -14,4 +15,3 @@ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - From d73005ae6d1b0bdb5969b2421cf98d5b213d81f6 Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Tue, 12 Jul 2016 12:14:27 +0200 Subject: [PATCH 163/250] Added functions to modify the data at an entry. --- src/list.c | 8 ++++++++ src/list.h | 10 ++++++++++ src/slist.c | 7 +++++++ src/slist.h | 9 +++++++++ 4 files changed, 34 insertions(+) diff --git a/src/list.c b/src/list.c index c8f407b..19fdbe8 100644 --- a/src/list.c +++ b/src/list.c @@ -142,6 +142,14 @@ ListValue list_data(ListEntry *listentry) return listentry->data; } +void list_set(ListEntry *listentry, ListValue value) +{ + if (listentry != NULL) { + listentry->data = value; + } +} + + ListEntry *list_prev(ListEntry *listentry) { if (listentry == NULL) { diff --git a/src/list.h b/src/list.h index 88796ff..5d0548d 100644 --- a/src/list.h +++ b/src/list.h @@ -46,6 +46,8 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * To access an entry in the list by index, use @ref list_nth_entry or * @ref list_nth_data. * + * To modify data in the list use @ref list_set. + * * To sort a list, use @ref list_sort. * */ @@ -176,6 +178,14 @@ ListEntry *list_next(ListEntry *listentry); ListValue list_data(ListEntry *listentry); +/** + * Set the value at a list entry. If listentry is NULL nothing is done. + * + * @param listentry Pointer to the list entry. + * @param value The value to set. + */ +void list_set(ListEntry *listentry, ListValue value); + /** * Retrieve the entry at a specified index in a list. * diff --git a/src/slist.c b/src/slist.c index fa81d3a..32a4921 100644 --- a/src/slist.c +++ b/src/slist.c @@ -120,6 +120,13 @@ SListValue slist_data(SListEntry *listentry) return listentry->data; } +void slist_set(SListEntry *listentry, SListValue data) +{ + if (listentry != NULL) { + listentry->data = data; + } +} + SListEntry *slist_next(SListEntry *listentry) { return listentry->next; diff --git a/src/slist.h b/src/slist.h index ee22811..305ba7b 100644 --- a/src/slist.h +++ b/src/slist.h @@ -59,6 +59,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @li To find the next entry, use @ref slist_next. * @li To access the value stored at the entry, use @ref slist_data. + * @li To set the value stored at the entry, use @ref slist_set. * @li To remove the entry, use @ref slist_remove_entry. * */ @@ -174,6 +175,14 @@ SListEntry *slist_next(SListEntry *listentry); SListValue slist_data(SListEntry *listentry); +/** + * Set the value at a list entry. If listentry is NULL nothing is done. + * + * @param listentry Pointer to the list entry. + * @param value The value to set. + */ +void slist_set(SListEntry *listentry, SListValue value); + /** * Retrieve the entry at a specified index in a list. * From 68f3a2d431ecfdc49a9c34eaa4f26f49d77b409a Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Tue, 12 Jul 2016 17:33:47 +0200 Subject: [PATCH 164/250] Minor refactoring of names and comments. --- src/list.c | 3 +-- src/list.h | 5 +++-- src/slist.c | 2 +- src/slist.h | 5 +++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/list.c b/src/list.c index 19fdbe8..7329512 100644 --- a/src/list.c +++ b/src/list.c @@ -142,14 +142,13 @@ ListValue list_data(ListEntry *listentry) return listentry->data; } -void list_set(ListEntry *listentry, ListValue value) +void list_set_data(ListEntry *listentry, ListValue value) { if (listentry != NULL) { listentry->data = value; } } - ListEntry *list_prev(ListEntry *listentry) { if (listentry == NULL) { diff --git a/src/list.h b/src/list.h index 5d0548d..d9f2317 100644 --- a/src/list.h +++ b/src/list.h @@ -179,12 +179,13 @@ ListEntry *list_next(ListEntry *listentry); ListValue list_data(ListEntry *listentry); /** - * Set the value at a list entry. If listentry is NULL nothing is done. + * Set the value at a list entry. The value provided will be written to the + * given listentry. If listentry is NULL nothing is done. * * @param listentry Pointer to the list entry. * @param value The value to set. */ -void list_set(ListEntry *listentry, ListValue value); +void list_set_data(ListEntry *listentry, ListValue value); /** * Retrieve the entry at a specified index in a list. diff --git a/src/slist.c b/src/slist.c index 32a4921..3478008 100644 --- a/src/slist.c +++ b/src/slist.c @@ -120,7 +120,7 @@ SListValue slist_data(SListEntry *listentry) return listentry->data; } -void slist_set(SListEntry *listentry, SListValue data) +void slist_set_data(SListEntry *listentry, SListValue data) { if (listentry != NULL) { listentry->data = data; diff --git a/src/slist.h b/src/slist.h index 305ba7b..5a26fa9 100644 --- a/src/slist.h +++ b/src/slist.h @@ -176,12 +176,13 @@ SListEntry *slist_next(SListEntry *listentry); SListValue slist_data(SListEntry *listentry); /** - * Set the value at a list entry. If listentry is NULL nothing is done. + * Set the value at a list entry. The value provided will be written to the + * given listentry. If listentry is NULL nothing is done. * * @param listentry Pointer to the list entry. * @param value The value to set. */ -void slist_set(SListEntry *listentry, SListValue value); +void slist_set_data(SListEntry *listentry, SListValue value); /** * Retrieve the entry at a specified index in a list. From 9e55ed3ac221c7be576141f5ec570aebe651e15b Mon Sep 17 00:00:00 2001 From: Stefan Cloudt Date: Thu, 14 Jul 2016 18:30:30 +0200 Subject: [PATCH 165/250] Fixed comments. --- src/list.h | 2 +- src/slist.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/list.h b/src/list.h index d9f2317..c5b1f62 100644 --- a/src/list.h +++ b/src/list.h @@ -46,7 +46,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * To access an entry in the list by index, use @ref list_nth_entry or * @ref list_nth_data. * - * To modify data in the list use @ref list_set. + * To modify data in the list use @ref list_set_data. * * To sort a list, use @ref list_sort. * diff --git a/src/slist.h b/src/slist.h index 5a26fa9..a0525f5 100644 --- a/src/slist.h +++ b/src/slist.h @@ -59,7 +59,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * @li To find the next entry, use @ref slist_next. * @li To access the value stored at the entry, use @ref slist_data. - * @li To set the value stored at the entry, use @ref slist_set. + * @li To set the value stored at the entry, use @ref slist_set_data. * @li To remove the entry, use @ref slist_remove_entry. * */ From 057dfb055a00b3c22b1bb1d026345603def39503 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 14 Oct 2019 12:29:03 -0400 Subject: [PATCH 166/250] Add CONTRIBUTING.md Sad but necessary. --- .github/CONTRIBUTING.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/CONTRIBUTING.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..32ae4a2 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,7 @@ +Because of spam, an automated bot will automatically close all pull requests +opened on this repository. If you've found a legitimate bug in the source code, +you can open an issue to report it. + +This project isn't a dumping ground for random bits of C code you've written. +That goes double if you're being instructed to send pull requests as part of a +competition or a school class. From 17cd712ef84948ce5c3faae911bc797ebad26e09 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 1 Oct 2020 10:24:52 -0400 Subject: [PATCH 167/250] Create pull_request_template.md --- .github/pull_request_template.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ef4d389 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,9 @@ +DO NOT SUBMIT PULL REQUESTS HERE. + +Because of spam, an automated bot will automatically close all pull requests +opened on this repository. If you've found a legitimate bug in the source code, +you can open an issue to report it. + +This project isn't a dumping ground for random bits of C code you've written. +That goes double if you're being instructed to send pull requests as part of a +competition or a school class. From cecf615dc4f08a7f1de49add779ba63aedc7a436 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 13:58:26 -0500 Subject: [PATCH 168/250] Add continuous integration --- .github/workflows/make.yml | 57 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .github/workflows/make.yml diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml new file mode 100644 index 0000000..bb06e2c --- /dev/null +++ b/.github/workflows/make.yml @@ -0,0 +1,57 @@ +name: Continuous Integration + +on: [push, pull_request, workflow_dispatch] + +jobs: + build_and_coverage: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: configure + run: | + LDFLAGS="$CFLAGS" ./autogen.sh \ + --enable-coverage + - name: make + run: make -j + - name: make check + run: | + make -j check || (cat test/test-suite.log; false) + + valgrind_build: + runs-on: ubuntu-latest + + steps: + - name: Install dependencies + run: | + sudo apt update + sudo apt -q install valgrind + - uses: actions/checkout@v4 + - name: configure + run: | + LDFLAGS="$CFLAGS" ./autogen.sh \ + --enable-valgrind + - name: make + run: make -j + - name: make check + run: | + make -j check || (cat test/test-suite.log; false) + + ubsan_build: + runs-on: ubuntu-latest + env: + CC: clang + # TODO: Add -fsanitize=address and memory too. + CFLAGS: "-fsanitize=undefined + -fno-omit-frame-pointer + -fno-sanitize-recover=all + -fno-sanitize=shift-base" + + steps: + - uses: actions/checkout@v4 + - name: configure + run: | + LDFLAGS="$CFLAGS" ./autogen.sh + - name: make check + run: | + make -j check || (cat test/test-suite.log; false) From 405002775fe38f5e8f175acf1377353f8c97d87b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 14:32:08 -0500 Subject: [PATCH 169/250] Fix valgrind runner --- test/Makefile.am | 2 +- test/valgrind-wrapper | 21 +-------------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index d01cd7d..75e7b8d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,7 +4,7 @@ AM_CXXFLAGS = $(AM_CFLAGS) LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a if USE_VALGRIND -TESTS_ENVIRONMENT=./valgrind-wrapper +LOG_COMPILER=./valgrind-wrapper endif TESTS = \ diff --git a/test/valgrind-wrapper b/test/valgrind-wrapper index 7b98324..ceac67a 100755 --- a/test/valgrind-wrapper +++ b/test/valgrind-wrapper @@ -18,23 +18,4 @@ # # Run in valgrind, with leak checking enabled - -valgrind -q --leak-check=full "$@" 2> .valgrind-log - -# Save the test result - -result="$?" - -# Valgrind should generate no error messages - -log_contents="`cat .valgrind-log`" - -if [ "x$log_contents" != "x" ]; then - cat .valgrind-log >&2 - result=1 -fi - -rm -f .valgrind-log - -exit $result - +exec valgrind -q --leak-check=full "$@" From b5d3185cc8c78285e42795b6f3141c9f5fb63e00 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 14:33:29 -0500 Subject: [PATCH 170/250] Add log files to gitignore --- test/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/.gitignore b/test/.gitignore index b93661d..5ecb50a 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -14,3 +14,5 @@ test-rb-tree test-set test-slist test-trie +*.log +*.trs From 3604df1d41c3786ea91e1b0965a78cb93858b40c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 14:39:50 -0500 Subject: [PATCH 171/250] Quiet make output, don't show whole command --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 6557ed9..3ac219d 100644 --- a/configure.ac +++ b/configure.ac @@ -2,6 +2,7 @@ AC_INIT(C Algorithms, 1.2.0, fraggle@removethisbit.gmail.com, c-algorithms) AC_CONFIG_AUX_DIR(autotools) AC_CONFIG_SRCDIR([src/arraylist.c]) AC_CONFIG_MACRO_DIR([m4]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AM_INIT_AUTOMAKE From feb48ccffb35f463e5b19660b093ecc4c09ccb26 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 15:19:23 -0500 Subject: [PATCH 172/250] Modernize configure.ac to resolve warnings This is the result of running `autoupdate`. --- configure.ac | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 3ac219d..61e8dec 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(C Algorithms, 1.2.0, fraggle@removethisbit.gmail.com, c-algorithms) +AC_INIT([C Algorithms],[1.2.0],[fraggle@removethisbit.gmail.com],[c-algorithms]) AC_CONFIG_AUX_DIR(autotools) AC_CONFIG_SRCDIR([src/arraylist.c]) AC_CONFIG_MACRO_DIR([m4]) @@ -9,7 +9,7 @@ AM_INIT_AUTOMAKE AC_PROG_CC AM_PROG_CC_C_O AC_PROG_CXX -AC_PROG_LIBTOOL +LT_INIT AC_PROG_INSTALL AC_PROG_MAKE_SET @@ -67,17 +67,18 @@ AM_CONDITIONAL(USE_VALGRIND, $use_valgrind) MAIN_CFLAGS="$CFLAGS" CFLAGS="" -AM_CONFIG_HEADER(config.h:config.h.in) +AC_CONFIG_HEADERS(config.h:config.h.in) AC_SUBST(MAIN_CFLAGS) AC_SUBST(TEST_CFLAGS) AC_SUBST(ac_aux_dir) -AC_OUTPUT([ +AC_CONFIG_FILES([ Makefile libcalg-1.0.pc doc/Makefile src/Makefile test/Makefile ]) +AC_OUTPUT From 6099acb6e8d43c5b8a59d4142c4d0aa35fc4be2e Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 15:53:05 -0500 Subject: [PATCH 173/250] Modernize coverage reports; add build target It's now possible to run `make report-coverage` from the `test/` directory to generate a summary of per-file coverage. This replaces the old `gencov` shellscript with the newer Python-based version that I wrote for Lhasa. --- configure.ac | 8 ++-- src/gencov | 13 ------ test/Makefile.am | 18 ++++++++ test/gencov | 114 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 16 deletions(-) delete mode 100755 src/gencov create mode 100755 test/gencov diff --git a/configure.ac b/configure.ac index 61e8dec..2c9c733 100644 --- a/configure.ac +++ b/configure.ac @@ -31,12 +31,14 @@ fi # Support for coverage analysis via gcov: -coverage=no +build_coverage=false AC_ARG_ENABLE(coverage, [ --enable-coverage Enable coverage testing. ], -[ coverage=yes ]) +[ build_coverage=true ]) -if [[ "$coverage" = "yes" ]]; then +AM_CONDITIONAL(BUILD_COVERAGE, $build_coverage) + +if [[ "$build_coverage" = "true" ]]; then if $is_gcc; then TEST_CFLAGS="$TEST_CFLAGS -fprofile-arcs -ftest-coverage" else diff --git a/src/gencov b/src/gencov deleted file mode 100755 index 5eb721f..0000000 --- a/src/gencov +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# -# Simple shell script to generate a coverage report. -# - -cd $(dirname $0) - -for d in *.c; do - obj=`echo $d | sed "s/^/libcalgtest_a-/" | sed "s/.c$/.o/"` - - gcov -b -o $obj $d -done - diff --git a/test/Makefile.am b/test/Makefile.am index 75e7b8d..a0a53a9 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -37,3 +37,21 @@ test_cpp_SOURCES = test-cpp.cpp EXTRA_DIST=valgrind-wrapper +if BUILD_COVERAGE + +# Delete .gcda files before running tests. +check-am: check-prerun + +check-prerun: + @rm -f $(top_builddir)/lib/*.gcda \ + $(top_builddir)/src/*.gcda \ + $(top_builddir)/test/*.gcda + +# Display coverage summary after running tests. +check: report-coverage + +report-coverage: check-am + @cd $(top_builddir); ./test/gencov src/*.c + +endif + diff --git a/test/gencov b/test/gencov new file mode 100755 index 0000000..21ca5b1 --- /dev/null +++ b/test/gencov @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2011, 2012, Simon Howard +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +from re import match +from os import rename, popen, getcwd, chdir +from os.path import exists, dirname, basename +from os.path import join as path_join +from glob import glob +import sys + +def parse_stats(text): + m = match(r"(.*)% of (.*)", text) + + pct = m.group(1) + lines = int(m.group(2)) + cov_lines = int(float(pct) * lines / 100 + 0.5) + uncov_lines = lines - cov_lines + + return (pct + "%", uncov_lines, cov_lines, lines) + + +def gcov(filename): + + # gcov must be run from within the same directory as the source + # file that we are analysing. + + old_wd = getcwd() + src_dir = dirname(filename) + chdir(src_dir) + s = popen("gcov %s" % basename(filename)) + chdir(old_wd) + + # Process output from gcov. + # This may cover multiple files when one .c file includes another. + + results = {} + filename = None + + # File 'lha_file_header.c' + # Lines executed:88.97% of 136 + + for line in s: + m = match(r"File '(.*)'", line) + if m: + filename = m.group(1) + + m = match(r"Lines executed:(.*)", line) + if m: + full_path = path_join(src_dir, filename) + results[full_path] = parse_stats(m.group(1)) + + s.close() + + return results + +def format_output(filename, stats): + print(" %-35s%7s%7s%7s%7s" % ((filename, ) + stats)) + +print() +format_output("Filename", ("Percent", "Uncov", "Cov", "Total")) +print(" " + ("-" * 65)) + +for filename in sorted(sys.argv[1:]): + gcno = filename.replace(".c", ".gcno") + gcda = filename.replace(".c", ".gcda") + + xgcno = glob(path_join(dirname(gcno), "*-" + basename(gcno))) + xgcda = glob(path_join(dirname(gcda), "*-" + basename(gcda))) + + # Must rename e.g. liblhasatest_a-foo.gcno to foo.gcno: + + if len(xgcno) > 0: + rename(xgcno[0], gcno) + + if len(xgcda) > 0: + rename(xgcda[0], gcda) + + if not exists(gcno) or not exists(gcda): + continue + + # Run gcov and parse output: + + results = gcov(filename) + + if len(results) > 0: + if filename in results: + format_output(filename, results[filename]) + else: + format_output(filename, ("", "", "", "")) + + for subfile in sorted(results.keys()): + if subfile.endswith(".h"): + continue + + if subfile != filename: + format_output(" -> " + subfile, results[subfile]) + +print() From c5995629241773e4e462a0c1e86ee4caa9fba05c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 15:56:43 -0500 Subject: [PATCH 174/250] Generate coverage reports zip in CI build. --- .github/workflows/make.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index bb06e2c..4cbb050 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -17,6 +17,15 @@ jobs: - name: make check run: | make -j check || (cat test/test-suite.log; false) + - name: Generate coverage reports + run: | + mkdir artifacts + tar cf - lib/*.gcov src/*.gcov | tar -C artifacts -xf - + - name: Upload coverage-annotated source files + uses: actions/upload-artifact@v4 + with: + path: "artifacts" + name: coverage_reports valgrind_build: runs-on: ubuntu-latest From 5074fe71e899ce9c487e932bf3e25f7e79f8fc04 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 15:59:33 -0500 Subject: [PATCH 175/250] Use `setlocal`, enable `cindent` --- .lvimrc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.lvimrc b/.lvimrc index 6cbc45f..83b237a 100644 --- a/.lvimrc +++ b/.lvimrc @@ -1,6 +1,3 @@ " Local vimrc configuration file. Install the localvimrc.vim vim script. -set noexpandtab -set tabstop=8 -set softtabstop=8 -set shiftwidth=8 +setlocal tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab cindent From 4f207d19fbeb9bb703f708f1e2453a03bc5851a9 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 16:01:43 -0500 Subject: [PATCH 176/250] We don't have a lib/ directory --- .github/workflows/make.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index 4cbb050..961ba73 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -20,7 +20,7 @@ jobs: - name: Generate coverage reports run: | mkdir artifacts - tar cf - lib/*.gcov src/*.gcov | tar -C artifacts -xf - + tar cf - src/*.gcov | tar -C artifacts -xf - - name: Upload coverage-annotated source files uses: actions/upload-artifact@v4 with: From 06147d08a86326ed208e2317ca59e2ad96b054db Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 16:09:19 -0500 Subject: [PATCH 177/250] Fix dist; `gencov` script moved directory --- src/Makefile.am | 2 -- test/Makefile.am | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 06c9ab8..bf7ca0a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,5 +28,3 @@ headerfiles_HEADERS=$(MAIN_HEADERFILES) calgheaderfilesdir=$(headerfilesdir)/libcalg calgheaderfiles_HEADERS=$(CALG_HEADERFILES) -EXTRA_DIST=gencov - diff --git a/test/Makefile.am b/test/Makefile.am index a0a53a9..8c82efd 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -35,7 +35,7 @@ framework.c framework.h test_cpp_SOURCES = test-cpp.cpp -EXTRA_DIST=valgrind-wrapper +EXTRA_DIST=valgrind-wrapper gencov if BUILD_COVERAGE From 1e0dc99a6bd692afb2a685a8c5316329312f5b1b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 16:25:43 -0500 Subject: [PATCH 178/250] Use absolute, not relative paths Partly fixes out-of-tree builds, needed to fix `make distcheck`. --- doc/Makefile.am | 2 +- src/Makefile.am | 2 +- test/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index badc6a3..5c83bd6 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,5 +2,5 @@ EXTRA_DIST = html Doxyfile intro.h html: - doxygen + doxygen $(top_srcdir)/doc/Doxyfile diff --git a/src/Makefile.am b/src/Makefile.am index bf7ca0a..ee0bc36 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ avl-tree.c compare-string.c hash-string.c queue.c trie.c \ compare-int.c hash-int.c hash-table.c set.c binary-heap.c \ bloom-filter.c binomial-heap.c rb-tree.c sortedarray.c -libcalgtest_a_CFLAGS=$(TEST_CFLAGS) -DALLOC_TESTING -I../test -g +libcalgtest_a_CFLAGS=$(TEST_CFLAGS) -DALLOC_TESTING -I$(top_srcdir)/test -g libcalgtest_a_SOURCES=$(SRC) $(MAIN_HEADERFILES) libcalg_la_CFLAGS=$(MAIN_CFLAGS) diff --git a/test/Makefile.am b/test/Makefile.am index 8c82efd..f34eca5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,5 +1,5 @@ -AM_CFLAGS = $(TEST_CFLAGS) -I../src -g +AM_CFLAGS = $(TEST_CFLAGS) -I$(top_srcdir)/src -g AM_CXXFLAGS = $(AM_CFLAGS) LDADD = $(top_builddir)/src/libcalgtest.a libtestframework.a From 5d2d2674488690dce97ba61e34b482bb5e6843b8 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 16:35:16 -0500 Subject: [PATCH 179/250] Add `make clean` hook to clear generated docs --- doc/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/Makefile.am b/doc/Makefile.am index 5c83bd6..960443f 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -4,3 +4,5 @@ EXTRA_DIST = html Doxyfile intro.h html: doxygen $(top_srcdir)/doc/Doxyfile +clean-local: + rm -rf $(top_builddir)/doc/html From a8e11a24e64c3f06da3a55cec67115dbb547ca46 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 16:35:38 -0500 Subject: [PATCH 180/250] Add `make dist` checks to CI --- .github/workflows/make.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index 961ba73..14c2050 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -26,6 +26,10 @@ jobs: with: path: "artifacts" name: coverage_reports + - name: make dist + run: | + make distcheck + make dist valgrind_build: runs-on: ubuntu-latest From d2dad6238c373fffaee6e0bb9643507f288e267b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 17:34:55 -0500 Subject: [PATCH 181/250] Fix doxygen generation with out-of-tree build --- doc/Doxyfile | 4 ++-- doc/Makefile.am | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/Doxyfile b/doc/Doxyfile index 69d2d71..678fdb7 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -523,8 +523,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = intro.h \ - ../src +INPUT = $(DOXYGEN_DOC_DIR)intro.h \ + $(DOXYGEN_DOC_DIR)../src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/doc/Makefile.am b/doc/Makefile.am index 960443f..6f3b765 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,7 +2,7 @@ EXTRA_DIST = html Doxyfile intro.h html: - doxygen $(top_srcdir)/doc/Doxyfile + DOXYGEN_DOC_DIR=$(srcdir)/ doxygen $(srcdir)/Doxyfile clean-local: - rm -rf $(top_builddir)/doc/html + rm -rf html From cccf3210906058a072298051a7d05b5613f2ac4a Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 17:38:08 -0500 Subject: [PATCH 182/250] Make sure we install doxygen before build --- .github/workflows/make.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index 14c2050..d0d7f3c 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -7,6 +7,10 @@ jobs: runs-on: ubuntu-latest steps: + - name: Install dependencies + run: | + sudo apt update + sudo apt -q install doxygen - uses: actions/checkout@v4 - name: configure run: | From 2e34771257ec15061df32ff49dded886c6062fe1 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 22:40:23 -0500 Subject: [PATCH 183/250] Fix warnings about variables "set but not used" --- test/test-list.c | 2 ++ test/test-slist.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/test-list.c b/test/test-list.c index ea5eb1a..664129a 100644 --- a/test/test-list.c +++ b/test/test-list.c @@ -464,6 +464,7 @@ void test_list_iterate(void) while (list_iter_has_more(&iter)) { data = (int *) list_iter_next(&iter); + assert(data != NULL); ++counter; if ((counter % 2) == 0) { @@ -499,6 +500,7 @@ void test_list_iterate(void) while (list_iter_has_more(&iter)) { data = (int *) list_iter_next(&iter); + assert(data != NULL); ++counter; } diff --git a/test/test-slist.c b/test/test-slist.c index 8325f8b..8fb9129 100644 --- a/test/test-slist.c +++ b/test/test-slist.c @@ -421,6 +421,7 @@ void test_slist_iterate(void) while (slist_iter_has_more(&iter)) { data = (int *) slist_iter_next(&iter); + assert(data != NULL); ++counter; @@ -458,6 +459,7 @@ void test_slist_iterate(void) while (slist_iter_has_more(&iter)) { data = (int *) slist_iter_next(&iter); + assert(data != NULL); ++counter; From f4d01b0e8d673b2d5f0dd60d47e8874ef6f7ec2e Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 9 Dec 2024 22:44:42 -0500 Subject: [PATCH 184/250] Update Doxyfile; remove deprecated variables This is the result of `doxygen -u` using Doxygen 1.9.8. --- doc/Doxyfile | 2858 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 2153 insertions(+), 705 deletions(-) diff --git a/doc/Doxyfile b/doc/Doxyfile index 678fdb7..029fed8 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1,90 +1,144 @@ -# Doxyfile 1.5.5 +# Doxyfile 1.9.8 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project +# doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. # The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. PROJECT_NAME = "C Algorithms" -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. PROJECT_NUMBER = -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. OUTPUT_DIRECTORY = . -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, -# and Ukrainian. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. +# The default value is: YES. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ @@ -99,8 +153,9 @@ ABBREVIATE_BRIEF = "The $name class" \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# doxygen will generate a detailed section even if there is only a brief # description. +# The default value is: NO. ALWAYS_DETAILED_SEC = NO @@ -108,464 +163,857 @@ ALWAYS_DETAILED_SEC = NO # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. +# The default value is: NO. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. FULL_PATH_NAMES = NO -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = src/ -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. JAVADOC_AUTOBRIEF = YES -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. -DETAILS_AT_TOP = NO +PYTHON_DOCSTRING = YES -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = YES -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. +# The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. +# The default value is: NO. CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. SIP_SUPPORT = NO +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first +# tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. +# The default value is: NO. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. SUBGROUPING = YES -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. TYPEDEF_HIDES_STRUCT = NO +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. EXTRACT_ALL = NO -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. EXTRACT_PRIVATE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. EXTRACT_STATIC = NO -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_MEMBERS = YES -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_CLASSES = YES -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the # documentation. +# The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. CASE_SENSE_NAMES = YES -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. SHOW_INCLUDE_FILES = YES -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. SORT_BRIEF_DOCS = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. SORT_GROUP_NAMES = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. SORT_BY_SCOPE_NAME = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. GENERATE_DEPRECATEDLIST= YES -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. +# The default value is: YES. SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. -SHOW_DIRECTORIES = NO +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. FILE_VERSION_FILTER = +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + #--------------------------------------------------------------------------- -# configuration options related to warning and progress messages +# Configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. WARN_IF_UNDOCUMENTED = YES -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. WARN_NO_PARAMDOC = NO -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = #--------------------------------------------------------------------------- -# configuration options related to the input files +# Configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. INPUT = $(DOXYGEN_DOC_DIR)intro.h \ $(DOXYGEN_DOC_DIR)../src # This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING +# The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, +# *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, *.php, +# *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be +# provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.h -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. RECURSIVE = NO -# The EXCLUDE tag can be used to specify files and/or directories that should +# The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. EXCLUDE = -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded # from the input. +# The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = @@ -573,507 +1021,1306 @@ EXCLUDE_PATTERNS = # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test +# ANamespace::AClass, ANamespace::*Test EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. FILTER_SOURCE_FILES = NO +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- -# configuration options related to source browsing +# Configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. SOURCE_BROWSER = NO -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. STRIP_CODE_COMMENTS = YES -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. REFERENCED_BY_RELATION = NO -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. REFERENCES_RELATION = NO -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. VERBATIM_HEADERS = NO +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: +# http://clang.llvm.org/) for more accurate parsing at the cost of reduced +# performance. This can be particularly helpful with template rich C++ code for +# which doxygen's built-in parser lacks the necessary type information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS +# tag is set to YES then doxygen will add the directory of each input to the +# include path. +# The default value is: YES. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_ADD_INC_PATHS = YES + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the directory containing a file called compile_commands.json. This +# file is the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the +# options used when the source files were built. This is equivalent to +# specifying the -p option to a clang tool, such as clang-check. These options +# will then be passed to the parser. Any options specified with CLANG_OPTIONS +# will be added as well. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. + +CLANG_DATABASE_PATH = + #--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index +# Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. ALPHABETICAL_INDEX = NO -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- -# configuration options related to the HTML output +# Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a # standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_HTMLHELP = NO +HTML_DYNAMIC_SECTIONS = NO -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. -HTML_DYNAMIC_SECTIONS = NO +GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be # written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. -ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_TREEVIEW = NO +FULL_SIDEBAR = NO -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /