Saturday, November 2

A C doubly linked list

List.h:
#ifndef list_h
#define list_h

typedef Handle HList; /* Generic Linked List */

List ListAlloc(const int a_size);

#define ListFree(x) ListFreeX(__FILE__, __LINE__, x)

#endif

#ifdef __cplusplus
extern "C" {
#endif

void ListFreeX(const char *a_filename, int a_linenumber, const List a_hlist);
Bool ListEmpty(const List a_hlist);
int ListSize(const List a_hlist);
Bool ListFindFirst(const List a_hlist);
Bool ListFindPrior(const List a_hlist);
Bool ListFindNext(const List a_hlist);
Bool ListFindLast(const List a_hlist);
Bool ListFind(const List a_hlist,const void* a_pelement,FComp* a_pfcomp);
Bool ListInsertFirst(const List a_hlist,const void* a_pelement);
Bool ListInsertPrior(const List a_hlist,const void* a_pelement);
Bool ListInsertNext(const List a_hlist,const void* a_pelement);
Bool ListInsertLast(const List a_hlist,const void* a_pelement);
Bool ListRetrieve(const List a_hlist,void* a_pelement);
Bool ListUpdate(const List a_hlist,const void* a_pelement);
Bool ListRemove(const List a_hlist,void* a_pelement);
Bool ListMap(const List a_hlist,FMap* a_pfmap,void* a_pcontext);
Bool ListMapPos(const List a_hlist,FMap* a_pfmap,void* a_pcontext);
Bool ListSort(const List a_hlist,FComp* a_pfcomp);
List ListSortCopy(const List a_hlist,FComp* a_pfcomp);
List ListCopyX(const char *a_filename, int a_linenumber, const List a_hlist);
Bool ListAppend(List a_hlist1, const List a_hlist2 );

#ifdef __cplusplus
}
#endif

#define ListCopy(x) ListCopyX(__FILE__,__LINE__, x)
#define ListFilter(a,b,c) ListFilterX(__FILE__, __LINE__, a,b,c)

#endif

List.c:
#include
#include

#include "std.h"
#include "api.h"
#include "list.h"
#include "stdmem.h"
#include "message.h"

typedef struct  LNODE /* list node header */
{
struct LNODE*   pprior; /* prior element */
struct LNODE*   pnext; /* next element */
} lnode;

typedef struct  LIST /* list header */
{
lnode*  pfirst; /* first element */
lnode*  pcur; /* current element */
lnode*  plast; /* last element */
int     size; /* size of elements */
int count; /* # of elements */
Bool managed; /* used by higher-order structures to 'own' lists */
} list;

/***********************************************************************\
* Description *
* Allocates a list. *
* *
* Return value: *
* Failure: 0 *
* Success: Handle of list *
* *
\***********************************************************************/
const int a_size) /* size of elements */
{
register list*   l_plist; /* new list pointer */
assert(a_size>0);

l_plist=(list*)MemAlloc(poolDefault,sizeof(list)); /* allocate */
if (l_plist) /* sucess? */
{
l_plist->pfirst=0; /* empty list */
l_plist->pcur=0; /* no current */
l_plist->plast=0; /* empty list */
l_plist->size=a_size; /* record size */
l_plist->count=0; /* no elements */
l_plist->managed=False; /* not managed by default */
}
return (l_plist); /* return new list */
}

/***********************************************************************\
* Description *
* Determines whether a list is empty. *
* *
* Return value: *
* True: Empty *
* False: Not empty *
* *
\***********************************************************************/
Bool ListEmpty(const List a_hlist) /* handle of list */
{
register list*   l_plist; /* list pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_result=False; /* default */
if (l_plist->pfirst==0) /* any elements? */
l_result=True; /* no */
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Determines the number of elements in the list. *
* *
* Return value: *
* # of elements *
* *
\***********************************************************************/
int ListSize(const List a_hlist)
{
register list*  l_plist; /* list pointer */
register int l_size; /* return value */

assert(a_hlist!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_size=l_plist->count; /* get size */
return (l_size); /* done */
}

/***********************************************************************\
* Description *
* Marks the first element as the current. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListFindFirst(const List a_hlist) /* handle of list */
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_pnode=l_plist->pfirst; /* get first */
l_result=False; /* default */
if (l_pnode) /* node exists? */
{
l_plist->pcur=l_pnode; /* mark as current */
l_result=True; /* success */
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Marks the previous element as the current. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListFindPrior(const List a_hlist) /* handle of list */
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_pnode=l_plist->pcur; /* get current */
l_result=False; /* default */
if (l_pnode) /* node exists? */
{
l_pnode=l_pnode->pprior; /* get previous */
if (l_pnode) /* node exists? */
{
l_plist->pcur=l_pnode; /* mark as current */
l_result=True; /* success */
}
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Marks the following element as the current. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListFindNext(const List a_hlist) /* handle of list */
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_pnode=l_plist->pcur; /* get current */
l_result=False; /* default */
if (l_pnode) /* node exists? */
{
l_pnode=l_pnode->pnext; /* get following */
if (l_pnode) /* node exists? */
{
l_plist->pcur=l_pnode; /* mark as current */
l_result=True; /* success */
}
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Marks the last element as the current. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListFindLast(const List a_hlist) /* handle of list */
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_pnode=l_plist->plast; /* get last */
l_result=False; /* default */
if (l_pnode) /* node exists? */
{
l_plist->pcur=l_pnode; /* mark as current */
l_result=True; /* success */
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Searches the list for a specific element. *
* *
* Return value: *
* True: Found *
* False: Not found *
* *
\***********************************************************************/
Boo) ListFind(const List a_hlist, /* handle of list */
const void* a_pelement, /* element to find */
FComp* a_pfcomp) /* compare function */
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);
assert(a_pelement!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_pnode=l_plist->pfirst; /* start with first */
l_result=False; /* default */
while (l_pnode) /* more nodes? */
{
if (a_pfcomp) /* comp function used? */
{
if (a_pfcomp(a_pelement,l_pnode+1)==0) /* equeal? */
l_result=True; /* success */
}
else
{
if (MemCompare(a_pelement,l_pnode+1,l_plist->size)==0) 
l_result=True; /* success */
}
if (l_result) /* success? */
{
l_plist->pcur=l_pnode; /* mark as current */
break; /* done */
}
else l_pnode=l_pnode->pnext; /* next node */
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Inserts an element at the beginning of the list. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListInsertFirst(
const List a_hlist, /* handle of list */
const void* a_pelement) /* element to insert */
{
register list*   l_plist; /* list pointer */
register int     l_size; /* element size */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);
assert(a_pelement!=0);

l_plist=(list*)a_hlist; /* convert handle */
/* debugger stop here?  you tried to manipulate a managed list. */
assert(l_plist->managed==0);

l_size=l_plist->size; /* get size */
l_pnode=(lnode*)MemAlloc(poolDefault,sizeof(lnode)+l_size); /* allocate */
l_result=False; /* default */
if (l_pnode) /* success? */
{
l_pnode->pprior=0; /* no prior */
l_pnode->pnext=l_plist->pfirst; /* chain */
if (l_plist->pfirst) /* first exists? */
l_plist->pfirst->pprior=l_pnode; /* chain */
else
l_plist->plast=l_pnode; /* mark as last */
l_plist->pfirst=l_pnode; /* mark as first */
l_plist->pcur=l_pnode; /* mark as current */
(l_plist->count)++; /* one more */
MemCopy(l_pnode+1,a_pelement,l_size); /* copy */
l_result=True; /* success */
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Inserts an element before the current in the list. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListInsertPrior(
const List a_hlist, /* handle of list */
const void* a_pelement) /* element to insert */
{
register list*   l_plist; /* list pointer */
register int     l_size; /* element size */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);
assert(a_pelement!=0);

l_plist=(list*)a_hlist; /* convert handle */
/* debugger stop here?  you tried to mainpulate a managed list. */
assert(l_plist->managed==0);

if (l_plist->pcur==l_plist->pfirst) /* current is first? */
l_result=ListInsertFirst(a_hlist,a_pelement); /* insert first */
else
{
l_size=l_plist->size; /* get size */
l_pnode=(lnode*)MemAlloc(poolDefault,sizeof(lnode)+l_size); /* allocate */
l_result=False; /* default */
if (l_pnode) /* success? */
{
l_pnode->pprior=l_plist->pcur->pprior; /* chain */
l_pnode->pnext=l_plist->pcur; /* chain */
l_pnode->pprior->pnext=l_pnode; /* chain prior */
l_pnode->pnext->pprior=l_pnode; /* chain next */
l_plist->pcur=l_pnode; /* mark as current */
(l_plist->count)++; /* one more */
MemCopy(l_pnode+1,a_pelement,l_size); /* copy */
l_result=True; /* success */
}
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Inserts an element after the current in the list. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListInsertNext(
const List a_hlist, /* handle of list */
const void* a_pelement) /* element to insert */
{
register list*   l_plist; /* list pointer */
register int     l_size; /* element size */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);
assert(a_pelement!=0);

l_plist=(list*)a_hlist; /* convert handle */
/* debugger stop here?  you tried to manipulate a managed list. */
assert(l_plist->managed==0);

if (l_plist->pcur==l_plist->plast) /* current is last? */
l_result=ListInsertLast(a_hlist,a_pelement); /* insert last */
else
{
l_size=l_plist->size; /* get size */
l_pnode=(lnode*)MemAlloc(poolDefault,sizeof(lnode)+l_size); /* allocate */
l_result=False; /* default */
if (l_pnode) /* success? */
{
l_pnode->pprior=l_plist->pcur; /* chain */
l_pnode->pnext=l_plist->pcur->pnext; /* chain */
l_pnode->pprior->pnext=l_pnode; /* chain prior */
l_pnode->pnext->pprior=l_pnode; /* chain next */
l_plist->pcur=l_pnode; /* mark as current */
(l_plist->count)++; /* one more */
MemCopy(l_pnode+1,a_pelement,l_size); /* copy */
l_result=True; /* success */
}
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Inserts an element at the end of the list. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListInsertLast(
const List a_hlist, /* handle of list */
const void* a_pelement) /* element to insert */
{
register list*   l_plist; /* list pointer */
register int     l_size; /* element size */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);
assert(a_pelement!=0);
l_plist=(list*)a_hlist; /* convert handle */
/* debugger stop here?  you tried to manipulate a managed list. */
assert(l_plist->managed==0);

l_size=l_plist->size; /* get size */
l_pnode=(lnode*)MemAlloc(poolDefault,sizeof(lnode)+l_size); /* allocate */
l_result=False; /* default */
if (l_pnode) /* success? */
{
l_pnode->pprior=l_plist->plast; /* chain */
l_pnode->pnext=0; /* no next */
if (l_plist->plast) /* last exists? */
l_plist->plast->pnext=l_pnode; /* chain */
else
l_plist->pfirst=l_pnode; /* mark as first */
l_plist->plast=l_pnode; /* mark as last */
l_plist->pcur=l_pnode; /* mark as current */
(l_plist->count)++; /* one more */
MemCopy(l_pnode+1,a_pelement,l_size); /* copy */
l_result=True; /* success */
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Retrieves the current element of the list. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListRetrieve(
const List a_hlist, /* handle of list */
void* a_pelement) /* element pointer */
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);
assert(a_pelement!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_pnode=l_plist->pcur; /* get current */
l_result=False; /* default */
if (l_pnode) /* node exists? */
{
MemCopy(a_pelement,l_pnode+1,l_plist->size); /* copy */
l_result=True; /* success */
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Updates the current element of the list. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListUpdate(
const List a_hlist, /* handle of list */
const void* a_pelement) /* new element */
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);
assert(a_pelement!=0);

l_plist=(list*)a_hlist; /* convert handle */
/* debugger stop here?  you tried to manipulate a managed list. */
assert(l_plist->managed==0);

l_pnode=l_plist->pcur; /* get current */
l_result=False; /* default */
if (l_pnode) /* node exists? */
{
MemCopy(l_pnode+1,a_pelement,l_plist->size); /* copy */
l_result=True; /* success */
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Removes the current element of the list. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListRemove(
const List a_hlist, /* handle of list */
void* a_pelement) /* element pointer */
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);

l_plist=(list*)a_hlist; /* convert pointer */
/* debugger stop here?  you tried to manipulate a managed list. */
assert(l_plist->managed==0);

l_pnode=l_plist->pcur; /* get current */
l_result=False; /* default */
if (l_pnode) /* node exists? */
{
if (l_pnode==l_plist->pfirst) /* is first? */
l_plist->pfirst=l_pnode->pnext; /* move first */
else
l_pnode->pprior->pnext=l_pnode->pnext; /* unchain */
if (l_pnode==l_plist->plast) /* is last? */
l_plist->plast=l_pnode->pprior; /* move last */
else
l_pnode->pnext->pprior=l_pnode->pprior; /* unchain */
l_plist->pcur=l_plist->pfirst; /* first is new current */
(l_plist->count)--; /* one less */
if (a_pelement) /* copy? */
MemCopy(a_pelement,l_pnode+1,l_plist->size); /* yes */
MemFree(l_pnode); /* free element */
l_result=True; /* success */
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Maps a function onto each element of a list. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListMap(
const List a_hlist, /* handle of list */
FMap* a_pfmap, /* map function */
void* a_pcontext) /* context specific */
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register Bool    l_result; /* return value */

assert(a_hlist!=0);
assert(a_pfmap!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_pnode=l_plist->pfirst; /* start at first */
l_result=True; /* default */
while (l_pnode) /* more nodex? */
{
l_result=a_pfmap(l_pnode+1,a_pcontext); /* apply function */
if (!l_result) /* success? */
break; /* no */
l_pnode=l_pnode->pnext; /* next node */
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Maps a function onto each element of a list. *
* Mapping begins on the current node as opposed to the first *
* node. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListMapPos(const List a_hlist, FMap* a_pfmap, void* a_pcontext)
{
  register list*   l_plist; /* list pointer */
  register lnode*  l_pnode; /* node pointer */
  register Bool    l_result; /* return value */

  assert(a_hlist!=0);
  assert(a_pfmap!=0);

  l_plist=(list*)a_hlist; /* convert handle */
  l_pnode=l_plist->pcur; /* start at first */
  l_result=True; /* default */
  while (l_pnode) /* more nodex? */
    {
      l_result=a_pfmap(l_pnode+1,a_pcontext); /* apply function */
      if (!l_result) /* success? */
break; /* no */
      l_pnode=l_pnode->pnext; /* next node */
    }
  return (l_result); /* done */
}

/***********************************************************************\
* Description *
* *
* Return value: *
* *
\***********************************************************************/
Bool ListFilterX(
const char *a_filename, 
int a_linenumber,
const List a_hlist,
FFilter* a_pffilter,
void* a_pcontext
)
{
register list*   l_plist; /* list pointer */
register lnode*  l_pnode; /* node pointer */
register int l_temp; /* filter result */
register Bool l_result; /* return value */
Bool debug;

assert(a_hlist!=0);
assert(a_pffilter!=0);

l_plist=(list*)a_hlist; /* convert handle */

/* debugger stop here?  you tried to manipulate a managed list. */
if (l_plist->managed != 0)
{
MessageError ("Managed list freed manually in file %s, line %d",a_filename,a_linenumber);
assert(False);
}
assert(l_plist->managed==0);

l_pnode=l_plist->pfirst; /* start at first */
l_result=True; /* default */
while (l_pnode) /* more nodex? */
{
l_plist->pcur=l_pnode; /* set as current */
l_temp=a_pffilter(l_pnode+1,a_pcontext); /* apply function */
l_pnode=l_pnode->pnext; /* next node */
if (l_temp<0 class="Apple-tab-span" span="" style="white-space: pre;">
/* failure? */
{
l_result=False; /* yes */
break;
}
if (l_temp==0) /* success? */
{
debug=ListRemove(a_hlist,0); /* delete */
assert(debug);
(void)debug;
}
}
return (l_result); /* done */
}

static FComp* gs_pfcomp=0; /* sort pointer */

/***********************************************************************\
* Description *
* Compares two elements to each other *
* *
* Return value: *
* Negative: < *
* Zero: = *
* Positive: > *
* *
\***********************************************************************/
static int ListSortComp(
const void* a_pleft, /* left element */
const void* a_pright) /* right element */
{
lnode* l_pleft; /* node pointer */
lnode* l_pright; /* node pointer */
int l_result; /* return value */

assert(a_pleft!=0);
assert(a_pright!=0);
assert(gs_pfcomp!=0);

l_pleft=*(lnode**)a_pleft; /* get left */
l_pright=*(lnode**)a_pright; /* get right */
l_result=gs_pfcomp(l_pleft+1,l_pright+1); /* compare */
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Sorts a list in place. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
Bool ListSort(
const List a_hlist, /* handle of list */
FComp* a_pfcomp) /* compare function */
{
Bool l_result; /* return value */
int l_limit; /* list size */
lnode** l_ppnode; /* array pointer */
list*   l_plist; /* list pointer */
lnode* l_pnode; /* node pointer */
int l_index; /* loop counter */

assert(a_hlist!=0);
assert(a_pfcomp!=0);

l_result=True; /* default */
l_limit=ListSize(a_hlist); /* get # of elements */
if (l_limit>1) /* anything to sort? */
{
l_result=False; /* default */
l_ppnode=(lnode**)MemAlloc( /* alloc */
poolDefault,
(l_limit*sizeof(lnode*)));
if (l_ppnode!=0) /* success? */
{
l_plist=(list*)a_hlist; /* convert handle */
l_pnode=l_plist->pfirst;/* start at head */
for (l_index=0; l_index
{
l_ppnode[l_index]=l_pnode; /* store */
l_pnode=l_pnode->pnext; /* get next */
}
gs_pfcomp=a_pfcomp; /* get comp func */
qsort(
(void*)l_ppnode,
(size_t)l_limit,
sizeof(lnode*),
ListSortComp);
gs_pfcomp=0; /* reset comp func */
for (l_index=0; l_index
{
l_ppnode[l_index]->pprior= /* prior */
((l_index==0)
?0
:l_ppnode[l_index-1]);
l_ppnode[l_index]->pnext= /* next */
((l_index==(l_limit-1))
?0
:l_ppnode[l_index+1]);
}
l_plist->pfirst=l_ppnode[0]; /* get new first */
l_plist->plast=l_ppnode[l_limit-1]; /* get new last */
l_result=True; /* success */
MemFree(l_ppnode); /* free */
}
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Creates a sorted copy of a list. *
* *
* Return value: *
* Failure: 0 *
* Success: Handle of list *
* *
\***********************************************************************/
HList ListSortCopy(
const List a_hlist, /* handle of list */
FComp* a_pfcomp) /* compare function */
{
HList l_hlist; /* return value */

assert(a_hlist!=0);
assert(a_pfcomp!=0);

l_hlist=ListCopy(a_hlist); /* make copy */
if (l_hlist!=0) /* success? */
{
if (!ListSort(l_hlist,a_pfcomp))/* sorted? */
{
ListFree(l_hlist); /* no, free */
l_hlist=0; /* fail */
}
}
return (l_hlist); /* done */
}


/***********************************************************************\
* Description *
* Adds the element to a list. *
* *
* Return value: *
* True: Success *
* False: Failure *
* *
\***********************************************************************/
static Bool ListCopyMap(
void* a_pelement, /* element pointer */
void* a_pcontext) /* HList pointer */
{
register HList l_hlist; /* list handle */
register Bool l_result; /* return value */

assert(a_pelement!=0);
assert(a_pcontext!=0);

l_hlist=*(HList*)a_pcontext; /* reinterpret */
l_result=ListInsertLast(l_hlist,a_pelement); /* add to list */
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Creates a copy of a list. *
* *
* Return value: *
* Failure: 0 *
* Success: Handle of list *
* *
\***********************************************************************/
List ListCopyX(
const char *a_filename, 
int a_linenumber,
const HList a_hlist)
{
list*   l_plist; /* list pointer */
HList l_result; /* return value */
void* l_pcontext; /* context pointer */

assert(a_hlist!=0);

l_plist=(list*)a_hlist; /* convert handle */
l_result=ListAlloc(l_plist->size); /* create new list */
if (l_result!=0) /* success? */
{
l_pcontext=&l_result; /* pass result */
if (!ListMap(a_hlist,ListCopyMap,l_pcontext)) /* copy */
{
ListFree(l_result); /* free list */
l_result=0; /* no result */
}
}
return (l_result); /* done */
}

/***********************************************************************\
* Description *
* Appends the contents of one list to another. *
*   NOTE: ListAppend uses ListCopyMap, which creates a new copy of the data
*         at a_hlist2. So... caller needs to be sure to free the memory
*         for a_hlist2 if it's no longer needed.
* *
* Return value: *
* Failure: 0 *
* Success: Handle of list *
* *
\***********************************************************************/
Bool ListAppend(List a_hlist1, const List a_hlist2)
{
list*   l_plist1; /* list pointer */
list*   l_plist2; /* list pointer */
Bool l_result; /* return value */

assert(a_hlist1!=0);
assert(a_hlist2!=0);

l_plist1=(list*)a_hlist1; /* convert handle */
/* debugger stop here?  you tried to manipulate a managed list. */
assert(l_plist1->managed==0);
l_plist2=(list*)a_hlist2; /* convert handle */

/* Both lists should contain the same size elements */
assert( l_plist1->size == l_plist2->size );

l_result = True;
if (!ListMap(l_plist2,ListCopyMap,&l_plist1)) /* copy */
{
l_result=False; /* no result */
}
return (l_result); /* done */
}

#endif

No comments: