/*
* 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
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
* CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
*
* Author: Gary.Pennington@uk.sun.com
*/
#define IN_LIBXML
#include "libxml.h"
#include <stdlib.h>
#include <string.h>
#include <libxml/xmlmemory.h>
/*
* Type definition are kept internal
*/
struct _xmlLink
{
void *data;
};
struct _xmlList
{
int (*linkCompare)(const void *, const void*);
};
/************************************************************************
* *
* Interfaces *
* *
************************************************************************/
/**
* xmlLinkDeallocator:
* @l: a list
* @lk: a link
*
* Unlink and deallocate @lk from list @l
*/
static void
{
if(l->linkDeallocator)
l->linkDeallocator(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
{
return (-1);
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
*/
static xmlLinkPtr
{
if (l == NULL)
return(NULL);
return lk;
}
/**
* 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
*/
static xmlLinkPtr
{
if (l == NULL)
return(NULL);
return lk;
}
/**
* xmlListSearch:
* @l: a list
* @data: a data
*
* Search data in the list
*
* Returns the link containing the data or NULL
*/
static xmlLinkPtr
{
if (l == NULL)
return(NULL);
return NULL;
else {
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
*/
static xmlLinkPtr
{
if (l == NULL)
return(NULL);
return NULL;
else {
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 l;
"Cannot initialize memory for list");
return (NULL);
}
/* Initialize the list to NULL */
/* Add the sentinel */
"Cannot initialize memory for sentinel");
xmlFree(l);
return (NULL);
}
/* If there is a link deallocator, use it */
if (deallocator != NULL)
l->linkDeallocator = deallocator;
/* If there is a link comparator, use it */
l->linkCompare = compare;
else /* Use our own */
l->linkCompare = xmlLinkCompare;
return l;
}
/**
* 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 *
{
if (l == NULL)
return(NULL);
if (lk)
return NULL;
}
/**
* xmlListReverseSearch:
* @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 *
{
if (l == NULL)
return(NULL);
if (lk)
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
{
if (l == NULL)
return(1);
/* Add the new link */
"Cannot initialize memory for new link");
return (1);
}
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
*/
{
if (l == NULL)
return(1);
/* Add the new link */
"Cannot initialize memory for new link");
return (1);
}
return 0;
}
/**
* xmlListDelete:
* @l: a list
*
* Deletes the list and its associated data
*/
{
if (l == NULL)
return;
xmlListClear(l);
xmlFree(l);
}
/**
* xmlListRemoveFirst:
* @l: a list
* @data: list data
*
* Remove the first instance associated to data in the list
*
* Returns 1 if a deallocation occured, or 0 if not found
*/
int
{
if (l == NULL)
return(0);
/*Find the first instance of this data */
xmlLinkDeallocator(l, lk);
return 1;
}
return 0;
}
/**
* xmlListRemoveLast:
* @l: a list
* @data: list data
*
* Remove the last instance associated to data in the list
*
* Returns 1 if a deallocation occured, or 0 if not found
*/
int
{
if (l == NULL)
return(0);
/*Find the last instance of this data */
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
{
int count=0;
if (l == NULL)
return(0);
while(xmlListRemoveFirst(l, data))
count++;
return count;
}
/**
* xmlListClear:
* @l: a list
*
* Remove the all data in the list
*/
void
{
if (l == NULL)
return;
xmlLinkDeallocator(l, lk);
}
}
/**
* xmlListEmpty:
* @l: a list
*
* Is the list empty ?
*
* Returns 1 if the list is empty, 0 if not empty and -1 in case of error
*/
int
{
if (l == NULL)
return(-1);
}
/**
* xmlListFront:
* @l: a list
*
* Get the first element in the list
*
* Returns the first element in the list, or NULL
*/
{
if (l == NULL)
return(NULL);
}
/**
* xmlListEnd:
* @l: a list
*
* Get the last element in the list
*
* Returns the last element in the list, or NULL
*/
{
if (l == NULL)
return(NULL);
}
/**
* xmlListSize:
* @l: a list
*
* Get the number of elements in the list
*
* Returns the number of elements in the list or -1 in case of error
*/
int
{
int count=0;
if (l == NULL)
return(-1);
/* TODO: keep a counter in xmlList instead */
return count;
}
/**
* xmlListPopFront:
* @l: a list
*
* Removes the first element in the list
*/
void
{
if(!xmlListEmpty(l))
}
/**
* xmlListPopBack:
* @l: a list
*
* Removes the last element in the list
*/
void
{
if(!xmlListEmpty(l))
}
/**
* xmlListPushFront:
* @l: a list
* @data: new data
*
* add the new data at the beginning of the list
*
* Returns 1 if successful, 0 otherwise
*/
int
{
if (l == NULL)
return(0);
/* Add the new link */
"Cannot initialize memory for new link");
return (0);
}
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
{
if (l == NULL)
return(0);
/* Add the new link */
"Cannot initialize memory for new link");
return (0);
}
return 1;
}
/**
* xmlLinkGetData:
* @lk: a link
*
* See Returns.
*
* Returns a pointer to the data referenced from this link
*/
void *
{
return(NULL);
}
/**
* xmlListReverse:
* @l: a list
*
* Reverse the order of the elements in the list
*/
void
{
if (l == NULL)
return;
}
/* Fix up the last node */
}
/**
* xmlListSort:
* @l: a list
*
* Sort all the elements in the list
*/
void
{
if (l == NULL)
return;
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...
*/
return;
xmlListClear(l);
xmlListMerge(l, lTemp);
return;
}
/**
* xmlListWalk:
* @l: a list
* @walker: a processing function
* @user: a user parameter passed to the walker function
*
* Walk all the element of the first from first to last and
* apply the walker function to it
*/
void
return;
break;
}
}
/**
* xmlListReverseWalk:
* @l: a list
* @walker: a processing function
* @user: a user parameter passed to the walker function
*
* Walk all the element of the list in reverse order and
* apply the walker function to it
*/
void
return;
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
{
}
/**
* xmlListDup:
* @old: the list
*
* Duplicate the list
*
* Returns a new copy of the list or NULL in case of error
*/
{
return(NULL);
/* 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
*/
return (NULL);
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
*
* Returns 0 in case of success 1 in case of error
*/
int
{
/* Walk the old tree and insert the data into the new one */
return(1);
return (1);
}
}
return (0);
}
/* xmlListUnique() */
/* xmlListSwap */
#define bottom_list
#include "elfgcchack.h"