#include "util.h"
#include "list.h"
#include "lsort.h"
Go to the source code of this file.
typedef struct gen_desc lsGenInternal |
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 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 }
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 }
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 }
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 }
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 }
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 }
Definition at line 661 of file list.c.
00669 { 00670 lsGenInternal *realGen = (lsGenInternal *) generator; 00671 00672 FREE(realGen); 00673 return(LS_OK); 00674 }
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 }
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 }
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 }
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 }
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 }
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 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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 } }