src/list/list.c File Reference

#include "util.h"
#include "list.h"
#include "lsort.h"
Include dependency graph for list.c:

Go to the source code of this file.

Data Structures

struct  list_elem
struct  list_desc
struct  gen_desc

Defines

#define TYPE   lsElem
#define SORT   lsSortItems
#define NEXT   nextPtr
#define FIELD   userData

Typedefs

typedef struct list_elem lsElem
typedef struct list_desc lsDesc
typedef struct gen_desc lsGenInternal

Functions

lsList lsCreate (void)
lsStatus lsDestroy (lsList list, void(*delFunc)(lsGeneric))
static lsGeneric lsIdentity (lsGeneric data)
lsList lsCopy (lsList list, lsGeneric(*copyFunc)(lsGeneric))
lsStatus lsNewBegin (lsList list, lsGeneric data, lsHandle *itemHandle)
lsStatus lsNewEnd (lsList list, lsGeneric data, lsHandle *itemHandle)
lsStatus lsFirstItem (lsList list, lsGeneric data, lsHandle *itemHandle)
lsStatus lsLastItem (lsList list, lsGeneric data, lsHandle *itemHandle)
int lsLength (lsList list)
lsStatus lsDelBegin (lsList list, lsGeneric data)
lsStatus lsDelEnd (lsList list, lsGeneric data)
lsGen lsStart (lsList list)
lsGen lsEnd (lsList list)
lsGen lsGenHandle (lsHandle itemHandle, lsGeneric data, int option)
lsStatus lsNext (lsGen generator, lsGeneric data, lsHandle *itemHandle)
lsStatus lsPrev (lsGen generator, lsGeneric data, lsHandle *itemHandle)
lsStatus lsInBefore (lsGen generator, lsGeneric data, lsHandle *itemHandle)
lsStatus lsInAfter (lsGen generator, lsGeneric data, lsHandle *itemHandle)
lsStatus lsDelBefore (lsGen generator, lsGeneric data)
lsStatus lsDelAfter (lsGen generator, lsGeneric data)
lsStatus lsFinish (lsGen generator)
static lsStatus lsGenForm (lsStatus(*userFunc)(lsGeneric, lsGeneric), lsGeneric arg, lsGen gen, lsStatus(*gen_func)(lsGen, lsGeneric, lsHandle *), lsStatus(*del_func)(lsGen, lsGeneric))
lsStatus lsForeach (lsList list, lsStatus(*userFunc)(lsGeneric, lsGeneric), lsGeneric arg)
lsStatus lsBackeach (lsList list, lsStatus(*userFunc)(lsGeneric, lsGeneric), lsGeneric arg)
lsList lsQueryHandle (lsHandle itemHandle)
lsGeneric lsFetchHandle (lsHandle itemHandle)
lsStatus lsRemoveItem (lsHandle itemHandle, lsGeneric userData)
lsStatus lsSort (lsList list, int(*compare)(lsGeneric, lsGeneric))
lsStatus lsUniq (lsList list, int(*compare)(lsGeneric, lsGeneric), void(*delFunc)(lsGeneric))

Define Documentation

#define FIELD   userData

Definition at line 812 of file list.c.

#define NEXT   nextPtr

Definition at line 811 of file list.c.

#define SORT   lsSortItems

Definition at line 810 of file list.c.

#define TYPE   lsElem

Definition at line 809 of file list.c.


Typedef Documentation

typedef struct list_desc lsDesc
typedef struct list_elem lsElem
typedef struct gen_desc lsGenInternal

Function Documentation

lsStatus lsBackeach ( lsList  list,
lsStatus(*)(lsGeneric, lsGeneric userFunc,
lsGeneric  arg 
)

Definition at line 716 of file list.c.

00724 {
00725     return lsGenForm(userFunc, arg, lsEnd(list), lsPrev, lsDelAfter);
00726 }

lsList lsCopy ( lsList  list,
lsGeneric(*)(lsGeneric copyFunc 
)

Definition at line 118 of file list.c.

00125                                                                     :
00126  *   lsGeneric copyFunc(data)
00127  *   lsGeneric data;
00128  * This is normally used to make copies of the user data in the new list.
00129  * If no `copyFunc' is provided,  an identity function is used.
00130  */
00131 {
00132     lsList newList;
00133     lsGen gen;
00134     lsGeneric data;
00135 
00136     if (!copyFunc) copyFunc = lsIdentity;
00137     newList = lsCreate();
00138     gen = lsStart(list);
00139     while (lsNext(gen, &data, LS_NH) == LS_OK) {
00140         (void) lsNewEnd(newList, (*copyFunc)(data), LS_NH);
00141     }
00142     lsFinish(gen);
00143     return newList;
00144 }

lsList lsCreate ( void   ) 

Definition at line 66 of file list.c.

00071 {
00072     lsDesc *newList;
00073 
00074     newList = ALLOC(lsDesc, 1);
00075     newList->topPtr = newList->botPtr = NIL(lsElem);
00076     newList->length = 0;
00077     return( (lsList) newList );
00078 }

lsStatus lsDelAfter ( lsGen  generator,
lsGeneric  data 
)

Definition at line 620 of file list.c.

00631 {
00632     lsGenInternal *realGen = (lsGenInternal *) generator;
00633     lsElem *doomedItem;
00634 
00635     if (realGen->afterSpot == NIL(lsElem)) {
00636         /* No item to delete */
00637         *(void **)data = (lsGeneric) 0;
00638         return LS_BADSTATE;
00639     } else if (realGen->afterSpot == realGen->mainList->topPtr) {
00640         /* Delete the first item of the list */
00641         realGen->afterSpot = realGen->afterSpot->nextPtr;
00642         return lsDelBegin((lsList) realGen->mainList, data);
00643     } else if (realGen->afterSpot == realGen->mainList->botPtr) {
00644         /* Delete the last item of the list */
00645         realGen->afterSpot = realGen->afterSpot->nextPtr;
00646         return lsDelEnd((lsList) realGen->mainList, data);
00647     } else {
00648         /* Normal mid list deletion */
00649         doomedItem = realGen->afterSpot;
00650         doomedItem->prevPtr->nextPtr = doomedItem->nextPtr;
00651         doomedItem->nextPtr->prevPtr = doomedItem->prevPtr;
00652         realGen->afterSpot = doomedItem->nextPtr;
00653         realGen->mainList->length -= 1;
00654         *(void **)data = doomedItem->userData;
00655         FREE(doomedItem);
00656         return LS_OK;
00657     }
00658 }

lsStatus lsDelBefore ( lsGen  generator,
lsGeneric  data 
)

Definition at line 579 of file list.c.

00590 {
00591     lsGenInternal *realGen = (lsGenInternal *) generator;
00592     lsElem *doomedItem;
00593 
00594     if (realGen->beforeSpot == NIL(lsElem)) {
00595         /* No item to delete */
00596         *(void **)data = (lsGeneric) 0;
00597         return LS_BADSTATE;
00598     } else if (realGen->beforeSpot == realGen->mainList->topPtr) {
00599         /* Delete the first item of the list */
00600         realGen->beforeSpot = realGen->beforeSpot->prevPtr;
00601         return lsDelBegin((lsList) realGen->mainList, data);
00602     } else if (realGen->beforeSpot == realGen->mainList->botPtr) {
00603         /* Delete the last item of the list */
00604         realGen->beforeSpot = realGen->beforeSpot->prevPtr;
00605         return lsDelEnd((lsList) realGen->mainList, data);
00606     } else {
00607         /* Normal mid list deletion */
00608         doomedItem = realGen->beforeSpot;
00609         doomedItem->prevPtr->nextPtr = doomedItem->nextPtr;
00610         doomedItem->nextPtr->prevPtr = doomedItem->prevPtr;
00611         realGen->beforeSpot = doomedItem->prevPtr;
00612         realGen->mainList->length -= 1;
00613         *(void **)data = doomedItem->userData;
00614         FREE(doomedItem);
00615         return LS_OK;
00616     }
00617 }

lsStatus lsDelBegin ( lsList  list,
lsGeneric  data 
)

Definition at line 285 of file list.c.

00294 {
00295     lsDesc *realList = (lsDesc *) list;
00296     lsElem *temp;
00297 
00298     if (realList->topPtr == NIL(lsElem)) {
00299         /* Nothing to delete */
00300         *(void **)data = (lsGeneric) 0;
00301         return LS_NOMORE;
00302     } else {
00303         *(void **)data = realList->topPtr->userData;
00304         temp = realList->topPtr;
00305         realList->topPtr = realList->topPtr->nextPtr;
00306         if (temp->nextPtr != NIL(lsElem)) {
00307             /* There is something after the first item */
00308             temp->nextPtr->prevPtr = NIL(lsElem);
00309         } else {
00310             /* Nothing after it - bottom becomes null as well */
00311             realList->botPtr = NIL(lsElem);
00312         }
00313         FREE(temp);
00314         realList->length -= 1;
00315     }
00316     return LS_OK;
00317 }

lsStatus lsDelEnd ( lsList  list,
lsGeneric  data 
)

Definition at line 320 of file list.c.

00329 {
00330     lsDesc *realList = (lsDesc *) list;
00331     lsElem *temp;
00332 
00333     if (realList->botPtr == NIL(lsElem)) {
00334         /* Nothing to delete */
00335         *(void **)data = (lsGeneric) 0;
00336         return LS_NOMORE;
00337     } else {
00338         *(void **)data = realList->botPtr->userData;
00339         temp = realList->botPtr;
00340         realList->botPtr = realList->botPtr->prevPtr;
00341         if (temp->prevPtr != NIL(lsElem)) {
00342             /* There is something before the last item */
00343             temp->prevPtr->nextPtr = NIL(lsElem);
00344         } else {
00345             /* Nothing before it - top becomes null as well */
00346             realList->topPtr = NIL(lsElem);
00347         }
00348         FREE(temp);
00349         realList->length -= 1;
00350     }
00351     return LS_OK;
00352 }

lsStatus lsDestroy ( lsList  list,
void(*)(lsGeneric delFunc 
)

Definition at line 80 of file list.c.

00089 {
00090     lsDesc *realList;
00091     lsElem *index, *temp;
00092 
00093     realList = (lsDesc *) list;
00094     /* Get rid of elements */
00095     index = realList->topPtr;
00096     while (index != NIL(lsElem)) {
00097         temp = index;  index = index->nextPtr;
00098         if (delFunc)
00099           (*delFunc)(temp->userData);
00100         FREE(temp);
00101     }
00102     /* Get rid of descriptor */
00103     FREE(realList);
00104     return(LS_OK);
00105 }

lsGen lsEnd ( lsList  list  ) 

Definition at line 380 of file list.c.

00387 {
00388     lsDesc *realList = (lsDesc *) list;
00389     lsGenInternal *newGen;
00390 
00391     newGen = ALLOC(lsGenInternal, 1);
00392     newGen->mainList = realList;
00393     newGen->beforeSpot = realList->botPtr;
00394     newGen->afterSpot = NIL(lsElem);
00395     return (lsGen) newGen;
00396 }

lsGeneric lsFetchHandle ( lsHandle  itemHandle  ) 

Definition at line 779 of file list.c.

00784 {
00785     return ((lsElem *) itemHandle)->userData;
00786 }

lsStatus lsFinish ( lsGen  generator  ) 

Definition at line 661 of file list.c.

00669 {
00670     lsGenInternal *realGen = (lsGenInternal *) generator;
00671 
00672     FREE(realGen);
00673     return(LS_OK);
00674 }

lsStatus lsFirstItem ( lsList  list,
lsGeneric  data,
lsHandle itemHandle 
)

Definition at line 215 of file list.c.

00225 {
00226     lsDesc *realList = (lsDesc *) list;
00227 
00228     if (realList->topPtr != NIL(lsElem)) {
00229         *(void **)data = realList->topPtr->userData;
00230         if (itemHandle) *itemHandle = (lsHandle) (realList->topPtr);
00231         return(LS_OK);
00232     } else {
00233         *(void **)data = (lsGeneric) 0;
00234         if (itemHandle) *itemHandle = (lsHandle) 0;
00235         return(LS_NOMORE);
00236     }
00237 }

lsStatus lsForeach ( lsList  list,
lsStatus(*)(lsGeneric, lsGeneric userFunc,
lsGeneric  arg 
)

Definition at line 691 of file list.c.

00698                                  :
00699  *   lsStatus userFunc(data, arg)
00700  *   lsGeneric data;
00701  *   lsGeneric arg;
00702  * `data' will be the user data associated with the item generated.
00703  * `arg' will be the same pointer provided to lsForeach.  The
00704  * routine should return LS_OK to continue the generation,  LS_STOP
00705  * to stop generating items,  and LS_DELETE to delete the item
00706  * from the list.  If the generation was stopped prematurely,
00707  * the routine will return LS_STOP.  If the user provided function
00708  * does not return an appropriate value,  the routine will return
00709  * LS_BADPARAM.
00710  */
00711 {
00712     return lsGenForm(userFunc, arg, lsStart(list), lsNext, lsDelBefore);
00713 }

static lsStatus lsGenForm ( lsStatus(*)(lsGeneric, lsGeneric userFunc,
lsGeneric  arg,
lsGen  gen,
lsStatus(*)(lsGen, lsGeneric, lsHandle *)  gen_func,
lsStatus(*)(lsGen, lsGeneric del_func 
) [static]

Definition at line 729 of file list.c.

00740 {
00741     lsGeneric data;
00742 
00743     while ((*gen_func)(gen, &data, LS_NH) == LS_OK) {
00744         switch ((*userFunc)(data, arg)) {
00745         case LS_OK:
00746             /* Nothing */
00747             break;
00748         case LS_STOP:
00749             (void) lsFinish(gen);
00750             return LS_STOP;
00751         case LS_DELETE:
00752             (*del_func)(gen, &data);
00753             break;
00754         default:
00755             return LS_BADPARAM;
00756         }
00757     }
00758     (void) lsFinish(gen);
00759     return LS_OK;
00760 }

lsGen lsGenHandle ( lsHandle  itemHandle,
lsGeneric  data,
int  option 
)

Definition at line 398 of file list.c.

00406                                           :  the generator
00407  * should be freed using lsFinish.  The 'option' parameter
00408  * determines whether the generator spot is before or after
00409  * the handle item.
00410  */
00411 {
00412     lsElem *realItem = (lsElem *) itemHandle;
00413     lsGenInternal *newGen;
00414 
00415     newGen = ALLOC(lsGenInternal, 1);
00416     newGen->mainList = realItem->mainList;
00417     *(void **)data = realItem->userData;
00418     if (option & LS_BEFORE) {
00419         newGen->beforeSpot = realItem->prevPtr;
00420         newGen->afterSpot = realItem;
00421     } else if (option & LS_AFTER) {
00422         newGen->beforeSpot = realItem;
00423         newGen->afterSpot = realItem->nextPtr;
00424     } else {
00425         FREE(newGen);
00426         newGen = (lsGenInternal *) 0;
00427     }
00428     return ( (lsGen) newGen );
00429 }

static lsGeneric lsIdentity ( lsGeneric  data  )  [static]

Definition at line 112 of file list.c.

00114 {
00115     return data;
00116 }

lsStatus lsInAfter ( lsGen  generator,
lsGeneric  data,
lsHandle itemHandle 
)

Definition at line 537 of file list.c.

00548 {
00549     lsGenInternal *realGen = (lsGenInternal *) generator;
00550     lsElem *newElem;
00551 
00552     if (realGen->beforeSpot == NIL(lsElem)) {
00553         /* Item added to the beginning of the list */
00554         (void) lsNewBegin((lsList) realGen->mainList, data, itemHandle);
00555         realGen->beforeSpot = realGen->mainList->topPtr;
00556         return LS_OK;
00557     } else if (realGen->afterSpot == NIL(lsElem)) {
00558         /* Item added to the end of the list */
00559         (void) lsNewEnd((lsList) realGen->mainList, data, itemHandle);
00560         realGen->afterSpot = realGen->mainList->botPtr;
00561         return LS_OK;
00562     } else {
00563         /* Item added in the middle of the list */
00564         newElem = ALLOC(lsElem, 1);
00565         newElem->mainList = realGen->mainList;
00566         newElem->prevPtr = realGen->beforeSpot;
00567         newElem->nextPtr = realGen->afterSpot;
00568         newElem->userData = data;
00569         realGen->beforeSpot->nextPtr = newElem;
00570         realGen->afterSpot->prevPtr = newElem;
00571         realGen->afterSpot = newElem;
00572         realGen->mainList->length += 1;
00573         if (itemHandle) *itemHandle = (lsHandle) newElem;
00574         return LS_OK;
00575     }
00576 }

lsStatus lsInBefore ( lsGen  generator,
lsGeneric  data,
lsHandle itemHandle 
)

Definition at line 496 of file list.c.

00507 {
00508     lsGenInternal *realGen = (lsGenInternal *) generator;
00509     lsElem *newElem;
00510 
00511     if (realGen->beforeSpot == NIL(lsElem)) {
00512         /* Item added to the beginning of the list */
00513         (void) lsNewBegin((lsList) realGen->mainList, data, itemHandle);
00514         realGen->beforeSpot = realGen->mainList->topPtr;
00515         return LS_OK;
00516     } else if (realGen->afterSpot == NIL(lsElem)) {
00517         /* Item added to the end of the list */
00518         (void) lsNewEnd((lsList) realGen->mainList, data, itemHandle);
00519         realGen->afterSpot = realGen->mainList->botPtr;
00520         return LS_OK;
00521     } else {
00522         /* Item added in the middle of the list */
00523         newElem = ALLOC(lsElem, 1);
00524         newElem->mainList = realGen->mainList;
00525         newElem->prevPtr = realGen->beforeSpot;
00526         newElem->nextPtr = realGen->afterSpot;
00527         newElem->userData = data;
00528         realGen->beforeSpot->nextPtr = newElem;
00529         realGen->afterSpot->prevPtr = newElem;
00530         realGen->beforeSpot = newElem;
00531         realGen->mainList->length += 1;
00532         if (itemHandle) *itemHandle = (lsHandle) newElem;
00533         return LS_OK;
00534     }
00535 }

lsStatus lsLastItem ( lsList  list,
lsGeneric  data,
lsHandle itemHandle 
)

Definition at line 239 of file list.c.

00251 {
00252     lsDesc *realList = (lsDesc *) list;
00253 
00254     if (realList->botPtr != NIL(lsElem)) {
00255         *(void **)data = realList->botPtr->userData;
00256         if (itemHandle) *itemHandle = (lsHandle) (realList->botPtr);
00257         return(LS_OK);
00258     } else {
00259         *(void **)data = (lsGeneric) 0;
00260         if (itemHandle) *itemHandle = (lsHandle) 0;
00261         return(LS_NOMORE);
00262     }
00263 }

int lsLength ( lsList  list  ) 

Definition at line 268 of file list.c.

00274 {
00275     lsDesc *realList = (lsDesc *) list;
00276 
00277     return(realList->length);
00278 }

lsStatus lsNewBegin ( lsList  list,
lsGeneric  data,
lsHandle itemHandle 
)

Definition at line 151 of file list.c.

00161 {
00162     lsDesc *realList = (lsDesc *) list;
00163     lsElem *newElem;
00164 
00165     newElem = ALLOC(lsElem, 1);
00166     newElem->userData = data;
00167     newElem->nextPtr = realList->topPtr;
00168     newElem->prevPtr = NIL(lsElem);
00169     newElem->mainList = realList;
00170     if (realList->topPtr == NIL(lsElem)) {
00171         /* The new item is both the top and bottom element */
00172         realList->botPtr = newElem;
00173     } else {
00174         /* There was a top element - make its prev correct */
00175         realList->topPtr->prevPtr = newElem;
00176     }
00177     realList->topPtr = newElem;
00178     realList->length += 1;
00179     if (itemHandle) *itemHandle = (lsHandle) newElem;
00180     return(LS_OK);
00181 }

lsStatus lsNewEnd ( lsList  list,
lsGeneric  data,
lsHandle itemHandle 
)

Definition at line 183 of file list.c.

00192 {
00193     lsDesc *realList = (lsDesc *) list;
00194     lsElem *newElem;
00195 
00196     newElem = ALLOC(lsElem, 1);
00197     newElem->userData = data;
00198     newElem->prevPtr = realList->botPtr;
00199     newElem->nextPtr = NIL(lsElem);
00200     newElem->mainList = realList;
00201     if (realList->topPtr == NIL(lsElem))
00202       realList->topPtr = newElem;
00203     if (realList->botPtr != NIL(lsElem))
00204       realList->botPtr->nextPtr = newElem;
00205     realList->botPtr = newElem;
00206     realList->length += 1;
00207     if (itemHandle) *itemHandle = (lsHandle) newElem;
00208     return(LS_OK);
00209 }

lsStatus lsNext ( lsGen  generator,
lsGeneric  data,
lsHandle itemHandle 
)

Definition at line 432 of file list.c.

00445 {
00446     register lsGenInternal *realGen = (lsGenInternal *) generator;
00447 
00448     if (realGen->afterSpot == NIL(lsElem)) {
00449         /* No more stuff to generate */
00450         *(void **) data = (lsGeneric) 0;
00451         if (itemHandle) *itemHandle = (lsHandle) 0;
00452         return LS_NOMORE;
00453     } else {
00454         *(void **) data = realGen->afterSpot->userData;
00455         if (itemHandle) *itemHandle = (lsHandle) (realGen->afterSpot);
00456         /* Move the pointers down one */
00457         realGen->beforeSpot = realGen->afterSpot;
00458         realGen->afterSpot = realGen->afterSpot->nextPtr;
00459         return LS_OK;
00460     }
00461 }

lsStatus lsPrev ( lsGen  generator,
lsGeneric  data,
lsHandle itemHandle 
)

Definition at line 464 of file list.c.

00477 {
00478     register lsGenInternal *realGen = (lsGenInternal *) generator;
00479 
00480     if (realGen->beforeSpot == NIL(lsElem)) {
00481         /* No more stuff to generate */
00482         *(void **) data = (lsGeneric) 0;
00483         if (itemHandle) *itemHandle = (lsHandle) 0;
00484         return LS_NOMORE;
00485     } else {
00486         *(void **) data = realGen->beforeSpot->userData;
00487         if (itemHandle) *itemHandle = (lsHandle) (realGen->beforeSpot);
00488         /* Move the pointers down one */
00489         realGen->afterSpot = realGen->beforeSpot;
00490         realGen->beforeSpot = realGen->beforeSpot->prevPtr;
00491         return LS_OK;
00492     }
00493 
00494 }

lsList lsQueryHandle ( lsHandle  itemHandle  ) 

Definition at line 763 of file list.c.

00769 {
00770     lsElem *realHandle = (lsElem *) itemHandle;
00771 
00772     if (realHandle) {
00773         return (lsList) realHandle->mainList;
00774     } else {
00775         return (lsList) 0;
00776     }
00777 }

lsStatus lsRemoveItem ( lsHandle  itemHandle,
lsGeneric  userData 
)

Definition at line 788 of file list.c.

00797 {
00798     lsElem *realItem = (lsElem *) itemHandle;
00799     lsGenInternal gen;
00800 
00801     gen.mainList = realItem->mainList;
00802     gen.beforeSpot = realItem->prevPtr;
00803     gen.afterSpot = realItem;
00804     return lsDelAfter((lsGen) &gen, userData);
00805 }

lsStatus lsSort ( lsList  list,
int(*)(lsGeneric, lsGeneric compare 
)

Definition at line 815 of file list.c.

00820                                                                         :
00821  *   int compare(item1, item2)
00822  *   lsGeneric item1, item2;
00823  * The routine should return -1 if item1 is less than item2, 0 if
00824  * they are equal,  and 1 if item1 is greater than item2.
00825  * The routine uses a generic merge sort written by Rick Rudell.
00826  */
00827 {
00828     lsDesc *realList = (lsDesc *) list;
00829     lsElem *idx, *lastElem;
00830 
00831     realList->topPtr = lsSortItems(realList->topPtr, compare,
00832                                   realList->length);
00833 
00834     /* Forward pointers are correct - fix backward pointers */
00835     lastElem = (lsElem *) 0;
00836     for (idx = realList->topPtr;  idx != (lsElem *) 0;  idx = idx->nextPtr) {
00837         idx->prevPtr = lastElem;
00838         lastElem = idx;
00839     }
00840     /* lastElem is last item in list */
00841     realList->botPtr = lastElem;
00842     return LS_OK;
00843 }

lsGen lsStart ( lsList  list  ) 

Definition at line 361 of file list.c.

00369 {
00370     lsDesc *realList = (lsDesc *) list;
00371     lsGenInternal *newGen;
00372 
00373     newGen = ALLOC(lsGenInternal, 1);
00374     newGen->mainList = realList;
00375     newGen->beforeSpot = NIL(lsElem);
00376     newGen->afterSpot = realList->topPtr;
00377     return ( (lsGen) newGen );
00378 }

lsStatus lsUniq ( lsList  list,
int(*)(lsGeneric, lsGeneric compare,
void(*)(lsGeneric delFunc 
)

Definition at line 846 of file list.c.

00852                                              :
00853  *   int compare(item1, item2)
00854  *   lsGeneric item1, item2;
00855  * The routine should return -1 if item1 is less than item2, 0 if
00856  * they are equal,  and 1 if item1 is greater than item2. `delFunc'
00857  * will be called with a pointer to a user data item for each
00858  * duplicate destroyed.  `delFunc' can be zero if no clean up
00859  * is required.
00860  */
00861 {
00862     lsGeneric this_item, last_item;
00863     lsGenInternal realGen;
00864     lsDesc *realList = (lsDesc *) list;
00865 
00866     if (realList->length > 1) {
00867         last_item = realList->topPtr->userData;
00868 
00869         /* Inline creation of generator */
00870         realGen.mainList = realList;
00871         realGen.beforeSpot = realList->topPtr;
00872         realGen.afterSpot = realList->topPtr->nextPtr;
00873 
00874         while (realGen.afterSpot) {
00875             this_item = realGen.afterSpot->userData;
00876             if ((*compare)(this_item, last_item) == 0) {
00877                 /* Duplicate -- eliminate */
00878                 (void) lsDelAfter((lsGen) &realGen, &this_item);
00879                 if (delFunc) (*delFunc)(this_item);
00880             } else {
00881                 /* Move generator forward */
00882                 realGen.beforeSpot = realGen.afterSpot;
00883                 realGen.afterSpot = realGen.afterSpot->nextPtr;
00884                 last_item = this_item;
00885             }
00886         }
00887     }
00888     return LS_OK;
00889 }
}


Generated on Tue Jan 12 13:57:24 2010 for glu-2.2 by  doxygen 1.6.1