Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Analysis.AlgorithmBehavior/qhull-2012.1/src/testqset/testqset.c @ 10207

Last change on this file since 10207 was 10207, checked in by ascheibe, 11 years ago

#1886 added a unit test for volume calculation and the qhull library

File size: 32.5 KB
Line 
1/*<html><pre>  -<a                             href="../libqhull/index.htm#TOC"
2  >-------------------------------</a><a name="TOP">-</a>
3
4   testset.c -- test qset.c and its use of mem.c
5
6   The test sets are pointers to int.  Normally a set is a pointer to a type (e.g., facetT, ridgeT, etc.).
7   For consistency in notation, an "int" is typedef'd to i2T
8
9Functions and macros from qset.h.  Counts occurrences in this test.  Does not correspond to thoroughness.
10    qh_setaddsorted -- 4 tests
11    qh_setaddnth -- 1 test
12    qh_setappend -- 7 tests
13    qh_setappend_set -- 1 test
14    qh_setappend2ndlast -- 1 test
15    qh_setcheck -- lots of tests
16    qh_setcompact -- 7 tests
17    qh_setcopy -- 3 tests
18    qh_setdel -- 1 tests
19    qh_setdellast -- 1 tests
20    qh_setdelnth -- 2 tests
21    qh_setdelnthsorted -- 2 tests
22    qh_setdelsorted -- 1 test
23    qh_setduplicate -- not testable here
24    qh_setequal -- 4 tests
25    qh_setequal_except -- 2 tests
26    qh_setequal_skip -- 2 tests
27    qh_setfree -- 11+ tests
28    qh_setfree2 -- not testable here
29    qh_setfreelong -- 2 tests
30    qh_setin -- 3 tests
31    qh_setindex -- 4 tests
32    qh_setlarger -- 1 test
33    qh_setlast -- 2 tests
34    qh_setnew -- 6 tests
35    qh_setnew_delnthsorted
36    qh_setprint -- tested elsewhere
37    qh_setreplace -- 1 test
38    qh_setsize -- 9+ tests
39    qh_settemp -- 2 tests
40    qh_settempfree -- 1 test
41    qh_settempfree_all -- 1 test
42    qh_settemppop -- 1 test
43    qh_settemppush -- 1 test
44    qh_settruncate -- 3 tests
45    qh_setunique -- 3 tests
46    qh_setzero -- 1 test
47    FOREACHint_ -- 2 test
48    FOREACHint4_
49    FOREACHint_i_ -- 1 test
50    FOREACHintreverse_
51    FOREACHintreverse12_
52    FOREACHsetelement_ -- 1 test
53    FOREACHsetelement_i_ -- 1 test
54    FOREACHsetelementreverse_ -- 1 test
55    FOREACHsetelementreverse12_ -- 1 test
56    SETelem_ -- 3 tests
57    SETelemaddr_ -- 2 tests
58    SETelemt_ -- not tested (generic)
59    SETempty_ -- 1 test
60    SETfirst_ -- 4 tests
61    SETfirstt_ -- 2 tests
62    SETindex_ -- 2 tests
63    SETref_ -- 2 tests
64    SETreturnsize_ -- 2 tests
65    SETsecond_ -- 1 test
66    SETsecondt_ -- 2 tests
67    SETtruncate_ -- 2 tests
68*/
69
70#include <stdarg.h>
71#include <stdio.h>
72#include <stdlib.h>
73#include <string.h>
74
75#include "qset.h"
76#include "mem.h"
77
78typedef int i2T;
79#define MAXerrorCount 100 /* quit after n errors */
80
81#define FOREACHint_( ints ) FOREACHsetelement_( i2T, ints, i2)
82#define FOREACHint4_( ints ) FOREACHsetelement_( i2T, ints, i4)
83#define FOREACHint_i_( ints ) FOREACHsetelement_i_( i2T, ints, i2)
84#define FOREACHintreverse_( ints ) FOREACHsetelementreverse_( i2T, ints, i2)
85#define FOREACHintreverse12_( ints ) FOREACHsetelementreverse12_( i2T, ints, i2)
86
87enum {
88    MAXint= 0x7fffffff,
89};
90
91char prompt[]= "testqset N [M] -- Test qset.c and mem.c\n\
92  Test qsets of 0..N integers with a check every M iterations (default ~log10)\n\
93  Additional checking and logging if M is 1\n\
94  For example:\n\
95    testqset 10000\n\
96";
97
98int error_count= 0;  /* Global error_count.  checkSetContents() keeps its own error count.  It exits on too many errors */
99
100/* Macros normally defined in user.h */
101
102#define qh_MEMalign ((int)(sizeof(void *)))
103#define qh_MEMbufsize 0x10000       /* allocate 64K memory buffers */
104#define qh_MEMinitbuf 0x20000      /* initially allocate 128K buffer */
105
106/* Macros normally defined in QhullSet.h */
107
108
109/* Functions normally defined in usermem.h */
110
111void qh_exit(int exitcode) {
112    exit(exitcode);
113} /* exit */
114
115void qh_free(void *mem) {
116    free(mem);
117} /* free */
118
119void *qh_malloc(size_t size) {
120    return malloc(size);
121} /* malloc */
122
123void    qh_errexit(int exitcode, void *f, void *r)
124{
125    f= r; /* unused */
126    qh_exit(exitcode);
127}
128
129void    qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... )
130{
131    static int needs_cr= 0;  /* True if qh_fprintf needs a CR */
132
133    size_t fmtlen= strlen(fmt);
134    va_list args;
135
136    if (!fp) {
137        fprintf(stderr, "qh_fprintf: fp not defined for '%s'", fmt);
138        qh_errexit(6232, NULL, NULL);
139    }
140    if(fmtlen>0){
141        if(fmt[fmtlen-1]=='\n'){
142            if(needs_cr && fmtlen>1){
143                fprintf(fp, "\n");
144            }
145            needs_cr= 0;
146        }else{
147            needs_cr= 1;
148        }
149    }
150    if(msgcode>=6000 && msgcode<7000){
151        fprintf(fp, "Error TQ%d ", msgcode);
152    }
153    va_start(args, fmt);
154    vfprintf(fp, fmt, args);
155    va_end(args);
156}
157
158/* Defined below in order of use */
159int main(int argc, char **argv);
160void readOptions(int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery);
161void setupMemory(int tracelevel, int numInts, int **intarray);
162
163void testSetappendSettruncate(int numInts, int *intarray, int checkEvery);
164void testSetdelSetadd(int numInts, int *intarray, int checkEvery);
165void testSetappendSet(int numInts, int *intarray, int checkEvery);
166void testSetcompactCopy(int numInts, int *intarray, int checkEvery);
167void testSetequalInEtc(int numInts, int *intarray, int checkEvery);
168void testSettemp(int numInts, int *intarray, int checkEvery);
169void testSetlastEtc(int numInts, int *intarray, int checkEvery);
170void testSetdelsortedEtc(int numInts, int *intarray, int checkEvery);
171
172int log_i(setT *set, const char *s, int i, int numInts, int checkEvery);
173void checkSetContents(const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC);
174
175int main(int argc, char **argv) {
176    int *intarray= NULL;
177    int numInts;
178    int checkEvery= MAXint;
179    int curlong, totlong;
180    int tracelevel= 4; /* 4 normally.  5 for memory tracing */
181
182    readOptions(argc, argv, prompt, &numInts, &checkEvery);
183    setupMemory(tracelevel, numInts, &intarray);
184
185    testSetappendSettruncate(numInts, intarray, checkEvery);
186    testSetdelSetadd(numInts, intarray, checkEvery);
187    testSetappendSet(numInts, intarray, checkEvery);
188    testSetcompactCopy(numInts, intarray, checkEvery);
189    testSetequalInEtc(numInts, intarray, checkEvery);
190    testSettemp(numInts, intarray, checkEvery);
191    testSetlastEtc(numInts, intarray, checkEvery);
192    testSetdelsortedEtc(numInts, intarray, checkEvery);
193    printf("\n\nNot testing qh_setduplicate and qh_setfree2.\n  These routines use heap-allocated set contents.  See qhull tests.\n");
194
195    qh_memstatistics(stdout);
196    qh_memfreeshort(&curlong, &totlong);
197    if (curlong || totlong){
198        qh_fprintf(stderr, 8043, "qh_memfreeshort: did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
199        error_count++;
200    }
201    if(error_count){
202        qh_fprintf(stderr, 8012, "testqset: %d errors\n\n", error_count);
203        exit(1);
204    }else{
205        printf("testqset: OK\n\n");
206    }
207    return 0;
208}/*main*/
209
210void readOptions(int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery)
211{
212    long numIntsArg;
213    long checkEveryArg;
214    char *endp;
215
216    if (argc != 2 && argc != 3) {
217        printf(promptstr);
218        exit(0);
219    }
220    numIntsArg= strtol(argv[1], &endp, 10);
221    if(numIntsArg<1){
222        qh_fprintf(stderr, 6301, "First argument should be 1 or greater.  Got '%s'\n", argv[1]);
223        exit(1);
224    }
225    if(numIntsArg>MAXint){
226        qh_fprintf(stderr, 6302, "qset does not currently support 64-bit ints.  Maximum count is %d\n", MAXint);
227        exit(1);
228    }
229    *numInts= (int)numIntsArg;
230
231    if(argc>2){
232        checkEveryArg= strtol(argv[2], &endp, 10);
233        if(checkEveryArg<1){
234            qh_fprintf(stderr, 6321, "checkEvery argument should be 1 or greater.  Got '%s'\n", argv[2]);
235            exit(1);
236        }
237        if(checkEveryArg>MAXint){
238            qh_fprintf(stderr, 6322, "qset does not currently support 64-bit ints.  Maximum checkEvery is %d\n", MAXint);
239            exit(1);
240        }
241        *checkEvery= (int)checkEveryArg;
242    }
243}/*readOptions*/
244
245void setupMemory(int tracelevel, int numInts, int **intarray)
246{
247    int i;
248    if(numInts<0 || numInts*(int)sizeof(int)<0){
249        qh_fprintf(stderr, 6303, "qset does not currently support 64-bit ints.  Integer overflow\n");
250        exit(1);
251    }
252    *intarray= qh_malloc(numInts * sizeof(int));
253    if(!*intarray){
254        qh_fprintf(stderr, 6304, "Failed to allocate %d bytes of memory\n", numInts * sizeof(int));
255        exit(1);
256    }
257    for(i= 0; i<numInts; i++){
258        (*intarray)[i] =i;
259    }
260
261    qh_meminit(stderr);
262    qh_meminitbuffers(tracelevel, qh_MEMalign, 4 /*sizes*/, qh_MEMbufsize,qh_MEMinitbuf);
263    qh_memsize(10);
264    qh_memsize(20);
265    qh_memsize(30);
266    qh_memsize(40);
267    qh_memsetup();
268
269    qh_fprintf(stderr, 8001, "SETelemsize is %d bytes for pointer-to-int\n", SETelemsize);
270}/*setupMemmory*/
271
272void testSetappendSettruncate(int numInts, int *intarray, int checkEvery)
273{
274    setT *ints= qh_setnew(4);
275    int i, isCheck;
276
277    qh_fprintf(stderr, 8002, "\n\nTesting qh_setappend 0..%d.  Test", numInts-1);
278    for(i= 0; i<numInts; i++){
279        isCheck= log_i(ints, "i", i, numInts, checkEvery);
280        qh_setappend(&ints, intarray+i);
281        if(isCheck){
282            checkSetContents("qh_setappend", ints, i+1, 0, -1, -1);
283        }
284    }
285
286    qh_fprintf(stderr, 8014, "\n\nTesting qh_settruncate %d and 0.  Test", numInts/2);
287    if(numInts>=2){
288        isCheck= log_i(ints, "n", numInts/2, numInts, checkEvery);
289        qh_settruncate(ints, numInts/2);
290        checkSetContents("qh_settruncate by half", ints, numInts/2, 0, -1, -1);
291    }
292    isCheck= log_i(ints, "n", 0, numInts, checkEvery);
293    qh_settruncate(ints, 0);
294    checkSetContents("qh_settruncate", ints, 0, -1, -1, -1);
295
296    qh_fprintf(stderr, 8003, "\n\nTesting qh_setappend2ndlast 0,0..%d.  Test 0", numInts-1);
297    qh_setfree(&ints);
298    ints= qh_setnew(4);
299    qh_setappend(&ints, intarray+0);
300    for(i= 0; i<numInts; i++){
301        isCheck= log_i(ints, "i", i, numInts, checkEvery);
302        qh_setappend2ndlast(&ints, intarray+i);
303        if(isCheck){
304            checkSetContents("qh_setappend2ndlast", ints, i+2, 0, 0, -1);
305        }
306    }
307    qh_fprintf(stderr, 8015, "\n\nTesting SETtruncate_ %d and 0.  Test", numInts/2);
308    if(numInts>=2){
309        isCheck= log_i(ints, "n", numInts/2, numInts, checkEvery);
310        SETtruncate_(ints, numInts/2);
311        checkSetContents("SETtruncate_ by half", ints, numInts/2, 0, -1, -1);
312    }
313    isCheck= log_i(ints, "n", 0, numInts, checkEvery);
314    SETtruncate_(ints, 0);
315    checkSetContents("SETtruncate_", ints, 0, -1, -1, -1);
316
317    qh_setfree(&ints);
318}/*testSetappendSettruncate*/
319
320void testSetdelSetadd(int numInts, int *intarray, int checkEvery)
321{
322    setT *ints=qh_setnew(1);
323    int i,j, isCheck;
324
325    qh_fprintf(stderr, 8003, "\n\nTesting qh_setdelnthsorted and qh_setaddnth 1..%d. Test", numInts-1);
326    for(j=1; j<numInts; j++){  /* size 0 not valid */
327        if(log_i(ints, "j", j, numInts, MAXint)){
328            for(i= qh_setsize(ints); i<j; i++){
329                qh_setappend(&ints, intarray+i);
330            }
331            checkSetContents("qh_setappend", ints, j, 0, -1, -1);
332            for(i= 0; i<j && i<100; i++){  /* otherwise too slow */
333                isCheck= log_i(ints, "", i, numInts, checkEvery);
334                qh_setdelnthsorted(ints, i);
335                qh_setaddnth(&ints, i, intarray+i);
336                if(checkEvery==1){
337                    checkSetContents("qh_setdelnthsorted qh_setaddnth", ints, j, 0, -1, -1);
338                }
339            }
340            checkSetContents("qh_setdelnthsorted qh_setaddnth 2", ints, j, 0, -1, -1);
341        }
342    }
343    qh_setfree(&ints);
344}/*testSetdelSetadd*/
345
346void testSetappendSet(int numInts, int *intarray, int checkEvery)
347{
348    setT *ints=qh_setnew(1);
349    setT *ints2;
350    int i,j,k;
351
352    qh_fprintf(stderr, 8016, "\n\nTesting qh_setappend_set 0..%d. Test", numInts-1);
353    for(j=0; j<numInts; j++){
354        if(log_i(ints, "j", j, numInts, numInts)){
355            for(i= qh_setsize(ints); i<j; i++){
356                qh_setappend(&ints, intarray+i);
357            }
358            if(checkEvery==1){
359                checkSetContents("qh_setappend", ints, j, 0, -1, -1);
360            }
361            ints2= qh_setnew(j==0 ? 0 : j-1);  /* One less than needed */
362            for(i= 0; i<=j && i<=20; i++){  /* otherwise too slow */
363                if(log_i(ints, "", i, numInts, numInts)){
364                    for(k= qh_setsize(ints2); k<i; k++){
365                        qh_setappend(&ints2, intarray+k);
366                    }
367                    if(checkEvery==1){
368                        checkSetContents("qh_setappend 2", ints2, i, 0, -1, -1);
369                    }
370                    qh_setappend_set(&ints, ints2);
371                    checkSetContents("qh_setappend_set", ints, i+j, 0, (j==0 ? -1 : 0), -1);
372                    qh_settruncate(ints, j);
373                    if(checkEvery==1){
374                        checkSetContents("qh_settruncate", ints, j, 0, -1, -1);
375                    }
376                }
377            }
378            qh_setfree(&ints2);
379        }
380    }
381    qh_setfree(&ints);
382}/*testSetappendSet*/
383
384void testSetcompactCopy(int numInts, int *intarray, int checkEvery)
385{
386    setT *ints= qh_setnew(20);
387    setT *ints2= NULL;
388    int i,j,k;
389
390    qh_fprintf(stderr, 8017, "\n\nTesting qh_setcompact and qh_setcopy 0..%d. Test", numInts-1);
391    for(j=0; j<numInts; j++){
392        if(log_i(ints, "j", j, numInts, checkEvery)){
393            for(i= qh_setsize(ints); i<j; i++){  /* Test i<j to test the empty set */
394                for(k= 0; k<i%7; k++){
395                    qh_setappend(&ints, NULL);
396                }
397                qh_setappend(&ints, intarray+i);
398            }
399            qh_setfree(&ints2);
400            ints2= qh_setcopy(ints, 0);
401            qh_setcompact(ints);
402            qh_setcompact(ints2);
403            checkSetContents("qh_setcompact", ints, j, 0, 0, -1);
404            checkSetContents("qh_setcompact", ints2, j, 0, 0, -1);
405            qh_setcompact(ints);
406            checkSetContents("qh_setcompact", ints, j, 0, 0, -1);
407        }
408    }
409    qh_setfree(&ints);
410    qh_setfree(&ints2);
411}/*testSetcompactCopy*/
412
413void testSetdelsortedEtc(int numInts, int *intarray, int checkEvery)
414{
415    setT *ints= qh_setnew(1);
416    setT *ints2= NULL;
417    int i,j;
418
419    qh_fprintf(stderr, 8018, "\n\nTesting qh_setdel*, qh_setaddsorted, and  0..%d. Test", numInts-1);
420    for(j=0; j<numInts; j++){
421        if(log_i(ints, "j", j, numInts, checkEvery)){
422            for(i= qh_setsize(ints); i<j; i++){  /* Test i<j to test the empty set */
423                qh_setaddsorted(&ints, intarray+i);
424            }
425            checkSetContents("qh_setaddsorted", ints, j, 0, 0, -1);
426            if(j>3){
427                qh_setdelsorted(ints, intarray+i/2);
428                checkSetContents("qh_setdelsorted", ints, j-1, 0, i/2+1, -1);
429                qh_setaddsorted(&ints, intarray+i/2);
430                checkSetContents("qh_setaddsorted i/2", ints, j, 0, 0, -1);
431            }
432            qh_setdellast(ints);
433            checkSetContents("qh_setdellast", ints, (j ? j-1 : 0), 0, -1, -1);
434            if(j>0){
435                qh_setaddsorted(&ints, intarray+j-1);
436                checkSetContents("qh_setaddsorted j-1", ints, j, 0, -1, -1);
437            }
438            if(j>4){
439                qh_setdelnthsorted(ints, i/2);
440                if (checkEvery==1)
441                  checkSetContents("qh_setdelnthsorted", ints, j-1, 0, i/2+1, -1);
442                /* FIXUP qh_setdelnth  move-to-front */
443                qh_setdelsorted(ints, intarray+i/2+1);
444                checkSetContents("qh_setdelsorted 2", ints, j-2, 0, i/2+2, -1);
445                qh_setaddsorted(&ints, intarray+i/2+1);
446                if (checkEvery==1)
447                  checkSetContents("qh_setaddsorted i/2+1", ints, j-1, 0, i/2+1, -1);
448                qh_setaddsorted(&ints, intarray+i/2);
449                checkSetContents("qh_setaddsorted i/2 again", ints, j, 0, -1, -1);
450            }
451            qh_setfree(&ints2);
452            ints2= qh_setcopy(ints, 0);
453            qh_setcompact(ints);
454            qh_setcompact(ints2);
455            checkSetContents("qh_setcompact", ints, j, 0, 0, -1);
456            checkSetContents("qh_setcompact 2", ints2, j, 0, 0, -1);
457            qh_setcompact(ints);
458            checkSetContents("qh_setcompact 3", ints, j, 0, 0, -1);
459            qh_setfree(&ints2);
460        }
461    }
462    qh_setfreelong(&ints);
463    if(ints){
464        qh_setfree(&ints); /* Was quick memory */
465    }
466}/*testSetdelsortedEtc*/
467
468void testSetequalInEtc(int numInts, int *intarray, int checkEvery)
469{
470    setT *ints= NULL;
471    setT *ints2= NULL;
472    setT *ints3= NULL;
473    int i,j,n;
474
475    qh_fprintf(stderr, 8019, "\n\nTesting qh_setequal*, qh_setin*, qh_setdel, qh_setdelnth, and qh_setlarger 0..%d. Test", numInts-1);
476    for(j=0; j<numInts; j++){
477        if(log_i(ints, "j", j, numInts, checkEvery)){
478            n= qh_setsize(ints);
479            qh_setlarger(&ints);
480            checkSetContents("qh_setlarger", ints, n, 0, -1, -1);
481            for(i= qh_setsize(ints); i<j; i++){  /* Test i<j to test the empty set */
482                qh_setappend(&ints, intarray+i);
483            }
484            checkSetContents("qh_setappend", ints, j, 0, -1, -1);
485            if(!qh_setequal(ints, ints)){
486                qh_fprintf(stderr, 6300, "testSetequalInEtc: set not equal to itself at length %d\n", j);
487                error_count++;
488            }
489            if(j==0 && !qh_setequal(ints, ints2)){
490                qh_fprintf(stderr, 6323, "testSetequalInEtc: empty set not equal to null set\n");
491                error_count++;
492            }
493            if(j>0){
494                if(qh_setequal(ints, ints2)){
495                    qh_fprintf(stderr, 6324, "testSetequalInEtc: non-empty set equal to empty set\n", j);
496                    error_count++;
497                }
498                qh_setfree(&ints3);
499                ints3= qh_setcopy(ints, 0);
500                checkSetContents("qh_setreplace", ints3, j, 0, -1, -1);
501                qh_setreplace(ints3, intarray+j/2, intarray+j/2+1);
502                if(j==1){
503                    checkSetContents("qh_setreplace 2", ints3, j, j/2+1, -1, -1);
504                }else if(j==2){
505                    checkSetContents("qh_setreplace 3", ints3, j, 0, j/2+1, -1);
506                }else{
507                    checkSetContents("qh_setreplace 3", ints3, j, 0, j/2+1, j/2+1);
508                }
509                if(qh_setequal(ints, ints3)){
510                    qh_fprintf(stderr, 6325, "testSetequalInEtc: modified set equal to original set at %d/2\n", j);
511                    error_count++;
512                }
513                if(!qh_setequal_except(ints, intarray+j/2, ints3, intarray+j/2+1)){
514                    qh_fprintf(stderr, 6326, "qh_setequal_except: modified set not equal to original set except modified\n", j);
515                    error_count++;
516                }
517                if(qh_setequal_except(ints, intarray+j/2, ints3, intarray)){
518                    qh_fprintf(stderr, 6327, "qh_setequal_except: modified set equal to original set with wrong excepts\n", j);
519                    error_count++;
520                }
521                if(!qh_setequal_skip(ints, j/2, ints3, j/2)){
522                    qh_fprintf(stderr, 6328, "qh_setequal_skip: modified set not equal to original set except modified\n", j);
523                    error_count++;
524                }
525                if(j>2 && qh_setequal_skip(ints, j/2, ints3, 0)){
526                    qh_fprintf(stderr, 6329, "qh_setequal_skip: modified set equal to original set with wrong excepts\n", j);
527                    error_count++;
528                }
529                if(intarray+j/2+1!=qh_setdel(ints3, intarray+j/2+1)){
530                    qh_fprintf(stderr, 6330, "qh_setdel: failed to find added element\n", j);
531                    error_count++;
532                }
533                checkSetContents("qh_setdel", ints3, j-1, 0, j-1, (j==1 ? -1 : j/2+1));  /* swaps last element with deleted element */
534                if(j>3){
535                    qh_setdelnth(ints3, j/2); /* Delete at the same location as the original replace, for only one out-of-order element */
536                    checkSetContents("qh_setdelnth", ints3, j-2, 0, j-2, (j==2 ? -1 : j/2+1));
537                }
538                if(qh_setin(ints3, intarray+j/2)){
539                    qh_fprintf(stderr, 6331, "qh_setin: found deleted element\n");
540                    error_count++;
541                }
542                if(j>4 && !qh_setin(ints3, intarray+1)){
543                    qh_fprintf(stderr, 6332, "qh_setin: did not find second element\n");
544                    error_count++;
545                }
546                if(j>4 && !qh_setin(ints3, intarray+j-2)){
547                    qh_fprintf(stderr, 6333, "qh_setin: did not find last element\n");
548                    error_count++;
549                }
550                if(-1!=qh_setindex(ints2, intarray)){
551                    qh_fprintf(stderr, 6334, "qh_setindex: found element in empty set\n");
552                    error_count++;
553                }
554                if(-1!=qh_setindex(ints3, intarray+j/2)){
555                    qh_fprintf(stderr, 6335, "qh_setindex: found deleted element in set\n");
556                    error_count++;
557                }
558                if(0!=qh_setindex(ints, intarray)){
559                    qh_fprintf(stderr, 6336, "qh_setindex: did not find first in set\n");
560                    error_count++;
561                }
562                if(j-1!=qh_setindex(ints, intarray+j-1)){
563                    qh_fprintf(stderr, 6337, "qh_setindex: did not find last in set\n");
564                    error_count++;
565                }
566            }
567            qh_setfree(&ints2);
568        }
569    }
570    qh_setfree(&ints3);
571    qh_setfreelong(&ints);
572    if(ints){
573        qh_setfree(&ints); /* Was quick memory */
574    }
575}/*testSetequalInEtc*/
576
577
578void testSetlastEtc(int numInts, int *intarray, int checkEvery)
579{
580    setT *ints= NULL;
581    setT *ints2= NULL;
582    int i,j,prepend;
583
584    qh_fprintf(stderr, 8020, "\n\nTesting qh_setlast, qh_setnew_delnthsorted, qh_setunique, and qh_setzero 0..%d. Test", numInts-1);
585    for(j=0; j<numInts; j++){
586        if(log_i(ints, "j", j, numInts, checkEvery)){
587            for(i= qh_setsize(ints); i<j; i++){  /* Test i<j to test the empty set */
588                if(!qh_setunique(&ints, intarray+i)){
589                    qh_fprintf(stderr, 6340, "qh_setunique: not able to append next element %d\n", i);
590                    error_count++;
591                }
592                if(checkEvery==1){
593                    checkSetContents("qh_setunique", ints, i+1, 0, -1, -1);
594                }
595                if(qh_setunique(&ints, intarray+i)){
596                    qh_fprintf(stderr, 6341, "qh_setunique: appended next element twice %d\n", i);
597                    error_count++;
598                }
599                if(qh_setunique(&ints, intarray+i/2)){
600                    qh_fprintf(stderr, 6346, "qh_setunique: appended middle element twice %d/2\n", i);
601                    error_count++;
602                }
603            }
604            checkSetContents("qh_setunique 2", ints, j, 0, -1, -1);
605            if(j==0 && NULL!=qh_setlast(ints)){
606                qh_fprintf(stderr, 6339, "qh_setlast: returned last element of empty set\n");
607                error_count++;
608            }
609            if(j>0){
610                if(intarray+j-1!=qh_setlast(ints)){
611                    qh_fprintf(stderr, 6338, "qh_setlast: wrong last element\n");
612                    error_count++;
613                }
614                prepend= (j<100 ? j/4 : 0);
615                ints2= qh_setnew_delnthsorted(ints, qh_setsize(ints), j/2, prepend);
616                if(qh_setsize(ints2)!=j+prepend-1){
617                    qh_fprintf(stderr, 6345, "qh_setnew_delnthsorted: Expecting %d elements, got %d\n", j+prepend-1, qh_setsize(ints2));
618                    error_count++;
619                }
620                /* Define prepended elements.  Otherwise qh_setdelnthsorted may fail */
621                for(i= 0; i<prepend; i++){
622                    void **p= &SETelem_(ints2, i);
623                    *p= intarray+0;
624                }
625                for(i= 0; i<prepend; i++){
626                    qh_setdelnthsorted(ints2, 0);  /* delete undefined prefix */
627                }
628                checkSetContents("qh_setnew_delnthsorted", ints2, j-1, 0, j/2+1, -1);
629                if(j>2){
630                    qh_setzero(ints2, j/2, j-1);  /* max size may be j-1 */
631                    if(qh_setsize(ints2)!=j-1){
632                        qh_fprintf(stderr, 6342, "qh_setzero: Expecting %d elements, got %d\n", j, qh_setsize(ints2));
633                        error_count++;
634                    }
635                    qh_setcompact(ints2);
636                    checkSetContents("qh_setzero", ints2, j/2, 0, -1, -1);
637                }
638            }
639            qh_setfree(&ints2);
640        }
641    }
642    qh_setfreelong(&ints);
643    if(ints){
644        qh_setfree(&ints); /* Was quick memory */
645    }
646}/*testSetlastEtc*/
647
648void testSettemp(int numInts, int *intarray, int checkEvery)
649{
650    setT *ints= NULL;
651    setT *ints2= NULL;
652    setT *ints3= NULL;
653    int i,j;
654
655    qh_fprintf(stderr, 8021, "\n\nTesting qh_settemp* 0..%d. Test", numInts-1);
656    for(j=0; j<numInts; j++){
657        if(log_i(ints, "j", j, numInts, checkEvery)){
658            if(j<20){
659                for(i=0; i<j; i++){
660                    ints2= qh_settemp(j);
661                }
662                qh_settempfree_all();
663            }
664            for(i= qh_setsize(ints); i<j; i++){  /* Test i<j to test the empty set */
665                qh_setappend(&ints, intarray+i);
666            }
667            ints2= qh_settemp(j);
668            if(j>0){
669                qh_settemppush(ints);
670                ints3= qh_settemppop();
671                if(ints!=ints3){
672                    qh_fprintf(stderr, 6343, "qh_settemppop: didn't pop the push\n");
673                    error_count++;
674                }
675            }
676            qh_settempfree(&ints2);
677        }
678    }
679    qh_setfreelong(&ints);
680    if(ints){
681        qh_setfree(&ints); /* Was quick memory */
682    }
683}/*testSettemp*/
684
685/* Check that a set contains count elements
686   Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
687   Use -1 for missing ranges
688   Returns -1 if should check results
689*/
690int log_i(setT *set, const char *s, int i, int numInts, int checkEvery)
691{
692    int j= i;
693    int scale= 1;
694    int e= 0;
695    int *i2, **i2p;
696
697    if(*s || checkEvery==1){
698        if(i<10){
699            qh_fprintf(stderr, 8004, " %s%d", s, i);
700        }else{
701            if(i==11 && checkEvery==1){
702                qh_fprintf(stderr, 8005, "\nResults after 10: ");
703                FOREACHint_(set){
704                    qh_fprintf(stderr, 8006, " %d", *i2);
705                }
706                qh_fprintf(stderr, 8007, " Continue");
707            }
708            while((j= j/10)>=1){
709                scale *= 10;
710                e++;
711            }
712            if(i==numInts-1){
713                qh_fprintf(stderr, 8008, " %s%d", s, i);
714            }else if(i==scale){
715                if(i<=1000){
716                    qh_fprintf(stderr, 8010, " %s%d", s, i);
717                }else{
718                    qh_fprintf(stderr, 8009, " %s1e%d", s, e);
719                }
720            }
721        }
722    }
723    if(i<1000 || i%checkEvery==0 || i== scale || i==numInts-1){
724        return 1;
725    }
726    return 0;
727}/*log_i*/
728
729/* Check that a set contains count elements
730   Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
731   Use -1 for missing ranges
732*/
733void checkSetContents(const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC)
734{
735
736    i2T *i2, **i2p;
737    int i2_i, i2_n;
738    int prev= -1; /* avoid warning */
739    int i;
740    int first= -3;
741    int second= -3;
742    int rangeCount=1;
743    int actualSize= 0;
744
745    qh_setcheck(set, name, 0);
746    if(set){
747        SETreturnsize_(set, actualSize);  /* normally used only when speed is critical */
748        if(*qh_setendpointer(set)!=NULL){
749            qh_fprintf(stderr, 6344, "%s: qh_setendpointer(), 0x%x, is not NULL terminator of set 0x%x", name, qh_setendpointer(set), set);
750            error_count++;
751        }
752    }
753    if(actualSize!=qh_setsize(set)){
754        qh_fprintf(stderr, 6305, "%s: SETreturnsize_() returned %d while qh_setsize() returns %d\n", name, actualSize, qh_setsize(set));
755        error_count++;
756    }else if(actualSize!=count){
757        qh_fprintf(stderr, 6306, "%s: Expecting %d elements for set.  Got %d elements\n", name, count, actualSize);
758        error_count++;
759    }
760    if(SETempty_(set)){
761        if(count!=0){
762            qh_fprintf(stderr, 6307, "%s: Got empty set instead of count %d, rangeA %d, rangeB %d, rangeC %d\n", name, count, rangeA, rangeB, rangeC);
763            error_count++;
764        }
765    }else{
766        /* Must be first, otherwise trips msvc 8 */
767        i2T **p= SETaddr_(set, i2T);
768        if(*p!=SETfirstt_(set, i2T)){
769            qh_fprintf(stderr, 6309, "%s: SETaddr_(set, i2t) [%p] is not the same as SETfirst_(set) [%p]\n", name, SETaddr_(set, i2T), SETfirst_(set));
770            error_count++;
771        }
772        first= *(int *)SETfirst_(set);
773        if(SETfirst_(set)!=SETfirstt_(set, i2T)){
774            qh_fprintf(stderr, 6308, "%s: SETfirst_(set) [%p] is not the same as SETfirstt_(set, i2T [%p]\n", name, SETfirst_(set), SETfirstt_(set, i2T));
775            error_count++;
776        }
777        if(qh_setsize(set)>1){
778            second= *(int *)SETsecond_(set);
779            if(SETsecond_(set)!=SETsecondt_(set, i2T)){
780                qh_fprintf(stderr, 6310, "%s: SETsecond_(set) [%p] is not the same as SETsecondt_(set, i2T) [%p]\n", name, SETsecond_(set), SETsecondt_(set, i2T));
781                error_count++;
782            }
783        }
784    }
785    /* Test first run of ints in set*/
786    i= 0;
787    FOREACHint_(set){
788        if(i2!=SETfirst_(set) && *i2!=prev+1){
789            break;
790        }
791        prev= *i2;
792        if(SETindex_(set, i2)!=i){
793            qh_fprintf(stderr, 6311, "%s: Expecting SETIndex_(set, pointer-to-%d) to be %d.  Got %d\n", name, *i2, i, SETindex_(set, i2));
794            error_count++;;
795        }
796        if(i2!=SETref_(i2)){
797            qh_fprintf(stderr, 6312, "%s: SETref_(i2) [%p] does not point to i2 (the %d'th element)\n", name, SETref_(i2), i);
798            error_count++;;
799        }
800        i++;
801    }
802    FOREACHint_i_(set){
803        /* Must be first conditional, otherwise it trips up msvc 8 */
804        i2T **p= SETelemaddr_(set, i2_i, i2T);
805        if(i2!=*p){
806            qh_fprintf(stderr, 6320, "%s: SETelemaddr_(set, %d, i2T) [%p] does not point to i2\n", name, i2_i, SETelemaddr_(set, i2_i, int));
807            error_count++;;
808        }
809        if(i2_i==0){
810            if(first!=*i2){
811                qh_fprintf(stderr, 6314, "%s: First element is %d instead of SETfirst %d\n", name, *i2, first);
812                error_count++;;
813            }
814            if(rangeA!=*i2){
815                qh_fprintf(stderr, 6315, "%s: starts with %d instead of rangeA %d\n", name, *i2, rangeA);
816                error_count++;;
817            }
818            prev= rangeA;
819        }else{
820            if(i2_i==1 && second!=*i2){
821                qh_fprintf(stderr, 6316, "%s: Second element is %d instead of SETsecond %d\n", name, *i2, second);
822                error_count++;;
823            }
824            if(prev+1==*i2){
825                prev++;
826            }else{
827                if(*i2==rangeB){
828                    prev= rangeB;
829                    rangeB= -1;
830                    rangeCount++;
831                }else if(rangeB==-1 && *i2==rangeC){
832                    prev= rangeC;
833                    rangeC= -1;
834                    rangeCount++;
835                }else{
836                    prev++;
837                    qh_fprintf(stderr, 6317, "%s: Expecting %d'th element to be %d.  Got %d\n", name, i2_i, prev, *i2);
838                    error_count++;
839                }
840            }
841        }
842        if(i2!=SETelem_(set, i2_i)){
843            qh_fprintf(stderr, 6318, "%s: SETelem_(set, %d) [%p] is not i2 [%p] (the %d'th element)\n", name, i2_i, SETelem_(set, i2_i), i2, i2_i);
844            error_count++;;
845        }
846        if(SETelemt_(set, i2_i, i2T)!=SETelem_(set, i2_i)){   /* Normally SETelemt_ is used for generic sets */
847            qh_fprintf(stderr, 6319, "%s: SETelemt_(set, %d, i2T) [%p] is not SETelem_(set, %d) [%p] (the %d'th element)\n", name, i2_i, SETelemt_(set, i2_i, int), i2_i, SETelem_(set, i2_i), i2_i);
848            error_count++;;
849        }
850    }
851    if(error_count>=MAXerrorCount){
852        qh_fprintf(stderr, 8011, "testqset: Stop testing after %d errors\n", error_count);
853        exit(1);
854    }
855}/*checkSetContents*/
856
Note: See TracBrowser for help on using the repository browser.