00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <string.h>
00014
00015
00016
00017
00018 #include "set.h"
00019 #include "mem.h"
00020
00021 #ifdef USE_DMALLOC
00022 #include "dmalloc.h"
00023 #endif
00024
00025 #ifndef qhDEFqhull
00026 typedef struct ridgeT ridgeT;
00027 typedef struct facetT facetT;
00028 void qh_errexit(int exitcode, facetT *, ridgeT *);
00029 #endif
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #define SETsizeaddr_(set) (&((set)->e[(set)->maxsize].i))
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 void qh_setaddnth(setT **setp, int nth, void *newelem) {
00064 int *sizep, oldsize, i;
00065 void **oldp, **newp;
00066
00067 if (!*setp || !*(sizep= SETsizeaddr_(*setp))) {
00068 qh_setlarger(setp);
00069 sizep= SETsizeaddr_(*setp);
00070 }
00071 oldsize= *sizep - 1;
00072 if (nth < 0 || nth > oldsize) {
00073 fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
00074 qh_setprint (qhmem.ferr, "", *setp);
00075 qh_errexit (qhmem_ERRqhull, NULL, NULL);
00076 }
00077 (*sizep)++;
00078 oldp= SETelemaddr_(*setp, oldsize, void);
00079 newp= oldp+1;
00080 for (i= oldsize-nth+1; i--; )
00081 *(newp--)= *(oldp--);
00082 *newp= newelem;
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 void qh_setaddsorted(setT **setp, void *newelem) {
00102 int newindex=0;
00103 void *elem, **elemp;
00104
00105 FOREACHelem_(*setp) {
00106 if (elem < newelem)
00107 newindex++;
00108 else if (elem == newelem)
00109 return;
00110 else
00111 break;
00112 }
00113 qh_setaddnth(setp, newindex, newelem);
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 void qh_setappend(setT **setp, void *newelem) {
00133 int *sizep;
00134 void **endp;
00135
00136 if (!newelem)
00137 return;
00138 if (!*setp || !*(sizep= SETsizeaddr_(*setp))) {
00139 qh_setlarger(setp);
00140 sizep= SETsizeaddr_(*setp);
00141 }
00142 *(endp= &((*setp)->e[(*sizep)++ - 1].p))= newelem;
00143 *(++endp)= NULL;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 void qh_setappend_set(setT **setp, setT *setA) {
00162 int *sizep, sizeA, size;
00163 setT *oldset;
00164
00165 if (!setA)
00166 return;
00167 SETreturnsize_(setA, sizeA);
00168 if (!*setp)
00169 *setp= qh_setnew (sizeA);
00170 sizep= SETsizeaddr_(*setp);
00171 if (!(size= *sizep))
00172 size= (*setp)->maxsize;
00173 else
00174 size--;
00175 if (size + sizeA > (*setp)->maxsize) {
00176 oldset= *setp;
00177 *setp= qh_setcopy (oldset, sizeA);
00178 qh_setfree (&oldset);
00179 sizep= SETsizeaddr_(*setp);
00180 }
00181 *sizep= size+sizeA+1;
00182 if (sizeA > 0)
00183 memcpy((char *)&((*setp)->e[size].p), (char *)&(setA->e[0].p), SETelemsize *(sizeA+1));
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 void qh_setappend2ndlast(setT **setp, void *newelem) {
00204 int *sizep;
00205 void **endp, **lastp;
00206
00207 if (!*setp || !*(sizep= SETsizeaddr_(*setp))) {
00208 qh_setlarger(setp);
00209 sizep= SETsizeaddr_(*setp);
00210 }
00211 endp= SETelemaddr_(*setp, (*sizep)++ -1, void);
00212 lastp= endp-1;
00213 *(endp++)= *lastp;
00214 *endp= NULL;
00215 *lastp= newelem;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 void qh_setcheck(setT *set, char *tname, int id) {
00230 int maxsize, size;
00231 int waserr= 0;
00232
00233 if (!set)
00234 return;
00235 SETreturnsize_(set, size);
00236 maxsize= set->maxsize;
00237 if (size > maxsize || !maxsize) {
00238 fprintf (qhmem.ferr, "qhull internal error (qh_setcheck): actual size %d of %s%d is greater than max size %d\n",
00239 size, tname, id, maxsize);
00240 waserr= 1;
00241 }else if (set->e[size].p) {
00242 fprintf (qhmem.ferr, "qhull internal error (qh_setcheck): %s%d (size %d max %d) is not null terminated.\n",
00243 tname, id, maxsize, size-1);
00244 waserr= 1;
00245 }
00246 if (waserr) {
00247 qh_setprint (qhmem.ferr, "ERRONEOUS", set);
00248 qh_errexit (qhmem_ERRqhull, NULL, NULL);
00249 }
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 void qh_setcompact(setT *set) {
00272 int size;
00273 void **destp, **elemp, **endp, **firstp;
00274
00275 if (!set)
00276 return;
00277 SETreturnsize_(set, size);
00278 destp= elemp= firstp= SETaddr_(set, void);
00279 endp= destp + size;
00280 while (1) {
00281 if (!(*destp++ = *elemp++)) {
00282 destp--;
00283 if (elemp > endp)
00284 break;
00285 }
00286 }
00287 qh_settruncate (set, destp-firstp);
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 setT *qh_setcopy(setT *set, int extra) {
00306 setT *newset;
00307 int size;
00308
00309 if (extra < 0)
00310 extra= 0;
00311 SETreturnsize_(set, size);
00312 newset= qh_setnew(size+extra);
00313 *SETsizeaddr_(newset)= size+1;
00314 memcpy((char *)&(newset->e[0].p), (char *)&(set->e[0].p), SETelemsize *(size+1));
00315 return (newset);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 void *qh_setdel(setT *set, void *oldelem) {
00340 void **elemp, **lastp;
00341 int *sizep;
00342
00343 if (!set)
00344 return NULL;
00345 elemp= SETaddr_(set, void);
00346 while (*elemp != oldelem && *elemp)
00347 elemp++;
00348 if (*elemp) {
00349 sizep= SETsizeaddr_(set);
00350 if (!(*sizep)--)
00351 *sizep= set->maxsize;
00352 lastp= SETelemaddr_(set, *sizep-1, void);
00353 *elemp= *lastp;
00354 *lastp= NULL;
00355 return oldelem;
00356 }
00357 return NULL;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 void *qh_setdellast(setT *set) {
00379 int setsize;
00380 int maxsize;
00381 int *sizep;
00382 void *returnvalue;
00383
00384 if (!set || !(set->e[0].p))
00385 return NULL;
00386 sizep= SETsizeaddr_(set);
00387 if ((setsize= *sizep)) {
00388 returnvalue= set->e[setsize - 2].p;
00389 set->e[setsize - 2].p= NULL;
00390 (*sizep)--;
00391 }else {
00392 maxsize= set->maxsize;
00393 returnvalue= set->e[maxsize - 1].p;
00394 set->e[maxsize - 1].p= NULL;
00395 *sizep= maxsize;
00396 }
00397 return returnvalue;
00398 }
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 void *qh_setdelnth(setT *set, int nth) {
00419 void **elemp, **lastp, *elem;
00420 int *sizep;
00421
00422
00423 elemp= SETelemaddr_(set, nth, void);
00424 sizep= SETsizeaddr_(set);
00425 if (!(*sizep)--)
00426 *sizep= set->maxsize;
00427 if (nth < 0 || nth >= *sizep) {
00428 fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
00429 qh_setprint (qhmem.ferr, "", set);
00430 qh_errexit (qhmem_ERRqhull, NULL, NULL);
00431 }
00432 lastp= SETelemaddr_(set, *sizep-1, void);
00433 elem= *elemp;
00434 *elemp= *lastp;
00435 *lastp= NULL;
00436 return elem;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 void *qh_setdelnthsorted(setT *set, int nth) {
00460 void **newp, **oldp, *elem;
00461 int *sizep;
00462
00463 sizep= SETsizeaddr_(set);
00464 if (nth < 0 || (*sizep && nth >= *sizep-1) || nth >= set->maxsize) {
00465 fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
00466 qh_setprint (qhmem.ferr, "", set);
00467 qh_errexit (qhmem_ERRqhull, NULL, NULL);
00468 }
00469 newp= SETelemaddr_(set, nth, void);
00470 elem= *newp;
00471 oldp= newp+1;
00472 while ((*(newp++)= *(oldp++)))
00473 ;
00474 if (!(*sizep)--)
00475 *sizep= set->maxsize;
00476 return elem;
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 void *qh_setdelsorted(setT *set, void *oldelem) {
00498 void **newp, **oldp;
00499 int *sizep;
00500
00501 if (!set)
00502 return NULL;
00503 newp= SETaddr_(set, void);
00504 while(*newp != oldelem && *newp)
00505 newp++;
00506 if (*newp) {
00507 oldp= newp+1;
00508 while ((*(newp++)= *(oldp++)))
00509 ;
00510 sizep= SETsizeaddr_(set);
00511 if (!(*sizep)--)
00512 *sizep= set->maxsize;
00513 return oldelem;
00514 }
00515 return NULL;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 setT *qh_setduplicate (setT *set, int elemsize) {
00535 void *elem, **elemp, *newElem;
00536 setT *newSet;
00537 int size;
00538
00539 if (!(size= qh_setsize (set)))
00540 return NULL;
00541 newSet= qh_setnew (size);
00542 FOREACHelem_(set) {
00543 newElem= qh_memalloc (elemsize);
00544 memcpy (newElem, elem, elemsize);
00545 qh_setappend (&newSet, newElem);
00546 }
00547 return newSet;
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 int qh_setequal(setT *setA, setT *setB) {
00566 void **elemAp, **elemBp;
00567 int sizeA, sizeB;
00568
00569 SETreturnsize_(setA, sizeA);
00570 SETreturnsize_(setB, sizeB);
00571 if (sizeA != sizeB)
00572 return 0;
00573 if (!sizeA)
00574 return 1;
00575 elemAp= SETaddr_(setA, void);
00576 elemBp= SETaddr_(setB, void);
00577 if (!memcmp((char *)elemAp, (char *)elemBp, sizeA*SETelemsize))
00578 return 1;
00579 return 0;
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 int qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB) {
00604 void **elemA, **elemB;
00605 int skip=0;
00606
00607 elemA= SETaddr_(setA, void);
00608 elemB= SETaddr_(setB, void);
00609 while (1) {
00610 if (*elemA == skipelemA) {
00611 skip++;
00612 elemA++;
00613 }
00614 if (skipelemB) {
00615 if (*elemB == skipelemB) {
00616 skip++;
00617 elemB++;
00618 }
00619 }else if (*elemA != *elemB) {
00620 skip++;
00621 if (!(skipelemB= *elemB++))
00622 return 0;
00623 }
00624 if (!*elemA)
00625 break;
00626 if (*elemA++ != *elemB++)
00627 return 0;
00628 }
00629 if (skip != 2 || *elemB)
00630 return 0;
00631 return 1;
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 int qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB) {
00652 void **elemA, **elemB, **skipAp, **skipBp;
00653
00654 elemA= SETaddr_(setA, void);
00655 elemB= SETaddr_(setB, void);
00656 skipAp= SETelemaddr_(setA, skipA, void);
00657 skipBp= SETelemaddr_(setB, skipB, void);
00658 while (1) {
00659 if (elemA == skipAp)
00660 elemA++;
00661 if (elemB == skipBp)
00662 elemB++;
00663 if (!*elemA)
00664 break;
00665 if (*elemA++ != *elemB++)
00666 return 0;
00667 }
00668 if (*elemB)
00669 return 0;
00670 return 1;
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 void qh_setfree(setT **setp) {
00691 int size;
00692 void **freelistp;
00693
00694 if (*setp) {
00695 size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize;
00696 if (size <= qhmem.LASTsize) {
00697 qh_memfree_(*setp, size, freelistp);
00698 }else
00699 qh_memfree (*setp, size);
00700 *setp= NULL;
00701 }
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 void qh_setfree2 (setT **setp, int elemsize) {
00719 void *elem, **elemp;
00720
00721 FOREACHelem_(*setp)
00722 qh_memfree (elem, elemsize);
00723 qh_setfree (setp);
00724 }
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 void qh_setfreelong(setT **setp) {
00745 int size;
00746
00747 if (*setp) {
00748 size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize;
00749 if (size > qhmem.LASTsize) {
00750 qh_memfree (*setp, size);
00751 *setp= NULL;
00752 }
00753 }
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 int qh_setin(setT *set, void *setelem) {
00770 void *elem, **elemp;
00771
00772 FOREACHelem_(set) {
00773 if (elem == setelem)
00774 return 1;
00775 }
00776 return 0;
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794 int qh_setindex(setT *set, void *atelem) {
00795 void **elem;
00796 int size, i;
00797
00798 SETreturnsize_(set, size);
00799 if (size > set->maxsize)
00800 return -1;
00801 elem= SETaddr_(set, void);
00802 for (i=0; i < size; i++) {
00803 if (*elem++ == atelem)
00804 return i;
00805 }
00806 return -1;
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826 void qh_setlarger(setT **oldsetp) {
00827 int size= 1, *sizep;
00828 setT *newset, *set, **setp, *oldset;
00829 void **oldp, **newp;
00830
00831 if (*oldsetp) {
00832 oldset= *oldsetp;
00833 SETreturnsize_(oldset, size);
00834 qhmem.cntlarger++;
00835 qhmem.totlarger += size+1;
00836 newset= qh_setnew(2 * size);
00837 oldp= SETaddr_(oldset, void);
00838 newp= SETaddr_(newset, void);
00839 memcpy((char *)newp, (char *)oldp, (size+1) * SETelemsize);
00840 sizep= SETsizeaddr_(newset);
00841 *sizep= size+1;
00842 FOREACHset_((setT *)qhmem.tempstack) {
00843 if (set == oldset)
00844 *(setp-1)= newset;
00845 }
00846 qh_setfree(oldsetp);
00847 }else
00848 newset= qh_setnew(3);
00849 *oldsetp= newset;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 void *qh_setlast(setT *set) {
00866 int size;
00867
00868 if (set) {
00869 size= *SETsizeaddr_(set);
00870 if (!size)
00871 return SETelem_(set, set->maxsize - 1);
00872 else if (size > 1)
00873 return SETelem_(set, size - 2);
00874 }
00875 return NULL;
00876 }
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 setT *qh_setnew(int setsize) {
00895 setT *set;
00896 int sizereceived;
00897 int size;
00898 void **freelistp;
00899
00900 if (!setsize)
00901 setsize++;
00902 size= sizeof(setT) + setsize * SETelemsize;
00903 if ((unsigned) size <= (unsigned) qhmem.LASTsize) {
00904 qh_memalloc_(size, freelistp, set, setT);
00905 #ifndef qh_NOmem
00906 sizereceived= qhmem.sizetable[ qhmem.indextable[size]];
00907 if (sizereceived > size)
00908 setsize += (sizereceived - size)/SETelemsize;
00909 #endif
00910 }else
00911 set= (setT*)qh_memalloc (size);
00912 set->maxsize= setsize;
00913 set->e[setsize].i= 1;
00914 set->e[0].p= NULL;
00915 return (set);
00916 }
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend) {
00938 setT *newset;
00939 void **oldp, **newp;
00940 int tailsize= size - nth -1, newsize;
00941
00942 if (tailsize < 0) {
00943 fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
00944 qh_setprint (qhmem.ferr, "", set);
00945 qh_errexit (qhmem_ERRqhull, NULL, NULL);
00946 }
00947 newsize= size-1 + prepend;
00948 newset= qh_setnew(newsize);
00949 newset->e[newset->maxsize].i= newsize+1;
00950 oldp= SETaddr_(set, void);
00951 newp= SETaddr_(newset, void) + prepend;
00952 switch (nth) {
00953 case 0:
00954 break;
00955 case 1:
00956 *(newp++)= *oldp++;
00957 break;
00958 case 2:
00959 *(newp++)= *oldp++;
00960 *(newp++)= *oldp++;
00961 break;
00962 case 3:
00963 *(newp++)= *oldp++;
00964 *(newp++)= *oldp++;
00965 *(newp++)= *oldp++;
00966 break;
00967 case 4:
00968 *(newp++)= *oldp++;
00969 *(newp++)= *oldp++;
00970 *(newp++)= *oldp++;
00971 *(newp++)= *oldp++;
00972 break;
00973 default:
00974 memcpy((char *)newp, (char *)oldp, nth * SETelemsize);
00975 newp += nth;
00976 oldp += nth;
00977 break;
00978 }
00979 oldp++;
00980 switch (tailsize) {
00981 case 0:
00982 break;
00983 case 1:
00984 *(newp++)= *oldp++;
00985 break;
00986 case 2:
00987 *(newp++)= *oldp++;
00988 *(newp++)= *oldp++;
00989 break;
00990 case 3:
00991 *(newp++)= *oldp++;
00992 *(newp++)= *oldp++;
00993 *(newp++)= *oldp++;
00994 break;
00995 case 4:
00996 *(newp++)= *oldp++;
00997 *(newp++)= *oldp++;
00998 *(newp++)= *oldp++;
00999 *(newp++)= *oldp++;
01000 break;
01001 default:
01002 memcpy((char *)newp, (char *)oldp, tailsize * SETelemsize);
01003 newp += tailsize;
01004 }
01005 *newp= NULL;
01006 return(newset);
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019 void qh_setprint(FILE *fp, char* string, setT *set) {
01020 int size, k;
01021
01022 if (!set)
01023 fprintf (fp, "%s set is null\n", string);
01024 else {
01025 SETreturnsize_(set, size);
01026 fprintf (fp, "%s set=%p maxsize=%d size=%d elems=",
01027 string, set, set->maxsize, size);
01028 if (size > set->maxsize)
01029 size= set->maxsize+1;
01030 for (k=0; k < size; k++)
01031 fprintf(fp, " %p", set->e[k].p);
01032 fprintf(fp, "\n");
01033 }
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050 void qh_setreplace(setT *set, void *oldelem, void *newelem) {
01051 void **elemp;
01052
01053 elemp= SETaddr_(set, void);
01054 while(*elemp != oldelem && *elemp)
01055 elemp++;
01056 if (*elemp)
01057 *elemp= newelem;
01058 else {
01059 fprintf (qhmem.ferr, "qhull internal error (qh_setreplace): elem %p not found in set\n",
01060 oldelem);
01061 qh_setprint (qhmem.ferr, "", set);
01062 qh_errexit (qhmem_ERRqhull, NULL, NULL);
01063 }
01064 }
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 int qh_setsize(setT *set) {
01081 int size, *sizep;
01082
01083 if (!set)
01084 return (0);
01085 sizep= SETsizeaddr_(set);
01086 if ((size= *sizep)) {
01087 size--;
01088 if (size > set->maxsize) {
01089 fprintf (qhmem.ferr, "qhull internal error (qh_setsize): current set size %d is greater than maximum size %d\n",
01090 size, set->maxsize);
01091 qh_setprint (qhmem.ferr, "set: ", set);
01092 qh_errexit (qhmem_ERRqhull, NULL, NULL);
01093 }
01094 }else
01095 size= set->maxsize;
01096 return size;
01097 }
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114 setT *qh_settemp(int setsize) {
01115 setT *newset;
01116
01117 newset= qh_setnew (setsize);
01118 qh_setappend ((setT **)&qhmem.tempstack, newset);
01119 if (qhmem.IStracing >= 5)
01120 fprintf (qhmem.ferr, "qh_settemp: temp set %p of %d elements, depth %d\n",
01121 newset, newset->maxsize, qh_setsize ((setT*)qhmem.tempstack));
01122 return newset;
01123 }
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142 void qh_settempfree(setT **set) {
01143 setT *stackedset;
01144
01145 if (!*set)
01146 return;
01147 stackedset= qh_settemppop ();
01148 if (stackedset != *set) {
01149 qh_settemppush(stackedset);
01150 fprintf (qhmem.ferr, "qhull internal error (qh_settempfree): set %p (size %d) was not last temporary allocated (depth %d, set %p, size %d)\n",
01151 *set, qh_setsize(*set), qh_setsize((setT*)qhmem.tempstack)+1,
01152 stackedset, qh_setsize(stackedset));
01153 qh_errexit (qhmem_ERRqhull, NULL, NULL);
01154 }
01155 qh_setfree (set);
01156 }
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169 void qh_settempfree_all(void) {
01170 setT *set, **setp;
01171
01172 FOREACHset_((setT *)qhmem.tempstack)
01173 qh_setfree(&set);
01174 qh_setfree((setT **)&qhmem.tempstack);
01175 }
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 setT *qh_settemppop(void) {
01190 setT *stackedset;
01191
01192 stackedset= (setT*)qh_setdellast((setT *)qhmem.tempstack);
01193 if (!stackedset) {
01194 fprintf (qhmem.ferr, "qhull internal error (qh_settemppop): pop from empty temporary stack\n");
01195 qh_errexit (qhmem_ERRqhull, NULL, NULL);
01196 }
01197 if (qhmem.IStracing >= 5)
01198 fprintf (qhmem.ferr, "qh_settemppop: depth %d temp set %p of %d elements\n",
01199 qh_setsize((setT*)qhmem.tempstack)+1, stackedset, qh_setsize(stackedset));
01200 return stackedset;
01201 }
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 void qh_settemppush(setT *set) {
01216
01217 qh_setappend ((setT**)&qhmem.tempstack, set);
01218 if (qhmem.IStracing >= 5)
01219 fprintf (qhmem.ferr, "qh_settemppush: depth %d temp set %p of %d elements\n",
01220 qh_setsize((setT*)qhmem.tempstack), set, qh_setsize(set));
01221 }
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 void qh_settruncate (setT *set, int size) {
01238
01239 if (size < 0 || size > set->maxsize) {
01240 fprintf (qhmem.ferr, "qhull internal error (qh_settruncate): size %d out of bounds for set:\n", size);
01241 qh_setprint (qhmem.ferr, "", set);
01242 qh_errexit (qhmem_ERRqhull, NULL, NULL);
01243 }
01244 set->e[set->maxsize].i= size+1;
01245 set->e[size].p= NULL;
01246 }
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261 int qh_setunique (setT **set, void *elem) {
01262
01263 if (!qh_setin (*set, elem)) {
01264 qh_setappend (set, elem);
01265 return 1;
01266 }
01267 return 0;
01268 }
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 void qh_setzero (setT *set, int index, int size) {
01290 int count;
01291
01292 if (index < 0 || index >= size || size > set->maxsize) {
01293 fprintf (qhmem.ferr, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", index, size);
01294 qh_setprint (qhmem.ferr, "", set);
01295 qh_errexit (qhmem_ERRqhull, NULL, NULL);
01296 }
01297 set->e[set->maxsize].i= size+1;
01298 count= size - index + 1;
01299 memset ((char *)SETelemaddr_(set, index, void), 0, count * SETelemsize);
01300 }
01301
01302