2006-04-19 22:12:33 +04:00
/*
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2010-05-06 14:10:15 +04:00
* Copyright ( C ) 2004 - 2010 Red Hat , Inc . All rights reserved .
2006-04-19 22:12:33 +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 .
2006-04-19 22:12:33 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2006-04-19 22:12:33 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2006-04-19 22:12:33 +04:00
*/
# include "lib.h"
2008-11-04 18:07:45 +03:00
# include <assert.h>
2006-04-19 22:12:33 +04:00
/*
* Initialise a list before use .
* The list head ' s next and previous pointers point back to itself .
*/
2008-11-04 01:14:30 +03:00
void dm_list_init ( struct dm_list * head )
2006-04-19 22:12:33 +04:00
{
head - > n = head - > p = head ;
}
/*
* Insert an element before ' head ' .
* If ' head ' is the list head , this adds an element to the end of the list .
*/
2008-11-04 01:14:30 +03:00
void dm_list_add ( struct dm_list * head , struct dm_list * elem )
2006-04-19 22:12:33 +04:00
{
assert ( head - > n ) ;
elem - > n = head ;
elem - > p = head - > p ;
head - > p - > n = elem ;
head - > p = elem ;
}
/*
* Insert an element after ' head ' .
* If ' head ' is the list head , this adds an element to the front of the list .
*/
2008-11-04 01:14:30 +03:00
void dm_list_add_h ( struct dm_list * head , struct dm_list * elem )
2006-04-19 22:12:33 +04:00
{
assert ( head - > n ) ;
elem - > n = head - > n ;
elem - > p = head ;
head - > n - > p = elem ;
head - > n = elem ;
}
/*
* Delete an element from its list .
* Note that this doesn ' t change the element itself - it may still be safe
* to follow its pointers .
*/
2008-11-04 01:14:30 +03:00
void dm_list_del ( struct dm_list * elem )
2006-04-19 22:12:33 +04:00
{
elem - > n - > p = elem - > p ;
elem - > p - > n = elem - > n ;
}
2008-04-10 23:14:27 +04:00
/*
* Remove an element from existing list and insert before ' head ' .
*/
2008-11-04 01:14:30 +03:00
void dm_list_move ( struct dm_list * head , struct dm_list * elem )
2008-04-10 23:14:27 +04:00
{
2008-11-04 01:14:30 +03:00
dm_list_del ( elem ) ;
dm_list_add ( head , elem ) ;
2008-04-10 23:14:27 +04:00
}
2006-04-19 22:12:33 +04:00
/*
* Is the list empty ?
*/
2008-11-04 01:14:30 +03:00
int dm_list_empty ( const struct dm_list * head )
2006-04-19 22:12:33 +04:00
{
return head - > n = = head ;
}
/*
* Is this the first element of the list ?
*/
2008-11-04 01:14:30 +03:00
int dm_list_start ( const struct dm_list * head , const struct dm_list * elem )
2006-04-19 22:12:33 +04:00
{
return elem - > p = = head ;
}
/*
* Is this the last element of the list ?
*/
2008-11-04 01:14:30 +03:00
int dm_list_end ( const struct dm_list * head , const struct dm_list * elem )
2006-04-19 22:12:33 +04:00
{
return elem - > n = = head ;
}
/*
* Return first element of the list or NULL if empty
*/
2008-11-04 01:14:30 +03:00
struct dm_list * dm_list_first ( const struct dm_list * head )
2006-04-19 22:12:33 +04:00
{
2008-11-04 01:14:30 +03:00
return ( dm_list_empty ( head ) ? NULL : head - > n ) ;
2006-04-19 22:12:33 +04:00
}
/*
* Return last element of the list or NULL if empty
*/
2008-11-04 01:14:30 +03:00
struct dm_list * dm_list_last ( const struct dm_list * head )
2006-04-19 22:12:33 +04:00
{
2008-11-04 01:14:30 +03:00
return ( dm_list_empty ( head ) ? NULL : head - > p ) ;
2006-04-19 22:12:33 +04:00
}
/*
* Return the previous element of the list , or NULL if we ' ve reached the start .
*/
2008-11-04 01:14:30 +03:00
struct dm_list * dm_list_prev ( const struct dm_list * head , const struct dm_list * elem )
2006-04-19 22:12:33 +04:00
{
2008-11-04 01:14:30 +03:00
return ( dm_list_start ( head , elem ) ? NULL : elem - > p ) ;
2006-04-19 22:12:33 +04:00
}
/*
* Return the next element of the list , or NULL if we ' ve reached the end .
*/
2008-11-04 01:14:30 +03:00
struct dm_list * dm_list_next ( const struct dm_list * head , const struct dm_list * elem )
2006-04-19 22:12:33 +04:00
{
2008-11-04 01:14:30 +03:00
return ( dm_list_end ( head , elem ) ? NULL : elem - > n ) ;
2006-04-19 22:12:33 +04:00
}
/*
* Return the number of elements in a list by walking it .
*/
2008-11-04 01:14:30 +03:00
unsigned int dm_list_size ( const struct dm_list * head )
2006-04-19 22:12:33 +04:00
{
unsigned int s = 0 ;
2008-11-04 01:14:30 +03:00
const struct dm_list * v ;
2006-04-19 22:12:33 +04:00
2008-11-04 01:14:30 +03:00
dm_list_iterate ( v , head )
2006-04-19 22:12:33 +04:00
s + + ;
return s ;
}
2010-05-06 14:10:15 +04:00
/*
* Join two lists together .
* This moves all the elements of the list ' head1 ' to the end of the list
* ' head ' , leaving ' head1 ' empty .
*/
void dm_list_splice ( struct dm_list * head , struct dm_list * head1 )
{
assert ( head - > n ) ;
assert ( head1 - > n ) ;
if ( dm_list_empty ( head1 ) )
return ;
head1 - > p - > n = head ;
head1 - > n - > p = head - > p ;
head - > p - > n = head1 - > n ;
head - > p = head1 - > p ;
dm_list_init ( head1 ) ;
}