blob: 7b077c44620cb095eea5f4d7b426a8929df0d1dc [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2005, 2010 The Regents of the University of California and others
* This material was produced under U.S. Government contract W-7405-ENG-36
* for Los Alamos National Laboratory, which is operated by the University
* of California for the U.S. Department of Energy. The U.S. Government has
* rights to use, reproduce, and distribute this software. NEITHER THE
* GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly
* marked, so as not to confuse it with the version available from LANL.
*
* Additionally, this program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* LA-CC 04-115
******************************************************************************/
/*
* NOTE: This list implementation is not thread safe.
*/
#include <stdio.h>
#include <stdlib.h>
#include "MIList.h"
/*
* Create a new empty list
*/
MIList *
MIListNew(void)
{
MIList * l;
l = (MIList *)malloc(sizeof(MIList));
l->l_head = (MIListElement *)NULL;
l->l_tail = &l->l_head;
l->l_nel = 0;
l->l_scan = NULL;
return l;
}
/*
* Add new element to end of list.
*/
void
MIListAdd(MIList *l, void *v)
{
MIListElement * e;
if ( l == (MIList *)NULL)
return;
e = malloc(sizeof(MIListElement));
e->l_value = v;
e->l_next = (MIListElement *)NULL;
*(l->l_tail) = e;
l->l_tail = &e->l_next;
l->l_nel++;
}
/*
* Add new element to beginning of list (stack emulation).
*/
void
MIListAddFirst(MIList *l, void *v)
{
MIListElement * e;
MIListElement * ep;
if (l == (MIList *)NULL)
return;
e = malloc(sizeof(MIListElement));
e->l_value = v;
e->l_next = l->l_head;
/*
** Adjust tail if necessary.
*/
if
(
(ep = l->l_head) != (MIListElement *)NULL
&&
ep->l_next == (MIListElement *)NULL
)
l->l_tail = &ep->l_next;
l->l_head = e;
l->l_nel++;
}
/*
* Insert new element before given element
*/
void
MIListInsertBefore(MIList *l, void *val, void *new_val)
{
MIListElement ** e;
MIListElement * ne;
if (l == (MIList *)NULL) {
return;
}
/*
* Find the element corresponding to val
*/
for (e = &l->l_head ; *e != (MIListElement *)NULL ; e = &(*e)->l_next) {
if ((*e)->l_value == val) {
break;
}
}
if (*e == NULL) {
return;
}
ne = malloc(sizeof(MIListElement));
ne->l_value = new_val;
ne->l_next = *e;
*e = ne;
l->l_nel++;
}
/*
* Append source list to destination list
*/
void
MIListAppend(MIList *dst, MIList *src)
{
void * e;
MIListSet(src);
while ( (e = MIListGet(src)) != (void *)NULL) {
MIListAdd(dst, e);
}
}
/*
* Remove element from list
*/
void
MIListRemove(MIList *l, void *v)
{
MIListElement * e;
MIListElement * ep;
if ( l == (MIList *)NULL || l->l_nel == 0 ) {
return;
}
for ( ep = e = l->l_head ; e != (MIListElement *)NULL ; )
{
if ( e->l_value != v )
{
if ( ep != e )
ep = ep->l_next;
e = e->l_next;
continue;
}
if ( l->l_scan == e )
l->l_scan = ep;
if ( ep == e )
{
l->l_head = e->l_next;
if ( e->l_next == (MIListElement *)NULL )
l->l_tail = &l->l_head;
}
else
{
ep->l_next = e->l_next;
if ( e->l_next == (MIListElement *)NULL )
l->l_tail = &ep->l_next;
}
free(e);
break;
}
l->l_nel--;
}
/*
* Remove first element of list (stack emulation)
*/
void *
MIListRemoveFirst(MIList *l)
{
void * v;
MIListElement * e;
MIListElement * ep;
if ( l == (MIList *)NULL || l->l_nel == 0 ) {
return (void *)NULL;
}
ep = e = l->l_head;
if ( l->l_scan == e )
l->l_scan = e->l_next;
l->l_head = e->l_next;
if ( e->l_next == (MIListElement *)NULL )
l->l_tail = &l->l_head;
v = e->l_value;
free(e);
l->l_nel--;
return v;
}
/*
* Destroy list and its contents
*/
void
MIListFree(MIList *l, void (*destroy)())
{
MIListElement * ep;
MIListElement * en;
if ( l == (MIList *)NULL )
return;
ep = l->l_head;
while ( ep != (MIListElement *)NULL )
{
en = ep->l_next;
if ( destroy != (void (*)())NULL )
destroy(ep->l_value);
free(ep);
ep = en;
}
free(l);
}
/*
* Initialize list iterator
*/
void
MIListSet(MIList *l)
{
if ( l == (MIList *)NULL )
return;
l->l_scan = l->l_head;
}
/*
* Get next element from list. Returns NULL when there are no more elements
*/
void *
MIListGet(MIList *l)
{
void * val;
MIListElement * le;
if ( l == (MIList *)NULL || l->l_scan == (MIListElement *)NULL ) {
return (void *)NULL;
}
le = l->l_scan;
l->l_scan = le->l_next;
val = le->l_value;
return val;
}
/*
* Get the first element in the list
*/
void *
MIListGetFirst(MIList *l)
{
void * val;
if ( l == (MIList *)NULL || l->l_head == (MIListElement *) NULL) {
return (void *)NULL;
}
val = l->l_head->l_value;
return val;
}
/*
* Check if the list is empty. Returns true (1) if it is.
*/
int
MIListIsEmpty(MIList *l)
{
return (int)(l == (MIList *)NULL || l->l_nel == 0);
}
/*
* Check if element is in the list
*/
int
MIListTest(MIList *l, void *v)
{
MIListElement * e;
if ( l == (MIList *)NULL ) {
return 0;
}
for ( e = l->l_head ; e != (MIListElement *)NULL ; e = e->l_next ) {
if ( e->l_value == v ) {
return 1;
}
}
return 0;
}
/*
* Get the number of elements in the list
*/
int
MIListSize(MIList *l)
{
if ( l == (MIList *)NULL )
return 0;
return l->l_nel;
}