00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "util.h"
00017 #include "list.h"
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 typedef struct list_elem {
00028 struct list_desc *mainList;
00029 struct list_elem *prevPtr;
00030 struct list_elem *nextPtr;
00031 lsGeneric userData;
00032 } lsElem;
00033
00034 typedef struct list_desc {
00035 lsElem *topPtr, *botPtr;
00036 int length;
00037 } lsDesc;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 typedef struct gen_desc {
00050 lsDesc *mainList;
00051 lsElem *beforeSpot;
00052 lsElem *afterSpot;
00053 } lsGenInternal;
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 lsList lsCreate(void)
00067
00068
00069
00070
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 }
00079
00080 lsStatus lsDestroy(
00081 lsList list ,
00082 void (*delFunc)(lsGeneric) )
00083
00084
00085
00086
00087
00088
00089 {
00090 lsDesc *realList;
00091 lsElem *index, *temp;
00092
00093 realList = (lsDesc *) list;
00094
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
00103 FREE(realList);
00104 return(LS_OK);
00105 }
00106
00107
00108
00109
00110
00111
00112 static lsGeneric lsIdentity(lsGeneric data)
00113
00114 {
00115 return data;
00116 }
00117
00118 lsList lsCopy(
00119 lsList list ,
00120 lsGeneric (*copyFunc)(lsGeneric) )
00121
00122
00123
00124
00125
00126
00127
00128
00129
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 }
00145
00146
00147
00148
00149
00150
00151 lsStatus lsNewBegin(
00152 lsList list ,
00153 lsGeneric data ,
00154 lsHandle *itemHandle )
00155
00156
00157
00158
00159
00160
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
00172 realList->botPtr = newElem;
00173 } else {
00174
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 }
00182
00183 lsStatus lsNewEnd(
00184 lsList list ,
00185 lsGeneric data ,
00186 lsHandle *itemHandle )
00187
00188
00189
00190
00191
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 }
00210
00211
00212
00213
00214
00215 lsStatus lsFirstItem(
00216 lsList list ,
00217 lsGeneric data ,
00218 lsHandle *itemHandle )
00219
00220
00221
00222
00223
00224
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 }
00238
00239 lsStatus lsLastItem(
00240 lsList list ,
00241 lsGeneric data ,
00242 lsHandle *itemHandle )
00243
00244
00245
00246
00247
00248
00249
00250
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 }
00264
00265
00266
00267
00268 int lsLength(
00269 lsList list )
00270
00271
00272
00273
00274 {
00275 lsDesc *realList = (lsDesc *) list;
00276
00277 return(realList->length);
00278 }
00279
00280
00281
00282
00283
00284
00285 lsStatus lsDelBegin(
00286 lsList list ,
00287 lsGeneric data )
00288
00289
00290
00291
00292
00293
00294 {
00295 lsDesc *realList = (lsDesc *) list;
00296 lsElem *temp;
00297
00298 if (realList->topPtr == NIL(lsElem)) {
00299
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
00308 temp->nextPtr->prevPtr = NIL(lsElem);
00309 } else {
00310
00311 realList->botPtr = NIL(lsElem);
00312 }
00313 FREE(temp);
00314 realList->length -= 1;
00315 }
00316 return LS_OK;
00317 }
00318
00319
00320 lsStatus lsDelEnd(
00321 lsList list ,
00322 lsGeneric data )
00323
00324
00325
00326
00327
00328
00329 {
00330 lsDesc *realList = (lsDesc *) list;
00331 lsElem *temp;
00332
00333 if (realList->botPtr == NIL(lsElem)) {
00334
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
00343 temp->prevPtr->nextPtr = NIL(lsElem);
00344 } else {
00345
00346 realList->topPtr = NIL(lsElem);
00347 }
00348 FREE(temp);
00349 realList->length -= 1;
00350 }
00351 return LS_OK;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361 lsGen lsStart(
00362 lsList list )
00363
00364
00365
00366
00367
00368
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 }
00379
00380 lsGen lsEnd(
00381 lsList list )
00382
00383
00384
00385
00386
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 }
00397
00398 lsGen lsGenHandle(
00399 lsHandle itemHandle ,
00400 lsGeneric data ,
00401 int option )
00402
00403
00404
00405
00406
00407
00408
00409
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 }
00430
00431
00432 lsStatus lsNext(
00433 lsGen generator ,
00434 lsGeneric data ,
00435 lsHandle *itemHandle )
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 {
00446 register lsGenInternal *realGen = (lsGenInternal *) generator;
00447
00448 if (realGen->afterSpot == NIL(lsElem)) {
00449
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
00457 realGen->beforeSpot = realGen->afterSpot;
00458 realGen->afterSpot = realGen->afterSpot->nextPtr;
00459 return LS_OK;
00460 }
00461 }
00462
00463
00464 lsStatus lsPrev(
00465 lsGen generator ,
00466 lsGeneric data ,
00467 lsHandle *itemHandle )
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 {
00478 register lsGenInternal *realGen = (lsGenInternal *) generator;
00479
00480 if (realGen->beforeSpot == NIL(lsElem)) {
00481
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
00489 realGen->afterSpot = realGen->beforeSpot;
00490 realGen->beforeSpot = realGen->beforeSpot->prevPtr;
00491 return LS_OK;
00492 }
00493
00494 }
00495
00496 lsStatus lsInBefore(
00497 lsGen generator ,
00498 lsGeneric data ,
00499 lsHandle *itemHandle )
00500
00501
00502
00503
00504
00505
00506
00507 {
00508 lsGenInternal *realGen = (lsGenInternal *) generator;
00509 lsElem *newElem;
00510
00511 if (realGen->beforeSpot == NIL(lsElem)) {
00512
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
00518 (void) lsNewEnd((lsList) realGen->mainList, data, itemHandle);
00519 realGen->afterSpot = realGen->mainList->botPtr;
00520 return LS_OK;
00521 } else {
00522
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 }
00536
00537 lsStatus lsInAfter(
00538 lsGen generator ,
00539 lsGeneric data ,
00540 lsHandle *itemHandle )
00541
00542
00543
00544
00545
00546
00547
00548 {
00549 lsGenInternal *realGen = (lsGenInternal *) generator;
00550 lsElem *newElem;
00551
00552 if (realGen->beforeSpot == NIL(lsElem)) {
00553
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
00559 (void) lsNewEnd((lsList) realGen->mainList, data, itemHandle);
00560 realGen->afterSpot = realGen->mainList->botPtr;
00561 return LS_OK;
00562 } else {
00563
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 }
00577
00578
00579 lsStatus lsDelBefore(
00580 lsGen generator ,
00581 lsGeneric data )
00582
00583
00584
00585
00586
00587
00588
00589
00590 {
00591 lsGenInternal *realGen = (lsGenInternal *) generator;
00592 lsElem *doomedItem;
00593
00594 if (realGen->beforeSpot == NIL(lsElem)) {
00595
00596 *(void **)data = (lsGeneric) 0;
00597 return LS_BADSTATE;
00598 } else if (realGen->beforeSpot == realGen->mainList->topPtr) {
00599
00600 realGen->beforeSpot = realGen->beforeSpot->prevPtr;
00601 return lsDelBegin((lsList) realGen->mainList, data);
00602 } else if (realGen->beforeSpot == realGen->mainList->botPtr) {
00603
00604 realGen->beforeSpot = realGen->beforeSpot->prevPtr;
00605 return lsDelEnd((lsList) realGen->mainList, data);
00606 } else {
00607
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 }
00618
00619
00620 lsStatus lsDelAfter(
00621 lsGen generator ,
00622 lsGeneric data )
00623
00624
00625
00626
00627
00628
00629
00630
00631 {
00632 lsGenInternal *realGen = (lsGenInternal *) generator;
00633 lsElem *doomedItem;
00634
00635 if (realGen->afterSpot == NIL(lsElem)) {
00636
00637 *(void **)data = (lsGeneric) 0;
00638 return LS_BADSTATE;
00639 } else if (realGen->afterSpot == realGen->mainList->topPtr) {
00640
00641 realGen->afterSpot = realGen->afterSpot->nextPtr;
00642 return lsDelBegin((lsList) realGen->mainList, data);
00643 } else if (realGen->afterSpot == realGen->mainList->botPtr) {
00644
00645 realGen->afterSpot = realGen->afterSpot->nextPtr;
00646 return lsDelEnd((lsList) realGen->mainList, data);
00647 } else {
00648
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 }
00659
00660
00661 lsStatus lsFinish(
00662 lsGen generator )
00663
00664
00665
00666
00667
00668
00669 {
00670 lsGenInternal *realGen = (lsGenInternal *) generator;
00671
00672 FREE(realGen);
00673 return(LS_OK);
00674 }
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 static lsStatus lsGenForm(lsStatus (*userFunc)(lsGeneric, lsGeneric),
00687 lsGeneric arg, lsGen gen,
00688 lsStatus (*gen_func)(lsGen, lsGeneric, lsHandle *),
00689 lsStatus (*del_func)(lsGen, lsGeneric));
00690
00691 lsStatus lsForeach(
00692 lsList list ,
00693 lsStatus (*userFunc)(lsGeneric, lsGeneric) ,
00694 lsGeneric arg )
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 {
00712 return lsGenForm(userFunc, arg, lsStart(list), lsNext, lsDelBefore);
00713 }
00714
00715
00716 lsStatus lsBackeach(
00717 lsList list ,
00718 lsStatus (*userFunc)(lsGeneric, lsGeneric) ,
00719 lsGeneric arg )
00720
00721
00722
00723
00724 {
00725 return lsGenForm(userFunc, arg, lsEnd(list), lsPrev, lsDelAfter);
00726 }
00727
00728
00729 static lsStatus lsGenForm(
00730 lsStatus (*userFunc)(lsGeneric, lsGeneric) ,
00731 lsGeneric arg ,
00732 lsGen gen ,
00733 lsStatus (*gen_func)(lsGen, lsGeneric, lsHandle *)
00734 ,
00735 lsStatus (*del_func)(lsGen, lsGeneric) )
00736
00737
00738
00739
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
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 }
00761
00762
00763 lsList lsQueryHandle(
00764 lsHandle itemHandle )
00765
00766
00767
00768
00769 {
00770 lsElem *realHandle = (lsElem *) itemHandle;
00771
00772 if (realHandle) {
00773 return (lsList) realHandle->mainList;
00774 } else {
00775 return (lsList) 0;
00776 }
00777 }
00778
00779 lsGeneric lsFetchHandle(lsHandle itemHandle)
00780
00781
00782
00783
00784 {
00785 return ((lsElem *) itemHandle)->userData;
00786 }
00787
00788 lsStatus lsRemoveItem(
00789 lsHandle itemHandle ,
00790 lsGeneric userData )
00791
00792
00793
00794
00795
00796
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 }
00806
00807
00808
00809 #define TYPE lsElem
00810 #define SORT lsSortItems
00811 #define NEXT nextPtr
00812 #define FIELD userData
00813 #include "lsort.h"
00814
00815 lsStatus lsSort(
00816 lsList list ,
00817 int (*compare)(lsGeneric, lsGeneric) )
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827 {
00828 lsDesc *realList = (lsDesc *) list;
00829 lsElem *idx, *lastElem;
00830
00831 realList->topPtr = lsSortItems(realList->topPtr, compare,
00832 realList->length);
00833
00834
00835 lastElem = (lsElem *) 0;
00836 for (idx = realList->topPtr; idx != (lsElem *) 0; idx = idx->nextPtr) {
00837 idx->prevPtr = lastElem;
00838 lastElem = idx;
00839 }
00840
00841 realList->botPtr = lastElem;
00842 return LS_OK;
00843 }
00844
00845
00846 lsStatus lsUniq(
00847 lsList list ,
00848 int (*compare)(lsGeneric, lsGeneric) ,
00849 void (*delFunc)(lsGeneric) )
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
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
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
00878 (void) lsDelAfter((lsGen) &realGen, &this_item);
00879 if (delFunc) (*delFunc)(this_item);
00880 } else {
00881
00882 realGen.beforeSpot = realGen.afterSpot;
00883 realGen.afterSpot = realGen.afterSpot->nextPtr;
00884 last_item = this_item;
00885 }
00886 }
00887 }
00888 return LS_OK;
00889 }