/* O. Baudon, project Inca, December 18, 1998 Copyright (c) 1993-1998 Olivier Baudon - LaBRI, Universite Bordeaux 1. All rights reserved. See the file "license.terms" for information on usage and redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef LIST_H #define LIST_H /* list is an independant module used to group objects into a single ordered set, and to allow mapping functions on this set. The order depends on how the objects are inserted in the list. */ typedef struct s_list * list; typedef struct s_atom * list_position; typedef void * (* list_malloc_type)(int size); typedef void (* list_free_type)(void * ptr); typedef void (* list_deallocate_type)(void * object); typedef int (* list_map_type)(void * object, void * call_data); #define BEGINNING NULL /* Create an empty list. malloc() is a function that allocates a block of memory. free() frees memory that has been allocated by malloc(). If deallocate() is not NULL, it is called whenever an object is removed from the list. There is an order in the list, i.e. each object has a predecessor and a successor, except the first and the last. */ extern list list_create(list_malloc_type malloc, list_free_type free, list_deallocate_type deallocate); /* Destroy a list. If not NULL, deallocate() is called for all the objects contained in the list. */ extern void list_destroy(list list); /* Number of objects in the list. */ extern int list_size(list list); /* Check whether the list is empty. It is equivalent to (list_size(l) == 0). */ extern int list_empty(list list); /* List and positions. A list has the notion of position and current position. When an object is inserted in the list, a new position is created and returned by the inserting function. It becomes the current position. To remove an element, it is necessary that the current position is the position associated to the object. When an object is removed, the current position becomes the position of the next element, except if the object is the last one. In that case, the current position becomes the position of its predecessor. The beggining position means the position before the first element. The current position of an empty list is always the beggining. */ /* Add an object. An object may appear twice in the list : be careful ! The newly inserted object is the successor of the object associated to the current position before insertion. If the current position was BEGINNING, then the newly inserted object will be the first. The new current position becomes the position of the newly inserted element. */ extern list_position list_insert(list list, void * object); /* Add an object after a given position. The current position is not changed. */ extern list_position list_insert_after(list list, list_position pos, void * object); /* Replace the current object by a new one. The deallocate function, if it exists, is called on the removed object. If the current position is the beggining, an error ocurs. Otherwise, this function does not affect the current position. */ extern void list_replace(list list, void * object); /* Remove the current object from the list and call deallocate() on it. The new cursor position is on the next object, except if the object was the last one. In that case, the current object is the new last.*/ extern void list_remove(list list); /* Remove the object from a given position. If the position is the current one, this function is equivalent to the previous one. Otherwise, the current position is not changed. */ extern void list_remove_from_position(list list, list_position pos); /* The following functions return the object at a given position. The current position cannot be the beggining. */ extern void * list_get_current(list list); extern void * list_get_object(list list, list_position pos); extern void * list_get_first(list list); extern void * list_get_last(list list); /* Return the current cursor position. The position is BEGINNING if it is before the first element. */ extern list_position list_get_position(list list); /* Test the position. */ int list_at_first(list list); int list_at_last(list list); int list_at_beginning(list list); /* The following functions change the current position. go_beginning means to go before the first element and is equivalent to modify_position() with BEGINNING as new position. An error occurs if the current position was BEGINNING (respectivly at last element) and you try to go to the previous (resp. next) element. */ extern void list_modify_position(list list, list_position new_pos); extern void list_go_previous(list list); extern void list_go_next(list list); extern void list_go_first(list list); extern void list_go_last(list list); extern void list_go_beginning(list list); /* Map a function on each object with parameter. No side effect on the list may be done (insertion or deletion). The mapping starts by the first object. It stops if the mapped function returns 0. The current position is not changed. */ extern void list_map(list list, list_map_type fun, void * call_data); /* Useful */ /* Append two lists in the first and return it. Note that l2 no more exists, but positions in l2 are still available as positions in the new list. The malloc, free and deallocate functions must be the same for the two lists, otherwise an error may occurs. */ extern list list_append(list l1, list l2); /* Create an array from a list. The memory used by the array is allocated using the malloc of the list. */ extern void list_to_array(list l, void *** arrayPtr); #endif