Blame list.c

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