2001-02-23 20:55:21 +03:00
/*
* list . c : lists handling implementation
*
* Copyright ( C ) 2000 Gary Pennington and Daniel Veillard .
*
* Permission to use , copy , modify , and distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
*
* THIS SOFTWARE IS PROVIDED ` ` AS IS ' ' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES , INCLUDING , WITHOUT LIMITATION , THE IMPLIED WARRANTIES OF
2020-03-08 19:19:42 +03:00
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE . THE AUTHORS AND
2001-02-23 20:55:21 +03:00
* CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER .
*
* Author : Gary . Pennington @ uk . sun . com
*/
2002-03-18 22:37:11 +03:00
# define IN_LIBXML
2001-04-21 20:57:29 +04:00
# include "libxml.h"
2001-02-23 20:55:21 +03:00
# include <stdlib.h>
# include <string.h>
# include <libxml/xmlmemory.h>
# include <libxml/list.h>
2001-10-17 19:58:35 +04:00
# include <libxml/globals.h>
2001-02-23 20:55:21 +03:00
/*
* Type definition are kept internal
*/
struct _xmlLink
{
struct _xmlLink * next ;
struct _xmlLink * prev ;
void * data ;
} ;
struct _xmlList
{
xmlLinkPtr sentinel ;
void ( * linkDeallocator ) ( xmlLinkPtr ) ;
int ( * linkCompare ) ( const void * , const void * ) ;
} ;
/************************************************************************
* *
* Interfaces *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlLinkDeallocator :
* @ l : a list
* @ lk : a link
*
* Unlink and deallocate @ lk from list @ l
*/
static void
xmlLinkDeallocator ( xmlListPtr l , xmlLinkPtr lk )
{
( lk - > prev ) - > next = lk - > next ;
( lk - > next ) - > prev = lk - > prev ;
if ( l - > linkDeallocator )
l - > linkDeallocator ( lk ) ;
xmlFree ( lk ) ;
}
/**
* xmlLinkCompare :
* @ data0 : first data
* @ data1 : second data
*
* Compares two arbitrary data
*
* Returns - 1 , 0 or 1 depending on whether data1 is greater equal or smaller
* than data0
*/
static int
xmlLinkCompare ( const void * data0 , const void * data1 )
{
if ( data0 < data1 )
return ( - 1 ) ;
else if ( data0 = = data1 )
return ( 0 ) ;
return ( 1 ) ;
}
/**
* xmlListLowerSearch :
* @ l : a list
* @ data : a data
*
* Search data in the ordered list walking from the beginning
*
* Returns the link containing the data or NULL
*/
2012-09-11 09:26:36 +04:00
static xmlLinkPtr
xmlListLowerSearch ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lk ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
for ( lk = l - > sentinel - > next ; lk ! = l - > sentinel & & l - > linkCompare ( lk - > data , data ) < 0 ; lk = lk - > next ) ;
2012-09-11 09:26:36 +04:00
return lk ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlListHigherSearch :
* @ l : a list
* @ data : a data
*
* Search data in the ordered list walking backward from the end
*
* Returns the link containing the data or NULL
*/
2012-09-11 09:26:36 +04:00
static xmlLinkPtr
xmlListHigherSearch ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lk ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
for ( lk = l - > sentinel - > prev ; lk ! = l - > sentinel & & l - > linkCompare ( lk - > data , data ) > 0 ; lk = lk - > prev ) ;
2012-09-11 09:26:36 +04:00
return lk ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlListSearch :
* @ l : a list
* @ data : a data
*
* Search data in the list
*
* Returns the link containing the data or NULL
*/
2012-09-11 09:26:36 +04:00
static xmlLinkPtr
xmlListLinkSearch ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lk ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
lk = xmlListLowerSearch ( l , data ) ;
if ( lk = = l - > sentinel )
return NULL ;
else {
if ( l - > linkCompare ( lk - > data , data ) = = 0 )
return lk ;
return NULL ;
}
}
/**
* xmlListLinkReverseSearch :
* @ l : a list
* @ data : a data
*
* Search data in the list processing backward
*
* Returns the link containing the data or NULL
*/
2012-09-11 09:26:36 +04:00
static xmlLinkPtr
xmlListLinkReverseSearch ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lk ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
lk = xmlListHigherSearch ( l , data ) ;
if ( lk = = l - > sentinel )
return NULL ;
else {
if ( l - > linkCompare ( lk - > data , data ) = = 0 )
return lk ;
return NULL ;
}
}
/**
* xmlListCreate :
* @ deallocator : an optional deallocator function
* @ compare : an optional comparison function
*
* Create a new list
*
* Returns the new list or NULL in case of error
*/
xmlListPtr
xmlListCreate ( xmlListDeallocator deallocator , xmlListDataCompare compare )
{
xmlListPtr l ;
if ( NULL = = ( l = ( xmlListPtr ) xmlMalloc ( sizeof ( xmlList ) ) ) ) {
2012-09-11 09:26:36 +04:00
xmlGenericError ( xmlGenericErrorContext ,
2002-09-05 15:33:25 +04:00
" Cannot initialize memory for list " ) ;
2001-02-23 20:55:21 +03:00
return ( NULL ) ;
}
/* Initialize the list to NULL */
memset ( l , 0 , sizeof ( xmlList ) ) ;
2012-09-11 09:26:36 +04:00
2001-02-23 20:55:21 +03:00
/* Add the sentinel */
if ( NULL = = ( l - > sentinel = ( xmlLinkPtr ) xmlMalloc ( sizeof ( xmlLink ) ) ) ) {
2012-09-11 09:26:36 +04:00
xmlGenericError ( xmlGenericErrorContext ,
2002-09-05 15:33:25 +04:00
" Cannot initialize memory for sentinel " ) ;
2001-02-23 20:55:21 +03:00
xmlFree ( l ) ;
return ( NULL ) ;
}
l - > sentinel - > next = l - > sentinel ;
l - > sentinel - > prev = l - > sentinel ;
l - > sentinel - > data = NULL ;
2012-09-11 09:26:36 +04:00
2001-02-23 20:55:21 +03:00
/* If there is a link deallocator, use it */
if ( deallocator ! = NULL )
l - > linkDeallocator = deallocator ;
/* If there is a link comparator, use it */
if ( compare ! = NULL )
l - > linkCompare = compare ;
else /* Use our own */
l - > linkCompare = xmlLinkCompare ;
return l ;
}
2012-09-11 09:26:36 +04:00
2001-02-23 20:55:21 +03:00
/**
* xmlListSearch :
* @ l : a list
* @ data : a search value
*
* Search the list for an existing value of @ data
*
* Returns the value associated to @ data or NULL in case of error
*/
void *
2012-09-11 09:26:36 +04:00
xmlListSearch ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lk ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
lk = xmlListLinkSearch ( l , data ) ;
if ( lk )
return ( lk - > data ) ;
return NULL ;
}
/**
2001-07-18 23:30:27 +04:00
* xmlListReverseSearch :
2001-02-23 20:55:21 +03:00
* @ l : a list
* @ data : a search value
*
* Search the list in reverse order for an existing value of @ data
*
* Returns the value associated to @ data or NULL in case of error
*/
void *
2012-09-11 09:26:36 +04:00
xmlListReverseSearch ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lk ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
lk = xmlListLinkReverseSearch ( l , data ) ;
if ( lk )
return ( lk - > data ) ;
return NULL ;
}
/**
* xmlListInsert :
* @ l : a list
* @ data : the data
*
* Insert data in the ordered list at the beginning for this value
*
* Returns 0 in case of success , 1 in case of failure
*/
int
2012-09-11 09:26:36 +04:00
xmlListInsert ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lkPlace , lkNew ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( 1 ) ;
2001-02-23 20:55:21 +03:00
lkPlace = xmlListLowerSearch ( l , data ) ;
/* Add the new link */
lkNew = ( xmlLinkPtr ) xmlMalloc ( sizeof ( xmlLink ) ) ;
if ( lkNew = = NULL ) {
2012-09-11 09:26:36 +04:00
xmlGenericError ( xmlGenericErrorContext ,
2002-09-05 15:33:25 +04:00
" Cannot initialize memory for new link " ) ;
2001-02-23 20:55:21 +03:00
return ( 1 ) ;
}
lkNew - > data = data ;
lkPlace = lkPlace - > prev ;
lkNew - > next = lkPlace - > next ;
( lkPlace - > next ) - > prev = lkNew ;
lkPlace - > next = lkNew ;
lkNew - > prev = lkPlace ;
return 0 ;
}
/**
* xmlListAppend :
* @ l : a list
* @ data : the data
*
* Insert data in the ordered list at the end for this value
*
* Returns 0 in case of success , 1 in case of failure
*/
2012-09-11 09:26:36 +04:00
int xmlListAppend ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lkPlace , lkNew ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( 1 ) ;
2001-02-23 20:55:21 +03:00
lkPlace = xmlListHigherSearch ( l , data ) ;
/* Add the new link */
lkNew = ( xmlLinkPtr ) xmlMalloc ( sizeof ( xmlLink ) ) ;
if ( lkNew = = NULL ) {
2012-09-11 09:26:36 +04:00
xmlGenericError ( xmlGenericErrorContext ,
2002-09-05 15:33:25 +04:00
" Cannot initialize memory for new link " ) ;
2007-05-10 03:53:30 +04:00
return ( 1 ) ;
2001-02-23 20:55:21 +03:00
}
lkNew - > data = data ;
lkNew - > next = lkPlace - > next ;
( lkPlace - > next ) - > prev = lkNew ;
lkPlace - > next = lkNew ;
lkNew - > prev = lkPlace ;
2007-05-10 03:53:30 +04:00
return 0 ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlListDelete :
* @ l : a list
*
* Deletes the list and its associated data
*/
void xmlListDelete ( xmlListPtr l )
{
2004-11-03 14:50:29 +03:00
if ( l = = NULL )
return ;
2001-02-23 20:55:21 +03:00
xmlListClear ( l ) ;
xmlFree ( l - > sentinel ) ;
xmlFree ( l ) ;
}
/**
* xmlListRemoveFirst :
* @ l : a list
* @ data : list data
*
* Remove the first instance associated to data in the list
*
2017-06-17 17:15:09 +03:00
* Returns 1 if a deallocation occurred , or 0 if not found
2001-02-23 20:55:21 +03:00
*/
int
xmlListRemoveFirst ( xmlListPtr l , void * data )
{
xmlLinkPtr lk ;
2012-09-11 09:26:36 +04:00
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
/*Find the first instance of this data */
lk = xmlListLinkSearch ( l , data ) ;
if ( lk ! = NULL ) {
xmlLinkDeallocator ( l , lk ) ;
return 1 ;
}
return 0 ;
}
/**
* xmlListRemoveLast :
* @ l : a list
* @ data : list data
*
* Remove the last instance associated to data in the list
*
2017-06-17 17:15:09 +03:00
* Returns 1 if a deallocation occurred , or 0 if not found
2001-02-23 20:55:21 +03:00
*/
int
xmlListRemoveLast ( xmlListPtr l , void * data )
{
xmlLinkPtr lk ;
2012-09-11 09:26:36 +04:00
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
/*Find the last instance of this data */
lk = xmlListLinkReverseSearch ( l , data ) ;
if ( lk ! = NULL ) {
xmlLinkDeallocator ( l , lk ) ;
return 1 ;
}
return 0 ;
}
/**
* xmlListRemoveAll :
* @ l : a list
* @ data : list data
*
* Remove the all instance associated to data in the list
*
* Returns the number of deallocation , or 0 if not found
*/
int
xmlListRemoveAll ( xmlListPtr l , void * data )
{
int count = 0 ;
2012-09-11 09:26:36 +04:00
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
while ( xmlListRemoveFirst ( l , data ) )
count + + ;
return count ;
}
/**
* xmlListClear :
* @ l : a list
*
* Remove the all data in the list
*/
void
xmlListClear ( xmlListPtr l )
{
2004-11-03 20:07:05 +03:00
xmlLinkPtr lk ;
2012-09-11 09:26:36 +04:00
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ;
lk = l - > sentinel - > next ;
2001-02-23 20:55:21 +03:00
while ( lk ! = l - > sentinel ) {
xmlLinkPtr next = lk - > next ;
xmlLinkDeallocator ( l , lk ) ;
lk = next ;
}
}
/**
* xmlListEmpty :
* @ l : a list
*
2001-07-18 23:30:27 +04:00
* Is the list empty ?
*
2004-11-03 20:07:05 +03:00
* Returns 1 if the list is empty , 0 if not empty and - 1 in case of error
2001-02-23 20:55:21 +03:00
*/
int
xmlListEmpty ( xmlListPtr l )
{
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
return ( l - > sentinel - > next = = l - > sentinel ) ;
}
/**
* xmlListFront :
* @ l : a list
*
2001-07-18 23:30:27 +04:00
* Get the first element in the list
*
2001-02-23 20:55:21 +03:00
* Returns the first element in the list , or NULL
*/
2012-09-11 09:26:36 +04:00
xmlLinkPtr
2001-02-23 20:55:21 +03:00
xmlListFront ( xmlListPtr l )
{
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
return ( l - > sentinel - > next ) ;
}
2012-09-11 09:26:36 +04:00
2001-02-23 20:55:21 +03:00
/**
2001-07-18 23:30:27 +04:00
* xmlListEnd :
2001-02-23 20:55:21 +03:00
* @ l : a list
*
2001-07-18 23:30:27 +04:00
* Get the last element in the list
*
2001-02-23 20:55:21 +03:00
* Returns the last element in the list , or NULL
*/
2012-09-11 09:26:36 +04:00
xmlLinkPtr
2001-02-23 20:55:21 +03:00
xmlListEnd ( xmlListPtr l )
{
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
return ( l - > sentinel - > prev ) ;
}
2012-09-11 09:26:36 +04:00
2001-02-23 20:55:21 +03:00
/**
* xmlListSize :
* @ l : a list
*
2001-07-18 23:30:27 +04:00
* Get the number of elements in the list
*
2004-11-03 20:07:05 +03:00
* Returns the number of elements in the list or - 1 in case of error
2001-02-23 20:55:21 +03:00
*/
int
xmlListSize ( xmlListPtr l )
{
xmlLinkPtr lk ;
int count = 0 ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
/* TODO: keep a counter in xmlList instead */
for ( lk = l - > sentinel - > next ; lk ! = l - > sentinel ; lk = lk - > next , count + + ) ;
return count ;
}
/**
* xmlListPopFront :
* @ l : a list
*
* Removes the first element in the list
*/
void
xmlListPopFront ( xmlListPtr l )
{
if ( ! xmlListEmpty ( l ) )
xmlLinkDeallocator ( l , l - > sentinel - > next ) ;
}
/**
* xmlListPopBack :
* @ l : a list
*
* Removes the last element in the list
*/
void
xmlListPopBack ( xmlListPtr l )
{
if ( ! xmlListEmpty ( l ) )
xmlLinkDeallocator ( l , l - > sentinel - > prev ) ;
}
/**
* xmlListPushFront :
* @ l : a list
* @ data : new data
*
* add the new data at the beginning of the list
*
* Returns 1 if successful , 0 otherwise
*/
int
2012-09-11 09:26:36 +04:00
xmlListPushFront ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lkPlace , lkNew ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
lkPlace = l - > sentinel ;
/* Add the new link */
lkNew = ( xmlLinkPtr ) xmlMalloc ( sizeof ( xmlLink ) ) ;
if ( lkNew = = NULL ) {
2012-09-11 09:26:36 +04:00
xmlGenericError ( xmlGenericErrorContext ,
2002-09-05 15:33:25 +04:00
" Cannot initialize memory for new link " ) ;
2001-02-23 20:55:21 +03:00
return ( 0 ) ;
}
lkNew - > data = data ;
lkNew - > next = lkPlace - > next ;
( lkPlace - > next ) - > prev = lkNew ;
lkPlace - > next = lkNew ;
lkNew - > prev = lkPlace ;
return 1 ;
}
/**
* xmlListPushBack :
* @ l : a list
* @ data : new data
*
* add the new data at the end of the list
*
* Returns 1 if successful , 0 otherwise
*/
int
2012-09-11 09:26:36 +04:00
xmlListPushBack ( xmlListPtr l , void * data )
2001-02-23 20:55:21 +03:00
{
xmlLinkPtr lkPlace , lkNew ;
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
lkPlace = l - > sentinel - > prev ;
/* Add the new link */
if ( NULL = = ( lkNew = ( xmlLinkPtr ) xmlMalloc ( sizeof ( xmlLink ) ) ) ) {
2012-09-11 09:26:36 +04:00
xmlGenericError ( xmlGenericErrorContext ,
2002-09-05 15:33:25 +04:00
" Cannot initialize memory for new link " ) ;
2001-02-23 20:55:21 +03:00
return ( 0 ) ;
}
lkNew - > data = data ;
lkNew - > next = lkPlace - > next ;
( lkPlace - > next ) - > prev = lkNew ;
lkPlace - > next = lkNew ;
lkNew - > prev = lkPlace ;
return 1 ;
}
/**
* xmlLinkGetData :
* @ lk : a link
*
* See Returns .
*
* Returns a pointer to the data referenced from this link
*/
void *
xmlLinkGetData ( xmlLinkPtr lk )
{
2004-11-03 20:07:05 +03:00
if ( lk = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
return lk - > data ;
}
/**
* xmlListReverse :
* @ l : a list
*
* Reverse the order of the elements in the list
*/
void
2004-11-03 20:07:05 +03:00
xmlListReverse ( xmlListPtr l )
{
xmlLinkPtr lk ;
xmlLinkPtr lkPrev ;
if ( l = = NULL )
return ;
lkPrev = l - > sentinel ;
for ( lk = l - > sentinel - > next ; lk ! = l - > sentinel ; lk = lk - > next ) {
lkPrev - > next = lkPrev - > prev ;
lkPrev - > prev = lk ;
lkPrev = lk ;
}
/* Fix up the last node */
2001-02-23 20:55:21 +03:00
lkPrev - > next = lkPrev - > prev ;
lkPrev - > prev = lk ;
}
/**
* xmlListSort :
* @ l : a list
*
* Sort all the elements in the list
*/
void
xmlListSort ( xmlListPtr l )
{
xmlListPtr lTemp ;
2012-09-11 09:26:36 +04:00
2004-11-03 20:07:05 +03:00
if ( l = = NULL )
return ;
2001-02-23 20:55:21 +03:00
if ( xmlListEmpty ( l ) )
return ;
/* I think that the real answer is to implement quicksort, the
* alternative is to implement some list copying procedure which
* would be based on a list copy followed by a clear followed by
* an insert . This is slow . . .
*/
if ( NULL = = ( lTemp = xmlListDup ( l ) ) )
return ;
xmlListClear ( l ) ;
xmlListMerge ( l , lTemp ) ;
xmlListDelete ( lTemp ) ;
return ;
}
/**
* xmlListWalk :
* @ l : a list
* @ walker : a processing function
2001-07-18 23:30:27 +04:00
* @ user : a user parameter passed to the walker function
2001-02-23 20:55:21 +03:00
*
* Walk all the element of the first from first to last and
* apply the walker function to it
*/
void
2017-11-09 19:28:00 +03:00
xmlListWalk ( xmlListPtr l , xmlListWalker walker , void * user ) {
2001-02-23 20:55:21 +03:00
xmlLinkPtr lk ;
2004-11-03 20:07:05 +03:00
if ( ( l = = NULL ) | | ( walker = = NULL ) )
return ;
2001-02-23 20:55:21 +03:00
for ( lk = l - > sentinel - > next ; lk ! = l - > sentinel ; lk = lk - > next ) {
if ( ( walker ( lk - > data , user ) ) = = 0 )
break ;
}
}
/**
* xmlListReverseWalk :
* @ l : a list
* @ walker : a processing function
2001-07-18 23:30:27 +04:00
* @ user : a user parameter passed to the walker function
2001-02-23 20:55:21 +03:00
*
* Walk all the element of the list in reverse order and
* apply the walker function to it
*/
void
2017-11-09 19:28:00 +03:00
xmlListReverseWalk ( xmlListPtr l , xmlListWalker walker , void * user ) {
2001-02-23 20:55:21 +03:00
xmlLinkPtr lk ;
2004-11-03 20:07:05 +03:00
if ( ( l = = NULL ) | | ( walker = = NULL ) )
return ;
2001-02-23 20:55:21 +03:00
for ( lk = l - > sentinel - > prev ; lk ! = l - > sentinel ; lk = lk - > prev ) {
if ( ( walker ( lk - > data , user ) ) = = 0 )
break ;
}
}
/**
* xmlListMerge :
* @ l1 : the original list
* @ l2 : the new list
*
* include all the elements of the second list in the first one and
* clear the second list
*/
void
xmlListMerge ( xmlListPtr l1 , xmlListPtr l2 )
{
xmlListCopy ( l1 , l2 ) ;
xmlListClear ( l2 ) ;
}
/**
* xmlListDup :
* @ old : the list
*
* Duplicate the list
2012-09-11 09:26:36 +04:00
*
2001-02-23 20:55:21 +03:00
* Returns a new copy of the list or NULL in case of error
*/
2012-09-11 09:26:36 +04:00
xmlListPtr
2001-02-23 20:55:21 +03:00
xmlListDup ( const xmlListPtr old )
{
xmlListPtr cur ;
2004-11-03 20:07:05 +03:00
if ( old = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
/* Hmmm, how to best deal with allocation issues when copying
* lists . If there is a de - allocator , should responsibility lie with
* the new list or the old list . Surely not both . I ' ll arbitrarily
* set it to be the old list for the time being whilst I work out
* the answer
*/
if ( NULL = = ( cur = xmlListCreate ( NULL , old - > linkCompare ) ) )
return ( NULL ) ;
if ( 0 ! = xmlListCopy ( cur , old ) )
return NULL ;
return cur ;
}
/**
* xmlListCopy :
* @ cur : the new list
* @ old : the old list
*
* Move all the element from the old list in the new list
2012-09-11 09:26:36 +04:00
*
2001-02-23 20:55:21 +03:00
* Returns 0 in case of success 1 in case of error
*/
int
xmlListCopy ( xmlListPtr cur , const xmlListPtr old )
{
/* Walk the old tree and insert the data into the new one */
xmlLinkPtr lk ;
2004-11-03 20:07:05 +03:00
if ( ( old = = NULL ) | | ( cur = = NULL ) )
return ( 1 ) ;
2001-02-23 20:55:21 +03:00
for ( lk = old - > sentinel - > next ; lk ! = old - > sentinel ; lk = lk - > next ) {
if ( 0 ! = xmlListInsert ( cur , lk - > data ) ) {
xmlListDelete ( cur ) ;
return ( 1 ) ;
}
}
2012-09-11 09:26:36 +04:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
/* xmlListUnique() */
/* xmlListSwap */