diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 6bc220ac18f78da14e08266098556ff00e687307..0601d91395d2f67941831a5990f556e7074e01f7 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -1558,7 +1558,7 @@ MACRO_EXPANSION = NO # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. @@ -1586,7 +1586,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = DOXYGEN_DOCUMENTATION_ONLY # 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. diff --git a/include/libmtime.h b/include/libmtime.h index 8f3b3a8d862875cd47158d94f4e7e4134dd2f2d8..5d37733051077e7bcfcb545031a49219ef480b7f 100644 --- a/include/libmtime.h +++ b/include/libmtime.h @@ -470,6493 +470,4 @@ return ret; } \endverbatim * -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ /** @file doc.h Documentation header file */ -/** @mainpage libdacav - A simple container library -* -* This project aims to produce some general purpose utilities shaped as -* libraries: -* -* Libdacav provides some simple and well documented data structures of -* common use: -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav -*/ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ -* -* \arg Hash tables; -* \arg Double linked lists; -* \arg Heaps; -* \arg Buffered strings; -* \arg Circular buffers. -* -* \section CompileInstall Compilation and installation -* -* You can obtain the source code tarball on the sourceforge site -* at http://sourceforge.net/projects/libdacav/ -* -* There's also a blog: -* https://sourceforge.net/apps/wordpress/libdacav/ -* -* This software uses the GNU Autotools build system: in order to -* compile and install the application the standard installation -* method must be used: -\verbatim -./configure -make -make install -\endverbatim -* -* More information is provided by the INSTALL file, which is -* included in the software package. -* -* \section Usage -* -* The doxygen documentation you are reading is pretty rich. You -* however can take a glance at the libdacav/tests directory, which -* contains the unit-tests. Hint: The tests which name matches the -* <em>^test[0-9][0-0]-.+$</em> regular rexpression are the most -* interesting ;-) -* -* \section License -* -* LibDacav is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* A copy of the GNU General Public License is provided along with -* LibDacav: see the COPYING file provided with the distribution. -* -* If you need me to cross-license it, just send me a mail (see the -* AUTHORS file). -* -* \section Dependency -* -* The library should work correctly without any dependency under any -* Posix-compliant operating system. If you experiment some issue -* please contact me. The AUTHORS and THANKS files provided with the -* software distribution contain developers contacts. -* -*/ -/** @defgroup LibDacav -* -* This library provides data containers. The implementation is as general -* as possible, and provides a way to store elements of type void *. This -* can be exploited for both tracing by pointer of allocated values and -* memorization of primitive types. In both cases objects can be stored by -* casting. -* -* @note For portability of your software, you may be interested in -* knowing that under a 64bit platform void * is no longer -* compatible with primitive types like int. The C standard library -* provides, in stdint.h, the type uintptr_t that is always -* compatible. -* -*/ -/** @defgroup DacavData Generic Data Types -* @ingroup LibDacav -* -* This module declares some general use data types. -*/ -/** @defgroup DacavHash Hash Tables -* @ingroup LibDacav -* -* This module provides a simple hash table implementation. -* -* When allocating a new hash table, five parameters are usually -* needed: -* -* \arg The number of buckets of the hash table; -* \arg A callback that computes a hash of a key; -* \arg A callback that compares two keys; -* \arg A pair of callbacks for respectively copying and freeing -* internal copies of the keys; -* \arg A similar pair of callbacks for the values. -* -* The number of buckets provided as first parameter is a trade-off -* between performances in time and space required. It should depend -* on the predicted number of stored element. The more objects are -* sparse among buckets, the more data retrieving will be optimized. -* Choosing a prime number will help in reducing hash clashes. -* -* Providing no hash function will result in the library using -* directly the value of the pointer as hash. Providing no comparison -* function will result in comparison of stored object addresses and -* search keys addresses. This can be useful, for instance, if you -* are storing primitive values and don't want to allocate memory -* just for them: just use the pointer as it were an integer. -* -* Providing no copy-constructor and destructor for the keys will -* result in the library directly storing the user-provided keys. -* This is usually a good idea only if you plan to store primitive -* types! You may do it also for allocated composite types, but this -* may result in memory leaks if you overwrite a stored value with -* dhash_insert(), as only the value (and not the key) will be -* overwritten, and the key you provided is simply not used. If you -* are crazy enough to do something like that, please check the -* return value of dhash_insert() in this case to decide what to do -* with your local copy of the key. -* -* \section DacavHashAlloc Allocation and deallocation: -* -* Example of hash table allocation: -* -\verbatim -dcprm_t cprm_k = { -.cp = copy_key, // copy-constructor for key -.rm = free_key // destructor for key -}; -dcprm_t cprm_v = { -.cp = copy_key, // copy-constructor for value -.rm = free_key // destructor for value -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_function, cmp_function, -&cprm_k, &cprm_v); -\endverbatim -* -* \see dhash_cb_t -* \see dcmp_cb_t -* \see dprm_t -* \see dhash_new -* -* \subsection DacavHashAllocInt Example using integers as keys -* -* In this example we show to use integer values as -* keys. -* -* A good hashing function for integer (the one used as -* default hashing function) may be: -\verbatim -static unsigned hash_int (const void *key) -{ -return (int) key; -} -\endverbatim -* -* Since the required semantic for the comparison is the same -* used by strcmp(3), a simple subtraction between two -* integers behaves correctly: -* -\verbatim -static int cmp_int (const void *v0, const void *v1) -{ -return (int) v0 - (int) v1; -} -\endverbatim -* -* Since integers are primitive types, we don't need to -* specify how to copy and destroy them. The declaration of -* such a hash table is so far the following: -* -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, hash_int, cmp_int, NULL, NULL); -\endverbatim -* -* Actually the shown hash and comparison functions are -* already defined internally, so in order to obtain the same -* result, the hash table initialization can be done by -* passing NULL as second and third argument. -\verbatim -dhash_t *tab = dhash_new(N_BUCKETS, NULL, NULL, NULL, NULL); -\endverbatim -* -* Note that this kind of behavior can also be exploited to -* achieve comparison based on object identity instead of -* object equality. -* -* \subsection DacavHashAllocString Using strings as keys -* -* Suppose you want to map strings to strings with an hash -* table. -* -* A good hashing function may be the following (which btw is -* the one standardized by the ELF specification): -\verbatim -static unsigned hash_str (const void *key) -{ -const char *name; -unsigned h = 0, g; -while (*name) { -h = (h << 4) + *name++; -if ((g = h & 0xf00000000) != 0) { -h &= g >> 24; -} -h &= ~g; -} -return h; -} -\endverbatim -* -* A good destructor is just free(3), while a good -* copy-constructor for strings is strcpy(3), except it -* doesn't work with NULL pointers. We can wrap it, just -* beware of zero-termination: -\verbatim -static void * copy_str (const void *key) -{ -if (key == NULL) return NULL; -return strdup((const char *)key); -} -\endverbatim -* -* The string comparison function is simply supplied by -* strcmp(3), however since the signature of strcmp(3) is -* slightly different from the dcmp_func_t data type, a -* casting is needed. -* -* The initialization would be the following -* -\verbatim -dhash_cprm_t cprm = { -.cp = copy_str, -.rm = free -}; -dhash_t *tab = dhash_new(N_BUCKETS, hash_str, (dcmp_func_t)strcmp, &cprm, -&cprm); -\endverbatim -* -* \section DacavHashIter Iterators for hash tables: -* -* Because of the particular nature of a hash table, for which -* every entry is composed by <key,value> couples, the return -* value of a diter_next() function called on a hash table -* iterator returns a pointer to an object of type dhash_pair_t -* -* In order to obtain the correct key and the correct value for -* a dhash_pair_t object, the functions dhash_key() and -* dhash_val() must be called respectively. -* -* By example, the following procedure will print all the <key, -* value> couples contained in a hash table and will remove them -* as long as they are listed: -\verbatim -void print_key_values () -{ -diter_t *iter = dhash_iter_new(table); -while (diter_hasnext(iter)) { -dhash_pair_t *pair = diter_next(iter); -int k = (int)dhash_key(pair); -int v = (int)dhash_val(pair); -printf("key=%d, value=%d\n", k, v); -dhash_remove(iter); -} -dhash_iter_free(iter); -} -\endverbatim -* -* @note Keys and values yielded through iterators are exactly -* the ones stored into the hash table. Keys are constant, -* but values are not, thus if you stored pointers you may -* modified stored objects. Of course this is not true if -* you stored primitve types. -* -* \see diter_next -* \see dhash_pair_t -* \see dhash_key -* \see dhash_val -* \see DacavIter -*/ -/** @defgroup DacavList Double Linked Lists -* @ingroup LibDacav -* -* This module provides a double linked list implementation. -* -* Using this module is pretty straightforward. Those lists can be -* used to achieve all list-related operations, like push, append, -* and pop. This can also be used to implement a stack semantics. -* -* \section DacavListAlloc Allocation and deallocation: -* -* There are two ways of allocating a dlist_t object: by use of -* the normal constructor dlist_new() or by the dlist_slice(), -* which allows to get a new, indipendent list as a piece of the -* one given as parameter. -* -* For ones who are familiar with Python, this is similar to the -* slice operation on iterable elements. Note that a list -* produced by means of dlist_slice is a shallow copy: it must be -* deallocated indipendendently from the original one, while the -* contained objects must be freed just one time! You should -* avoid double free corruptions. -* -* \section DacavListAssign Assignment semantics: -* -* In order to make the implementation more simple, every -* provided function (except dlist_free) returns a pointer to a -* dlist_t object. This entails that every operation on the -* lists corresponds to an assignment: -\verbatim -dlist_t *lst = dlist_new(); -int value = 3; -// Append the value to the list -lst = dlist_append(lst, (void *)value); -// Extract the first value stored in the list -lst = dlist_pop(lst, (void **)&value); -dlist_free(lst); -\endverbatim -* -*/ -/** @defgroup DacavIter Iterators -* @ingroup LibDacav -* -* Iterators concept is the same provided by Java. Every container -* structure declared in libdacav is provided with a dedicated -* iterator constructor and a dedicated iterator destructor, while -* functions that allows to iterate among elements are of general -* use. -* -* By example, for the dlist_t data type, libdacav provides the -* dlist_iter_new and the dlist_free functions, while for dhash_t the -* dhash_iter_new and the dhash_iter_free functions are provided. -* -* After allocating an iterator with the correct primitive (depending -* on which data structure you are working with), the iteration -* process is something like: -\verbatim -while (diter_hasnext(my_iterator)) { -do_something(diter_next(my_iterator)); -} -\endverbatim -* -* \section DacavIterOperations Allowed operations: -* -* Once the iterator is allocated, the iterator user can access -* to the diter_hasnext, diter_next, diter_remove and -* diter_replace primitive. -* -* The first two are always implemented, since they are somehow -* mandatory. The diter_remove and diter_replace ones, instead, -* can be left unimplemented by design. Requiring a diter_remove -* or a diter_replace operation on an iterator for which they are -* not implemented doesn't produce any consequence. -* -* \section DacavIterInternals Internal use primitive: -* -* Apart from the functions listed above, the library provides -* some additional primitives that can be used to implement a -* similar iteration semantics. -* -* \see InternalIter -*/ -/** @defgroup DacavHeap Heaps -* @ingroup LibDacav -* -* This module provides a Heap mechanism. This kind of mechanism is -* tipically used for priority queues implementation, because allows -* to select in a very efficient way the greatest or the least -* element of a set. -*/ -/** @defgroup DacavStrbuf Buffered strings -* @ingroup LibDacav -* -* This module addresses the necessity of building a string by -* appending incrementally pieces of text. Strings gets stored into a -* list of buffers, which gets transformed into a new string by -* request. -*/ -/** @defgroup DacavCirc Circular buffers -* @ingroup LibDacav -* -* This module provides a trivial implementation of fixed size -* circular buffers. -*/ -/** @defgroup Internals LibDacav development -* @ingroup LibDacav */ -/** @defgroup InternalIter Functions for Iterators -* @ingroup Internals -* -* Apart from the diter_hasnext(), diter_next(), diter_remove() and -* diter_replace() functions, the library provides some additional -* primitives that can be used to implement a similar iteration -* semantics. -* -* These primitive are diter_new(), diter_free() and -* diter_get_iterable(). They are meant to be used by an iterator -* provider. The first two respectively allocate and deallocate a raw -* iterator, while the third one can be used to retrieve a pointer to -* the iterator's reserved memory area. Confused? The following -* example will make it clear. -* -* \section InternalIterExample Usage example: -* -* Basing on the data structure you are writing, a different kind -* of information may be needed in order to build. The dlist_t -* implementation, for instance, requires the following internal -* structure: -\verbatim -struct iterable { -dlist_t *first; -dlist_t *cursor; -dlist_t **list; -}; -\endverbatim -* -* The iterator functions are provided as private (static) -* procedures, which are used as callback by the generic iterator -* implementation: -\verbatim -static -int iter_hasnext (struct iterable *it) -{ -... -} -static -void *iter_next (struct iterable *it) -{ -... -} -static -void iter_remove (struct iterable *it, dfree_cb_t f) -{ -... -} -static -void iter_replace (struct iterable *it, void *new_val) -{ -... -} -\endverbatim -* -* The allocation phase requires the construction of a raw -* iterator, which is parametrized with the dlist_t specific -* iteration functions. The fifth parameter of diter_new gives -* the auxiliary memory used by the specific iterator -* implementation, while the diter_get_iterable function will -* return a pointer to the memory zone itself: -\verbatim -diter_t *dlist_iter_new (dlist_t **l) -{ -diter_t *ret = diter_new((dnext_t)iter_next, (dhasnext_t)iter_hasnext, -(dremove_t)iter_remove, -(dreplace_t)iter_replace, -sizeof(struct iterable)); -struct iterable *it = diter_get_iterable(ret); -it->cursor = it->first = *l; -it->list = l; -return ret; -} -\endverbatim -* -*/ diff --git a/src/libmtime.f90 b/src/libmtime.f90 index 5a78d092b7af1c036e26a89601ea439216af6c1c..083921efdcd2035c7a3e1a7fc6d5590d2bd55456 100644 --- a/src/libmtime.f90 +++ b/src/libmtime.f90 @@ -53,6 +53,7 @@ module mtime_calendar !> provides a string length for toString integer, parameter :: max_calendar_str_len = 32 ! + !> @cond DOXYGEN_IGNORE_THIS interface ! subroutine setCalendar(ct) bind(c, name='initCalendar') @@ -74,11 +75,12 @@ module mtime_calendar end subroutine my_calendartostring ! end interface + !> @endcond DOXYGEN_IGNORE_THIS ! contains ! +#ifdef DOXYGEN_DOCUMENTATION_ONLY !> - !! @fn subroutine setCalendar(ct) !! @brief Initialize a new calendar. !! !! setCalendar is done at the very begining to select one of the @@ -100,15 +102,22 @@ contains !! right the first time. !! !! @param[in] ct the calendar type - ! - !> @fn subroutine resetCalendar() + subroutine setCalendar(ct) bind(c, name='initCalendar') + integer(c_int), value :: ct + end subroutine setCalendar + !> !! @brief called to discard the selected calendar type - ! - !> @fn function calendarType() + subroutine resetCalendar() bind(c, name='freeCalendar') + end subroutine resetCalendar + !> !! @brief to get an idea, which calendar type is selected !! !! @return an integer denoting the calendar in use + function calendarType() bind(c, name='getCalendarType') + integer(c_int) :: calendarType + end function calendarType ! +#endif !> !! @brief convert the calendar identifier into a human readable string !!