2001-10-31 15:47:01 +03:00
/*
2004-03-30 23:35:44 +04:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2007 Red Hat , Inc . All rights reserved .
2001-10-31 15:47:01 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2001-10-31 15:47:01 +03:00
*/
2001-09-28 17:19:17 +04:00
2001-10-01 19:14:39 +04:00
# ifndef _LVM_LIST_H
# define _LVM_LIST_H
2001-09-28 17:19:17 +04:00
2003-03-24 21:08:53 +03:00
# include <assert.h>
2005-04-06 18:50:37 +04:00
/*
* A list consists of a list head plus elements .
* Each element has ' next ' and ' previous ' pointers .
* The list head ' s pointers point to the first and the last element .
*/
2001-10-31 15:47:01 +03:00
struct list {
struct list * n , * p ;
2001-09-28 17:19:17 +04:00
} ;
2005-04-06 18:50:37 +04:00
/*
* Initialise a list before use .
* The list head ' s next and previous pointers point back to itself .
*/
2003-07-05 02:34:56 +04:00
# define LIST_INIT(name) struct list name = { &(name), &(name) }
2006-04-19 19:33:07 +04:00
void list_init ( struct list * head ) ;
2001-09-28 17:19:17 +04:00
2005-04-06 18:50:37 +04:00
/*
* Insert an element before ' head ' .
* If ' head ' is the list head , this adds an element to the end of the list .
*/
2006-04-19 19:33:07 +04:00
void list_add ( struct list * head , struct list * elem ) ;
2001-09-28 17:19:17 +04:00
2005-04-06 18:50:37 +04:00
/*
* Insert an element after ' head ' .
* If ' head ' is the list head , this adds an element to the front of the list .
*/
2006-04-19 19:33:07 +04:00
void list_add_h ( struct list * head , struct list * elem ) ;
2001-09-28 17:19:17 +04:00
2005-04-06 18:50:37 +04:00
/*
* Delete an element from its list .
* Note that this doesn ' t change the element itself - it may still be safe
* to follow its pointers .
*/
2006-04-19 19:33:07 +04:00
void list_del ( struct list * elem ) ;
2001-09-28 17:19:17 +04:00
2005-04-06 18:50:37 +04:00
/*
* Is the list empty ?
*/
2007-08-07 13:06:05 +04:00
int list_empty ( const struct list * head ) ;
2001-09-28 17:19:17 +04:00
2005-04-06 18:50:37 +04:00
/*
* Is this the first element of the list ?
*/
2007-08-07 13:06:05 +04:00
int list_start ( const struct list * head , const struct list * elem ) ;
2005-04-06 18:50:37 +04:00
/*
* Is this the last element of the list ?
*/
2007-08-07 13:06:05 +04:00
int list_end ( const struct list * head , const struct list * elem ) ;
2002-12-12 23:55:49 +03:00
2005-06-01 20:51:55 +04:00
/*
* Return first element of the list or NULL if empty
*/
2007-08-07 13:06:05 +04:00
struct list * list_first ( const struct list * head ) ;
2005-06-01 20:51:55 +04:00
2005-05-11 20:46:59 +04:00
/*
* Return last element of the list or NULL if empty
*/
2007-08-07 13:06:05 +04:00
struct list * list_last ( const struct list * head ) ;
2005-05-11 20:46:59 +04:00
2005-04-06 18:50:37 +04:00
/*
* Return the previous element of the list , or NULL if we ' ve reached the start .
*/
2007-08-07 13:06:05 +04:00
struct list * list_prev ( const struct list * head , const struct list * elem ) ;
2005-04-06 18:50:37 +04:00
/*
* Return the next element of the list , or NULL if we ' ve reached the end .
*/
2007-08-07 13:06:05 +04:00
struct list * list_next ( const struct list * head , const struct list * elem ) ;
2003-05-06 16:01:13 +04:00
2005-04-06 18:50:37 +04:00
/*
2005-04-06 19:21:28 +04:00
* Given the address v of an instance of ' struct list ' called ' head '
* contained in a structure of type t , return the containing structure .
2005-04-06 18:50:37 +04:00
*/
2005-04-06 19:21:28 +04:00
# define list_struct_base(v, t, head) \
( ( t * ) ( ( uintptr_t ) ( v ) - ( uintptr_t ) & ( ( t * ) 0 ) - > head ) )
2003-09-15 22:22:50 +04:00
2005-04-06 18:50:37 +04:00
/*
* Given the address v of an instance of ' struct list list ' contained in
* a structure of type t , return the containing structure .
*/
# define list_item(v, t) list_struct_base((v), t, list)
/*
* Given the address v of one known element e in a known structure of type t ,
* return another element f .
*/
2003-09-15 22:22:50 +04:00
# define struct_field(v, t, e, f) \
( ( ( t * ) ( ( uintptr_t ) ( v ) - ( uintptr_t ) & ( ( t * ) 0 ) - > e ) ) - > f )
2005-04-06 18:50:37 +04:00
/*
* Given the address v of a known element e in a known structure of type t ,
* return the list head ' list '
*/
2003-09-15 22:22:50 +04:00
# define list_head(v, t, e) struct_field(v, t, e, list)
2005-04-06 18:50:37 +04:00
/*
* Set v to each element of a list in turn .
*/
2001-10-31 15:47:01 +03:00
# define list_iterate(v, head) \
2002-01-29 19:28:52 +03:00
for ( v = ( head ) - > n ; v ! = head ; v = v - > n )
2005-04-06 18:50:37 +04:00
/*
* Set v to each element in a list in turn , starting from the element
* in front of ' start ' .
* You can use this to ' unwind ' a list_iterate and back out actions on
* already - processed elements .
* If ' start ' is ' head ' it walks the list backwards .
*/
2003-07-05 02:34:56 +04:00
# define list_uniterate(v, head, start) \
for ( v = ( start ) - > p ; v ! = head ; v = v - > p )
2005-04-06 18:50:37 +04:00
/*
* A safe way to walk a list and delete and free some elements along
* the way .
* t must be defined as a temporary variable of the same type as v .
*/
2002-01-29 19:28:52 +03:00
# define list_iterate_safe(v, t, head) \
for ( v = ( head ) - > n , t = v - > n ; v ! = head ; v = t , t = v - > n )
2001-09-28 17:19:17 +04:00
2005-04-06 18:50:37 +04:00
/*
* Walk a list , setting ' v ' in turn to the containing structure of each item .
* The containing structure should be the same type as ' v ' .
2005-04-06 19:21:28 +04:00
* The ' struct list ' variable within the containing structure is ' field ' .
2005-04-06 18:50:37 +04:00
*/
2005-04-06 19:21:28 +04:00
# define list_iterate_items_gen(v, head, field) \
for ( v = list_struct_base ( ( head ) - > n , typeof ( * v ) , field ) ; \
& v - > field ! = ( head ) ; \
v = list_struct_base ( v - > field . n , typeof ( * v ) , field ) )
2005-04-06 18:50:37 +04:00
/*
* Walk a list , setting ' v ' in turn to the containing structure of each item .
* The containing structure should be the same type as ' v ' .
* The list should be ' struct list list ' within the containing structure .
*/
2005-04-06 19:21:28 +04:00
# define list_iterate_items(v, head) list_iterate_items_gen(v, (head), list)
2003-09-15 22:22:50 +04:00
2005-10-17 03:03:59 +04:00
/*
* Walk a list , setting ' v ' in turn to the containing structure of each item .
* The containing structure should be the same type as ' v ' .
* The ' struct list ' variable within the containing structure is ' field ' .
* t must be defined as a temporary variable of the same type as v .
*/
# define list_iterate_items_gen_safe(v, t, head, field) \
for ( v = list_struct_base ( ( head ) - > n , typeof ( * v ) , field ) , \
t = list_struct_base ( v - > field . n , typeof ( * v ) , field ) ; \
& v - > field ! = ( head ) ; \
v = t , t = list_struct_base ( v - > field . n , typeof ( * v ) , field ) )
/*
* Walk a list , setting ' v ' in turn to the containing structure of each item .
* The containing structure should be the same type as ' v ' .
* The list should be ' struct list list ' within the containing structure .
* t must be defined as a temporary variable of the same type as v .
*/
# define list_iterate_items_safe(v, t, head) \
list_iterate_items_gen_safe ( v , t , ( head ) , list )
2005-06-01 20:51:55 +04:00
/*
* Walk a list backwards , setting ' v ' in turn to the containing structure
* of each item .
* The containing structure should be the same type as ' v ' .
* The ' struct list ' variable within the containing structure is ' field ' .
*/
# define list_iterate_back_items_gen(v, head, field) \
for ( v = list_struct_base ( ( head ) - > p , typeof ( * v ) , field ) ; \
& v - > field ! = ( head ) ; \
v = list_struct_base ( v - > field . p , typeof ( * v ) , field ) )
/*
* Walk a list backwards , setting ' v ' in turn to the containing structure
* of each item .
* The containing structure should be the same type as ' v ' .
* The list should be ' struct list list ' within the containing structure .
*/
# define list_iterate_back_items(v, head) list_iterate_back_items_gen(v, (head), list)
2005-04-06 18:50:37 +04:00
/*
* Return the number of elements in a list by walking it .
*/
2006-04-19 19:33:07 +04:00
unsigned int list_size ( const struct list * head ) ;
2001-11-28 16:45:50 +03:00
2001-09-28 17:19:17 +04:00
# endif