LCOV - code coverage report
Current view: top level - alg/internal_libqhull - global_r.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 378 1484 25.5 %
Date: 2024-05-02 00:41:30 Functions: 14 21 66.7 %

          Line data    Source code
       1             : 
       2             : /*<html><pre>  -<a                             href="qh-globa_r.htm"
       3             :   >-------------------------------</a><a name="TOP">-</a>
       4             : 
       5             :    global_r.c
       6             :    initializes all the globals of the qhull application
       7             : 
       8             :    see README
       9             : 
      10             :    see libqhull_r.h for qh.globals and function prototypes
      11             : 
      12             :    see qhull_ra.h for internal functions
      13             : 
      14             :    Copyright (c) 1993-2020 The Geometry Center.
      15             :    $Id: //main/2019/qhull/src/libqhull_r/global_r.c#19 $$Change: 3037 $
      16             :    $DateTime: 2020/09/03 17:28:32 $$Author: bbarber $
      17             :  */
      18             : 
      19             : #include "qhull_ra.h"
      20             : 
      21             : /*========= qh->definition -- globals defined in libqhull_r.h =======================*/
      22             : 
      23             : /*-<a                             href  ="qh-globa_r.htm#TOC"
      24             :   >--------------------------------</a><a name="version">-</a>
      25             : 
      26             :   qh_version
      27             :     version string by year and date
      28             :     qh_version2 for Unix users and -V
      29             : 
      30             :     the revision increases on code changes only
      31             : 
      32             :   notes:
      33             :     change date:    Changes.txt, Announce.txt, index.htm, README.txt,
      34             :                     qhull-news.html, Eudora signatures, CMakeLists.txt
      35             :     change version: README.txt, qh-get.htm, File_id.diz, Makefile.txt, CMakeLists.txt
      36             :     check that CMakeLists.txt @version is the same as qh_version2
      37             :     change year:    Copying.txt
      38             :     check download size
      39             :     recompile user_eg_r.c, rbox_r.c, libqhull_r.c, qconvex_r.c, qdelaun_r.c qvoronoi_r.c, qhalf_r.c, testqset_r.c
      40             : */
      41             : 
      42             : const char qh_version[]= "2020.2.r 2020/08/31";
      43             : const char qh_version2[]= "qhull_r 8.0.2 (2020.2.r 2020/08/31)";
      44             : 
      45             : /*-<a                             href="qh-globa_r.htm#TOC"
      46             :   >-------------------------------</a><a name="appendprint">-</a>
      47             : 
      48             :   qh_appendprint(qh, printFormat )
      49             :     append printFormat to qh.PRINTout unless already defined
      50             : */
      51           0 : void qh_appendprint(qhT *qh, qh_PRINT format) {
      52             :   int i;
      53             : 
      54           0 :   for (i=0; i < qh_PRINTEND; i++) {
      55           0 :     if (qh->PRINTout[i] == format && format != qh_PRINTqhull)
      56           0 :       break;
      57           0 :     if (!qh->PRINTout[i]) {
      58           0 :       qh->PRINTout[i]= format;
      59           0 :       break;
      60             :     }
      61             :   }
      62           0 : } /* appendprint */
      63             : 
      64             : /*-<a                             href="qh-globa_r.htm#TOC"
      65             :   >-------------------------------</a><a name="checkflags">-</a>
      66             : 
      67             :   qh_checkflags(qh, commandStr, hiddenFlags )
      68             :     errors if commandStr contains hiddenFlags
      69             :     hiddenFlags starts and ends with a space and is space delimited (checked)
      70             : 
      71             :   notes:
      72             :     ignores first word (e.g., "qconvex i")
      73             :     use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
      74             : 
      75             :   see:
      76             :     qh_initflags() initializes Qhull according to commandStr
      77             : */
      78           0 : void qh_checkflags(qhT *qh, char *command, char *hiddenflags) {
      79           0 :   char *s= command, *t, *chkerr; /* qh_skipfilename is non-const */
      80             :   char key, opt, prevopt;
      81           0 :   char chkkey[]=  "   ";    /* check one character options ('s') */
      82           0 :   char chkopt[]=  "    ";   /* check two character options ('Ta') */
      83           0 :   char chkopt2[]= "     ";  /* check three character options ('Q12') */
      84           0 :   boolT waserr= False;
      85             : 
      86           0 :   if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') {
      87           0 :     qh_fprintf(qh, qh->ferr, 6026, "qhull internal error (qh_checkflags): hiddenflags must start and end with a space: \"%s\"\n", hiddenflags);
      88           0 :     qh_errexit(qh, qh_ERRqhull, NULL, NULL);
      89             :   }
      90           0 :   if (strpbrk(hiddenflags, ",\n\r\t")) {
      91           0 :     qh_fprintf(qh, qh->ferr, 6027, "qhull internal error (qh_checkflags): hiddenflags contains commas, newlines, or tabs: \"%s\"\n", hiddenflags);
      92           0 :     qh_errexit(qh, qh_ERRqhull, NULL, NULL);
      93             :   }
      94           0 :   while (*s && !isspace(*s))  /* skip program name */
      95           0 :     s++;
      96           0 :   while (*s) {
      97           0 :     while (*s && isspace(*s))
      98           0 :       s++;
      99           0 :     if (*s == '-')
     100           0 :       s++;
     101           0 :     if (!*s)
     102           0 :       break;
     103           0 :     key= *s++;
     104           0 :     chkerr= NULL;
     105           0 :     if (key == 'T' && (*s == 'I' || *s == 'O')) {  /* TI or TO 'file name' */
     106           0 :       s= qh_skipfilename(qh, ++s);
     107           0 :       continue;
     108             :     }
     109           0 :     chkkey[1]= key;
     110           0 :     if (strstr(hiddenflags, chkkey)) {
     111           0 :       chkerr= chkkey;
     112           0 :     }else if (isupper(key)) {
     113           0 :       opt= ' ';
     114           0 :       prevopt= ' ';
     115           0 :       chkopt[1]= key;
     116           0 :       chkopt2[1]= key;
     117           0 :       while (!chkerr && *s && !isspace(*s)) {
     118           0 :         opt= *s++;
     119           0 :         if (isalpha(opt)) {
     120           0 :           chkopt[2]= opt;
     121           0 :           if (strstr(hiddenflags, chkopt))
     122           0 :             chkerr= chkopt;
     123           0 :           if (prevopt != ' ') {
     124           0 :             chkopt2[2]= prevopt;
     125           0 :             chkopt2[3]= opt;
     126           0 :             if (strstr(hiddenflags, chkopt2))
     127           0 :               chkerr= chkopt2;
     128             :           }
     129           0 :         }else if (key == 'Q' && isdigit(opt) && prevopt != 'b'
     130           0 :               && (prevopt == ' ' || islower(prevopt))) {
     131           0 :             if (isdigit(*s)) {  /* Q12 */
     132           0 :               chkopt2[2]= opt;
     133           0 :               chkopt2[3]= *s++;
     134           0 :               if (strstr(hiddenflags, chkopt2))
     135           0 :                 chkerr= chkopt2;
     136             :             }else {
     137           0 :               chkopt[2]= opt;
     138           0 :               if (strstr(hiddenflags, chkopt))
     139           0 :                 chkerr= chkopt;
     140             :             }
     141             :         }else {
     142           0 :           qh_strtod(s-1, &t);
     143           0 :           if (s < t)
     144           0 :             s= t;
     145             :         }
     146           0 :         prevopt= opt;
     147             :       }
     148             :     }
     149           0 :     if (chkerr) {
     150           0 :       *chkerr= '\'';
     151           0 :       chkerr[strlen(chkerr)-1]=  '\'';
     152           0 :       qh_fprintf(qh, qh->ferr, 6029, "qhull option error: option %s is not used with this program.\n             It may be used with qhull.\n", chkerr);
     153           0 :       waserr= True;
     154             :     }
     155             :   }
     156           0 :   if (waserr)
     157           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
     158           0 : } /* checkflags */
     159             : 
     160             : /*-<a                             href="qh-globa_r.htm#TOC"
     161             :   >-------------------------------</a><a name="clear_outputflags">-</a>
     162             : 
     163             :   qh_clear_outputflags(qh)
     164             :     Clear output flags for QhullPoints
     165             : */
     166           0 : void qh_clear_outputflags(qhT *qh) {
     167             :   int i,k;
     168             : 
     169           0 :   qh->ANNOTATEoutput= False;
     170           0 :   qh->DOintersections= False;
     171           0 :   qh->DROPdim= -1;
     172           0 :   qh->FORCEoutput= False;
     173           0 :   qh->GETarea= False;
     174           0 :   qh->GOODpoint= 0;
     175           0 :   qh->GOODpointp= NULL;
     176           0 :   qh->GOODthreshold= False;
     177           0 :   qh->GOODvertex= 0;
     178           0 :   qh->GOODvertexp= NULL;
     179           0 :   qh->IStracing= 0;
     180           0 :   qh->KEEParea= False;
     181           0 :   qh->KEEPmerge= False;
     182           0 :   qh->KEEPminArea= REALmax;
     183           0 :   qh->PRINTcentrums= False;
     184           0 :   qh->PRINTcoplanar= False;
     185           0 :   qh->PRINTdots= False;
     186           0 :   qh->PRINTgood= False;
     187           0 :   qh->PRINTinner= False;
     188           0 :   qh->PRINTneighbors= False;
     189           0 :   qh->PRINTnoplanes= False;
     190           0 :   qh->PRINToptions1st= False;
     191           0 :   qh->PRINTouter= False;
     192           0 :   qh->PRINTprecision= True;
     193           0 :   qh->PRINTridges= False;
     194           0 :   qh->PRINTspheres= False;
     195           0 :   qh->PRINTstatistics= False;
     196           0 :   qh->PRINTsummary= False;
     197           0 :   qh->PRINTtransparent= False;
     198           0 :   qh->SPLITthresholds= False;
     199           0 :   qh->TRACElevel= 0;
     200           0 :   qh->TRInormals= False;
     201           0 :   qh->USEstdout= False;
     202           0 :   qh->VERIFYoutput= False;
     203           0 :   for (k=qh->input_dim+1; k--; ) {  /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
     204           0 :     qh->lower_threshold[k]= -REALmax;
     205           0 :     qh->upper_threshold[k]= REALmax;
     206           0 :     qh->lower_bound[k]= -REALmax;
     207           0 :     qh->upper_bound[k]= REALmax;
     208             :   }
     209             : 
     210           0 :   for (i=0; i < qh_PRINTEND; i++) {
     211           0 :     qh->PRINTout[i]= qh_PRINTnone;
     212             :   }
     213             : 
     214           0 :   if (!qh->qhull_commandsiz2)
     215           0 :       qh->qhull_commandsiz2= (int)strlen(qh->qhull_command); /* WARN64 */
     216             :   else {
     217           0 :       qh->qhull_command[qh->qhull_commandsiz2]= '\0';
     218             :   }
     219           0 :   if (!qh->qhull_optionsiz2)
     220           0 :     qh->qhull_optionsiz2= (int)strlen(qh->qhull_options);  /* WARN64 */
     221             :   else {
     222           0 :     qh->qhull_options[qh->qhull_optionsiz2]= '\0';
     223           0 :     qh->qhull_optionlen= qh_OPTIONline;  /* start a new line */
     224             :   }
     225           0 : } /* clear_outputflags */
     226             : 
     227             : /*-<a                             href="qh-globa_r.htm#TOC"
     228             :   >-------------------------------</a><a name="clock">-</a>
     229             : 
     230             :   qh_clock()
     231             :     return user CPU time in 100ths (qh_SECtick)
     232             :     only defined for qh_CLOCKtype == 2
     233             : 
     234             :   notes:
     235             :     use first value to determine time 0
     236             :     from Stevens '92 8.15
     237             : */
     238           0 : unsigned long qh_clock(qhT *qh) {
     239             : 
     240             : #if (qh_CLOCKtype == 2)
     241             :   struct tms time;
     242             :   static long clktck;  /* initialized first call and never updated */
     243             :   double ratio, cpu;
     244             :   unsigned long ticks;
     245             : 
     246             :   if (!clktck) {
     247             :     if ((clktck= sysconf(_SC_CLK_TCK)) < 0) {
     248             :       qh_fprintf(qh, qh->ferr, 6030, "qhull internal error (qh_clock): sysconf() failed.  Use qh_CLOCKtype 1 in user_r.h\n");
     249             :       qh_errexit(qh, qh_ERRqhull, NULL, NULL);
     250             :     }
     251             :   }
     252             :   if (times(&time) == -1) {
     253             :     qh_fprintf(qh, qh->ferr, 6031, "qhull internal error (qh_clock): times() failed.  Use qh_CLOCKtype 1 in user_r.h\n");
     254             :     qh_errexit(qh, qh_ERRqhull, NULL, NULL);
     255             :   }
     256             :   ratio= qh_SECticks / (double)clktck;
     257             :   ticks= time.tms_utime * ratio;
     258             :   return ticks;
     259             : #else
     260           0 :   qh_fprintf(qh, qh->ferr, 6032, "qhull internal error (qh_clock): use qh_CLOCKtype 2 in user_r.h\n");
     261           0 :   qh_errexit(qh, qh_ERRqhull, NULL, NULL); /* never returns */
     262           0 :   return 0;
     263             : #endif
     264             : } /* clock */
     265             : 
     266             : /*-<a                             href="qh-globa_r.htm#TOC"
     267             :   >-------------------------------</a><a name="freebuffers">-</a>
     268             : 
     269             :   qh_freebuffers()
     270             :     free up global memory buffers
     271             : 
     272             :   notes:
     273             :     must match qh_initbuffers()
     274             : */
     275           5 : void qh_freebuffers(qhT *qh) {
     276             : 
     277           5 :   trace5((qh, qh->ferr, 5001, "qh_freebuffers: freeing up global memory buffers\n"));
     278             :   /* allocated by qh_initqhull_buffers */
     279           5 :   qh_setfree(qh, &qh->other_points);
     280           5 :   qh_setfree(qh, &qh->del_vertices);
     281           5 :   qh_setfree(qh, &qh->coplanarfacetset);
     282           5 :   qh_memfree(qh, qh->NEARzero, qh->hull_dim * (int)sizeof(realT));
     283           5 :   qh_memfree(qh, qh->lower_threshold, (qh->input_dim+1) * (int)sizeof(realT));
     284           5 :   qh_memfree(qh, qh->upper_threshold, (qh->input_dim+1) * (int)sizeof(realT));
     285           5 :   qh_memfree(qh, qh->lower_bound, (qh->input_dim+1) * (int)sizeof(realT));
     286           5 :   qh_memfree(qh, qh->upper_bound, (qh->input_dim+1) * (int)sizeof(realT));
     287           5 :   qh_memfree(qh, qh->gm_matrix, (qh->hull_dim+1) * qh->hull_dim * (int)sizeof(coordT));
     288           5 :   qh_memfree(qh, qh->gm_row, (qh->hull_dim+1) * (int)sizeof(coordT *));
     289           5 :   qh->NEARzero= qh->lower_threshold= qh->upper_threshold= NULL;
     290           5 :   qh->lower_bound= qh->upper_bound= NULL;
     291           5 :   qh->gm_matrix= NULL;
     292           5 :   qh->gm_row= NULL;
     293             : 
     294           5 :   if (qh->line)                /* allocated by qh_readinput, freed if no error */
     295           0 :     qh_free(qh->line);
     296           5 :   if (qh->half_space)
     297           0 :     qh_free(qh->half_space);
     298           5 :   if (qh->temp_malloc)
     299           0 :     qh_free(qh->temp_malloc);
     300           5 :   if (qh->feasible_point)      /* allocated by qh_readfeasible */
     301           0 :     qh_free(qh->feasible_point);
     302           5 :   if (qh->feasible_string)     /* allocated by qh_initflags */
     303           0 :     qh_free(qh->feasible_string);
     304           5 :   qh->line= qh->feasible_string= NULL;
     305           5 :   qh->half_space= qh->feasible_point= qh->temp_malloc= NULL;
     306             :   /* usually allocated by qh_readinput */
     307           5 :   if (qh->first_point && qh->POINTSmalloc) {
     308           4 :     qh_free(qh->first_point);
     309           4 :     qh->first_point= NULL;
     310             :   }
     311           5 :   if (qh->input_points && qh->input_malloc) { /* set by qh_joggleinput */
     312           0 :     qh_free(qh->input_points);
     313           0 :     qh->input_points= NULL;
     314             :   }
     315           5 :   trace5((qh, qh->ferr, 5002, "qh_freebuffers: finished\n"));
     316           5 : } /* freebuffers */
     317             : 
     318             : 
     319             : /*-<a                             href="qh-globa_r.htm#TOC"
     320             :   >-------------------------------</a><a name="freebuild">-</a>
     321             : 
     322             :   qh_freebuild(qh, allmem )
     323             :     free global memory used by qh_initbuild and qh_buildhull
     324             :     if !allmem,
     325             :       does not free short memory (e.g., facetT, freed by qh_memfreeshort)
     326             : 
     327             :   design:
     328             :     free centrums
     329             :     free each vertex
     330             :     for each facet
     331             :       free ridges
     332             :       free outside set, coplanar set, neighbor set, ridge set, vertex set
     333             :       free facet
     334             :     free hash table
     335             :     free interior point
     336             :     free merge sets
     337             :     free temporary sets
     338             : */
     339           5 : void qh_freebuild(qhT *qh, boolT allmem) {
     340             :   facetT *facet /*, *previousfacet= NULL*/;
     341             :   vertexT *vertex /*, *previousvertex= NULL*/;
     342             :   ridgeT *ridge, **ridgep /*, *previousridge= NULL */;
     343             :   mergeT *merge, **mergep;
     344             :   int newsize;
     345             :   boolT freeall;
     346             : 
     347             :   /* free qhT global sets first, includes references from qh_buildhull */
     348           5 :   trace5((qh, qh->ferr, 5004, "qh_freebuild: free global sets\n"));
     349           5 :   FOREACHmerge_(qh->facet_mergeset)  /* usually empty */
     350           0 :     qh_memfree(qh, merge, (int)sizeof(mergeT));
     351           5 :   FOREACHmerge_(qh->degen_mergeset)  /* usually empty */
     352           0 :     qh_memfree(qh, merge, (int)sizeof(mergeT));
     353           5 :   FOREACHmerge_(qh->vertex_mergeset)  /* usually empty */
     354           0 :     qh_memfree(qh, merge, (int)sizeof(mergeT));
     355           5 :   qh->facet_mergeset= NULL;  /* temp set freed by qh_settempfree_all */
     356           5 :   qh->degen_mergeset= NULL;  /* temp set freed by qh_settempfree_all */
     357           5 :   qh->vertex_mergeset= NULL;  /* temp set freed by qh_settempfree_all */
     358           5 :   qh_setfree(qh, &(qh->hash_table));
     359           5 :   trace5((qh, qh->ferr, 5003, "qh_freebuild: free temporary sets (qh_settempfree_all)\n"));
     360           5 :   qh_settempfree_all(qh);
     361           5 :   trace1((qh, qh->ferr, 1005, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n"));
     362           5 :   if (qh->del_vertices)
     363           4 :     qh_settruncate(qh, qh->del_vertices, 0);
     364           5 :   if (allmem) {
     365           0 :     while ((vertex= qh->vertex_list)) {
     366           0 :       if (vertex->next)
     367           0 :         qh_delvertex(qh, vertex);
     368             :       else {
     369           0 :         qh_memfree(qh, vertex, (int)sizeof(vertexT)); /* sentinel */
     370           0 :         qh->newvertex_list= qh->vertex_list= NULL;
     371           0 :         break;
     372             :       }
     373             :       /* previousvertex= vertex; */ /* in case of memory fault */
     374             :       /* QHULL_UNUSED(previousvertex) */
     375             :     }
     376           5 :   }else if (qh->VERTEXneighbors) {
     377       14675 :     FORALLvertices
     378       14672 :       qh_setfreelong(qh, &(vertex->neighbors));
     379             :   }
     380           5 :   qh->VERTEXneighbors= False;
     381           5 :   qh->GOODclosest= NULL;
     382           5 :   if (allmem) {
     383           0 :     FORALLfacets {
     384           0 :       FOREACHridge_(facet->ridges)
     385           0 :         ridge->seen= False;
     386             :     }
     387           0 :     while ((facet= qh->facet_list)) {
     388           0 :       if (!facet->newfacet || !qh->NEWtentative || qh_setsize(qh, facet->ridges) > 1) { /* skip tentative horizon ridges */
     389           0 :         trace4((qh, qh->ferr, 4095, "qh_freebuild: delete the previously-seen ridges of f%d\n", facet->id));
     390           0 :         FOREACHridge_(facet->ridges) {
     391           0 :           if (ridge->seen)
     392           0 :             qh_delridge(qh, ridge);
     393             :           else
     394           0 :             ridge->seen= True;
     395             :           /* previousridge= ridge; */ /* in case of memory fault */
     396             :           /* QHULL_UNUSED(previousridge) */
     397             :         }
     398             :       }
     399           0 :       qh_setfree(qh, &(facet->outsideset));
     400           0 :       qh_setfree(qh, &(facet->coplanarset));
     401           0 :       qh_setfree(qh, &(facet->neighbors));
     402           0 :       qh_setfree(qh, &(facet->ridges));
     403           0 :       qh_setfree(qh, &(facet->vertices));
     404           0 :       if (facet->next)
     405           0 :         qh_delfacet(qh, facet);
     406             :       else {
     407           0 :         qh_memfree(qh, facet, (int)sizeof(facetT));
     408           0 :         qh->visible_list= qh->newfacet_list= qh->facet_list= NULL;
     409             :       }
     410             :       /* previousfacet= facet; */ /* in case of memory fault */
     411             :       /* QHULL_UNUSED(previousfacet) */
     412             :     }
     413             :   }else {
     414           5 :     freeall= True;
     415           5 :     if (qh_setlarger_quick(qh, qh->hull_dim + 1, &newsize))
     416           4 :       freeall= False;
     417       29341 :     FORALLfacets {
     418       29336 :       qh_setfreelong(qh, &(facet->outsideset));
     419       29336 :       qh_setfreelong(qh, &(facet->coplanarset));
     420       29336 :       if (!facet->simplicial || freeall) {
     421           0 :         qh_setfreelong(qh, &(facet->neighbors));
     422           0 :         qh_setfreelong(qh, &(facet->ridges));
     423           0 :         qh_setfreelong(qh, &(facet->vertices));
     424             :       }
     425             :     }
     426             :   }
     427             :   /* qh internal constants */
     428           5 :   qh_memfree(qh, qh->interior_point, qh->normal_size);
     429           5 :   qh->interior_point= NULL;
     430           5 : } /* freebuild */
     431             : 
     432             : /*-<a                             href="qh-globa_r.htm#TOC"
     433             :   >-------------------------------</a><a name="freeqhull">-</a>
     434             : 
     435             :   qh_freeqhull(qh, allmem )
     436             : 
     437             :   free global memory and set qhT to 0
     438             :   if !allmem,
     439             :     does not free short memory (freed by qh_memfreeshort unless qh_NOmem)
     440             : 
     441             : notes:
     442             :   sets qh.NOerrexit in case caller forgets to
     443             :   Does not throw errors
     444             : 
     445             : see:
     446             :   see qh_initqhull_start2()
     447             :   For libqhull_r, qhstatT is part of qhT
     448             : 
     449             : design:
     450             :   free global and temporary memory from qh_initbuild and qh_buildhull
     451             :   free buffers
     452             : */
     453           5 : void qh_freeqhull(qhT *qh, boolT allmem) {
     454             : 
     455           5 :   qh->NOerrexit= True;  /* no more setjmp since called at exit and ~QhullQh */
     456           5 :   trace1((qh, qh->ferr, 1006, "qh_freeqhull: free global memory\n"));
     457           5 :   qh_freebuild(qh, allmem);
     458           5 :   qh_freebuffers(qh);
     459           5 :   trace1((qh, qh->ferr, 1061, "qh_freeqhull: clear qhT except for qh.qhmem and qh.qhstat\n"));
     460             :   /* memset is the same in qh_freeqhull() and qh_initqhull_start2() */
     461           5 :   memset((char *)qh, 0, sizeof(qhT)-sizeof(qhmemT)-sizeof(qhstatT));
     462           5 :   qh->NOerrexit= True;
     463           5 : } /* freeqhull */
     464             : 
     465             : /*-<a                             href="qh-globa_r.htm#TOC"
     466             :   >-------------------------------</a><a name="init_A">-</a>
     467             : 
     468             :   qh_init_A(qh, infile, outfile, errfile, argc, argv )
     469             :     initialize memory and stdio files
     470             :     convert input options to option string (qh.qhull_command)
     471             : 
     472             :   notes:
     473             :     infile may be NULL if qh_readpoints() is not called
     474             : 
     475             :     errfile should always be defined.  It is used for reporting
     476             :     errors.  outfile is used for output and format options.
     477             : 
     478             :     argc/argv may be 0/NULL
     479             : 
     480             :     called before error handling initialized
     481             :     qh_errexit() may not be used
     482             : */
     483           0 : void qh_init_A(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]) {
     484           0 :   qh_meminit(qh, errfile);
     485           0 :   qh_initqhull_start(qh, infile, outfile, errfile);
     486           0 :   qh_init_qhull_command(qh, argc, argv);
     487           0 : } /* init_A */
     488             : 
     489             : /*-<a                             href="qh-globa_r.htm#TOC"
     490             :   >-------------------------------</a><a name="init_B">-</a>
     491             : 
     492             :   qh_init_B(qh, points, numpoints, dim, ismalloc )
     493             :     initialize globals for points array
     494             : 
     495             :     points has numpoints dim-dimensional points
     496             :       points[0] is the first coordinate of the first point
     497             :       points[1] is the second coordinate of the first point
     498             :       points[dim] is the first coordinate of the second point
     499             : 
     500             :     ismalloc=True
     501             :       Qhull will call qh_free(points) on exit or input transformation
     502             :     ismalloc=False
     503             :       Qhull will allocate a new point array if needed for input transformation
     504             : 
     505             :     qh.qhull_command
     506             :       is the option string.
     507             :       It is defined by qh_init_B(), qh_qhull_command(), or qh_initflags
     508             : 
     509             :   returns:
     510             :     if qh.PROJECTinput or (qh.DELAUNAY and qh.PROJECTdelaunay)
     511             :       projects the input to a new point array
     512             : 
     513             :         if qh.DELAUNAY,
     514             :           qh.hull_dim is increased by one
     515             :         if qh.ATinfinity,
     516             :           qh_projectinput adds point-at-infinity for Delaunay tri.
     517             : 
     518             :     if qh.SCALEinput
     519             :       changes the upper and lower bounds of the input, see qh_scaleinput
     520             : 
     521             :     if qh.ROTATEinput
     522             :       rotates the input by a random rotation, see qh_rotateinput
     523             :       if qh.DELAUNAY
     524             :         rotates about the last coordinate
     525             : 
     526             :   notes:
     527             :     called after points are defined
     528             :     qh_errexit() may be used
     529             : */
     530           5 : void qh_init_B(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc) {
     531           5 :   qh_initqhull_globals(qh, points, numpoints, dim, ismalloc);
     532           4 :   if (qh->qhmem.LASTsize == 0)
     533           4 :     qh_initqhull_mem(qh);
     534             :   /* mem_r.c and qset_r.c are initialized */
     535           4 :   qh_initqhull_buffers(qh);
     536           4 :   qh_initthresholds(qh, qh->qhull_command);
     537           4 :   if (qh->PROJECTinput || (qh->DELAUNAY && qh->PROJECTdelaunay))
     538           4 :     qh_projectinput(qh);
     539           4 :   if (qh->SCALEinput)
     540           0 :     qh_scaleinput(qh);
     541           4 :   if (qh->ROTATErandom >= 0) {
     542           0 :     qh_randommatrix(qh, qh->gm_matrix, qh->hull_dim, qh->gm_row);
     543           0 :     if (qh->DELAUNAY) {
     544           0 :       int k, lastk= qh->hull_dim-1;
     545           0 :       for (k=0; k < lastk; k++) {
     546           0 :         qh->gm_row[k][lastk]= 0.0;
     547           0 :         qh->gm_row[lastk][k]= 0.0;
     548             :       }
     549           0 :       qh->gm_row[lastk][lastk]= 1.0;
     550             :     }
     551           0 :     qh_gram_schmidt(qh, qh->hull_dim, qh->gm_row);
     552           0 :     qh_rotateinput(qh, qh->gm_row);
     553             :   }
     554           4 : } /* init_B */
     555             : 
     556             : /*-<a                             href="qh-globa_r.htm#TOC"
     557             :   >-------------------------------</a><a name="init_qhull_command">-</a>
     558             : 
     559             :   qh_init_qhull_command(qh, argc, argv )
     560             :     build qh.qhull_command from argc/argv
     561             :     Calls qh_exit if qhull_command is too short
     562             : 
     563             :   returns:
     564             :     a space-delimited string of options (just as typed)
     565             : 
     566             :   notes:
     567             :     makes option string easy to input and output
     568             : 
     569             :     argc/argv may be 0/NULL
     570             : */
     571           0 : void qh_init_qhull_command(qhT *qh, int argc, char *argv[]) {
     572             : 
     573           0 :   if (!qh_argv_to_command(argc, argv, qh->qhull_command, (int)sizeof(qh->qhull_command))){
     574             :     /* Assumes qh.ferr is defined. */
     575           0 :     qh_fprintf(qh, qh->ferr, 6033, "qhull input error: more than %d characters in command line.\n",
     576             :           (int)sizeof(qh->qhull_command));
     577           0 :     qh_exit(qh_ERRinput);  /* error reported, can not use qh_errexit */
     578             :   }
     579           0 : } /* init_qhull_command */
     580             : 
     581             : /*-<a                             href="qh-globa_r.htm#TOC"
     582             :   >-------------------------------</a><a name="initflags">-</a>
     583             : 
     584             :   qh_initflags(qh, commandStr )
     585             :     set flags and initialized constants from commandStr
     586             :     calls qh_exit() if qh.NOerrexit
     587             : 
     588             :   returns:
     589             :     sets qh.qhull_command to command if needed
     590             : 
     591             :   notes:
     592             :     ignores first word (e.g., 'qhull' in "qhull d")
     593             :     use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
     594             : 
     595             :   see:
     596             :     qh_initthresholds() continues processing of 'Pdn' and 'PDn'
     597             :     'prompt' in unix_r.c for documentation
     598             : 
     599             :   design:
     600             :     for each space-delimited option group
     601             :       if top-level option
     602             :         check syntax
     603             :         append appropriate option to option string
     604             :         set appropriate global variable or append printFormat to print options
     605             :       else
     606             :         for each sub-option
     607             :           check syntax
     608             :           append appropriate option to option string
     609             :           set appropriate global variable or append printFormat to print options
     610             : */
     611           5 : void qh_initflags(qhT *qh, char *command) {
     612             :   int k, i, lastproject;
     613           5 :   char *s= command, *t = NULL, *prev_s, *start, key, *lastwarning= NULL;
     614           5 :   boolT isgeom= False, wasproject;
     615             :   realT r;
     616             : 
     617           5 :   if(qh->NOerrexit){
     618           0 :     qh_fprintf(qh, qh->ferr, 6245, "qhull internal error (qh_initflags): qh.NOerrexit was not cleared before calling qh_initflags().  It should be cleared after setjmp().  Exit qhull.\n");
     619           0 :     qh_exit(qh_ERRqhull);
     620             :   }
     621             : #ifdef qh_RANDOMdist
     622             :   qh->RANDOMfactor= qh_RANDOMdist;
     623             :   qh_option(qh, "Random-qh_RANDOMdist", NULL, &qh->RANDOMfactor);
     624             :   qh->RANDOMdist= True;
     625             : #endif
     626           5 :   if (command <= &qh->qhull_command[0] || command > &qh->qhull_command[0] + sizeof(qh->qhull_command)) {
     627           5 :     if (command != &qh->qhull_command[0]) {
     628           5 :       *qh->qhull_command= '\0';
     629           5 :       strncat(qh->qhull_command, command, sizeof(qh->qhull_command)-strlen(qh->qhull_command)-1);
     630             :     }
     631          30 :     while (*s && !isspace(*s))  /* skip program name */
     632          25 :       s++;
     633             :   }
     634          30 :   while (*s) {
     635          50 :     while (*s && isspace(*s))
     636          25 :       s++;
     637          25 :     if (*s == '-')
     638           0 :       s++;
     639          25 :     if (!*s)
     640           0 :       break;
     641          25 :     prev_s= s;
     642          25 :     switch (*s++) {
     643           5 :     case 'd':
     644           5 :       qh_option(qh, "delaunay", NULL, NULL);
     645           5 :       qh->DELAUNAY= True;
     646           5 :       break;
     647           0 :     case 'f':
     648           0 :       qh_option(qh, "facets", NULL, NULL);
     649           0 :       qh_appendprint(qh, qh_PRINTfacets);
     650           0 :       break;
     651           0 :     case 'i':
     652           0 :       qh_option(qh, "incidence", NULL, NULL);
     653           0 :       qh_appendprint(qh, qh_PRINTincidences);
     654           0 :       break;
     655           0 :     case 'm':
     656           0 :       qh_option(qh, "mathematica", NULL, NULL);
     657           0 :       qh_appendprint(qh, qh_PRINTmathematica);
     658           0 :       break;
     659           0 :     case 'n':
     660           0 :       qh_option(qh, "normals", NULL, NULL);
     661           0 :       qh_appendprint(qh, qh_PRINTnormals);
     662           0 :       break;
     663           0 :     case 'o':
     664           0 :       qh_option(qh, "offFile", NULL, NULL);
     665           0 :       qh_appendprint(qh, qh_PRINToff);
     666           0 :       break;
     667           0 :     case 'p':
     668           0 :       qh_option(qh, "points", NULL, NULL);
     669           0 :       qh_appendprint(qh, qh_PRINTpoints);
     670           0 :       break;
     671           0 :     case 's':
     672           0 :       qh_option(qh, "summary", NULL, NULL);
     673           0 :       qh->PRINTsummary= True;
     674           0 :       break;
     675           0 :     case 'v':
     676           0 :       qh_option(qh, "voronoi", NULL, NULL);
     677           0 :       qh->VORONOI= True;
     678           0 :       qh->DELAUNAY= True;
     679           0 :       break;
     680           0 :     case 'A':
     681           0 :       if (!isdigit(*s) && *s != '.' && *s != '-') {
     682           0 :         qh_fprintf(qh, qh->ferr, 7002, "qhull input warning: no maximum cosine angle given for option 'An'.  A1.0 is coplanar\n");
     683           0 :         lastwarning= s-1;
     684             :       }else {
     685           0 :         if (*s == '-') {
     686           0 :           qh->premerge_cos= -qh_strtod(s, &s);
     687           0 :           qh_option(qh, "Angle-premerge-", NULL, &qh->premerge_cos);
     688           0 :           qh->PREmerge= True;
     689             :         }else {
     690           0 :           qh->postmerge_cos= qh_strtod(s, &s);
     691           0 :           qh_option(qh, "Angle-postmerge", NULL, &qh->postmerge_cos);
     692           0 :           qh->POSTmerge= True;
     693             :         }
     694           0 :         qh->MERGING= True;
     695             :       }
     696           0 :       break;
     697           0 :     case 'C':
     698           0 :       if (!isdigit(*s) && *s != '.' && *s != '-') {
     699           0 :         qh_fprintf(qh, qh->ferr, 7003, "qhull input warning: no centrum radius given for option 'Cn'\n");
     700           0 :         lastwarning= s-1;
     701             :       }else {
     702           0 :         if (*s == '-') {
     703           0 :           qh->premerge_centrum= -qh_strtod(s, &s);
     704           0 :           qh_option(qh, "Centrum-premerge-", NULL, &qh->premerge_centrum);
     705           0 :           qh->PREmerge= True;
     706             :         }else {
     707           0 :           qh->postmerge_centrum= qh_strtod(s, &s);
     708           0 :           qh_option(qh, "Centrum-postmerge", NULL, &qh->postmerge_centrum);
     709           0 :           qh->POSTmerge= True;
     710             :         }
     711           0 :         qh->MERGING= True;
     712             :       }
     713           0 :       break;
     714           0 :     case 'E':
     715           0 :       if (*s == '-') {
     716           0 :         qh_fprintf(qh, qh->ferr, 6363, "qhull option error: expecting a positive number for maximum roundoff 'En'.  Got '%s'\n", s-1);
     717           0 :         qh_errexit(qh, qh_ERRinput, NULL, NULL);
     718           0 :       }else if (!isdigit(*s)) {
     719           0 :         qh_fprintf(qh, qh->ferr, 7005, "qhull option warning: no maximum roundoff given for option 'En'\n");
     720           0 :         lastwarning= s-1;
     721             :       }else {
     722           0 :         qh->DISTround= qh_strtod(s, &s);
     723           0 :         qh_option(qh, "Distance-roundoff", NULL, &qh->DISTround);
     724           0 :         qh->SETroundoff= True;
     725             :       }
     726           0 :       break;
     727           0 :     case 'H':
     728           0 :       start= s;
     729           0 :       qh->HALFspace= True;
     730           0 :       qh_strtod(s, &t);
     731           0 :       while (t > s)  {
     732           0 :         if (*t && !isspace(*t)) {
     733           0 :           if (*t == ',')
     734           0 :             t++;
     735             :           else {
     736           0 :             qh_fprintf(qh, qh->ferr, 6364, "qhull option error: expecting 'Hn,n,n,...' for feasible point of halfspace intersection. Got '%s'\n", start-1);
     737           0 :             qh_errexit(qh, qh_ERRinput, NULL, NULL);
     738             :           }
     739             :         }
     740           0 :         s= t;
     741           0 :         qh_strtod(s, &t);
     742             :       }
     743           0 :       if (start < t) {
     744           0 :         if (!(qh->feasible_string= (char *)calloc((size_t)(t-start+1), (size_t)1))) {
     745           0 :           qh_fprintf(qh, qh->ferr, 6034, "qhull error: insufficient memory for 'Hn,n,n'\n");
     746           0 :           qh_errexit(qh, qh_ERRmem, NULL, NULL);
     747             :         }
     748           0 :         strncpy(qh->feasible_string, start, (size_t)(t-start));
     749           0 :         qh_option(qh, "Halfspace-about", NULL, NULL);
     750           0 :         qh_option(qh, qh->feasible_string, NULL, NULL);
     751             :       }else
     752           0 :         qh_option(qh, "Halfspace", NULL, NULL);
     753           0 :       break;
     754           0 :     case 'R':
     755           0 :       if (!isdigit(*s)) {
     756           0 :         qh_fprintf(qh, qh->ferr, 7007, "qhull option warning: missing random perturbation for option 'Rn'\n");
     757           0 :         lastwarning= s-1;
     758             :       }else {
     759           0 :         qh->RANDOMfactor= qh_strtod(s, &s);
     760           0 :         qh_option(qh, "Random-perturb", NULL, &qh->RANDOMfactor);
     761           0 :         qh->RANDOMdist= True;
     762             :       }
     763           0 :       break;
     764           0 :     case 'V':
     765           0 :       if (!isdigit(*s) && *s != '-') {
     766           0 :         qh_fprintf(qh, qh->ferr, 7008, "qhull option warning: missing visible distance for option 'Vn'\n");
     767           0 :         lastwarning= s-1;
     768             :       }else {
     769           0 :         qh->MINvisible= qh_strtod(s, &s);
     770           0 :         qh_option(qh, "Visible", NULL, &qh->MINvisible);
     771             :       }
     772           0 :       break;
     773           0 :     case 'U':
     774           0 :       if (!isdigit(*s) && *s != '-') {
     775           0 :         qh_fprintf(qh, qh->ferr, 7009, "qhull option warning: missing coplanar distance for option 'Un'\n");
     776           0 :         lastwarning= s-1;
     777             :       }else {
     778           0 :         qh->MAXcoplanar= qh_strtod(s, &s);
     779           0 :         qh_option(qh, "U-coplanar", NULL, &qh->MAXcoplanar);
     780             :       }
     781           0 :       break;
     782           0 :     case 'W':
     783           0 :       if (*s == '-') {
     784           0 :         qh_fprintf(qh, qh->ferr, 6365, "qhull option error: expecting a positive number for outside width 'Wn'.  Got '%s'\n", s-1);
     785           0 :         qh_errexit(qh, qh_ERRinput, NULL, NULL);
     786           0 :       }else if (!isdigit(*s)) {
     787           0 :         qh_fprintf(qh, qh->ferr, 7011, "qhull option warning: missing outside width for option 'Wn'\n");
     788           0 :         lastwarning= s-1;
     789             :       }else {
     790           0 :         qh->MINoutside= qh_strtod(s, &s);
     791           0 :         qh_option(qh, "W-outside", NULL, &qh->MINoutside);
     792           0 :         qh->APPROXhull= True;
     793             :       }
     794           0 :       break;
     795             :     /************  sub menus ***************/
     796           0 :     case 'F':
     797           0 :       while (*s && !isspace(*s)) {
     798           0 :         switch (*s++) {
     799           0 :         case 'a':
     800           0 :           qh_option(qh, "Farea", NULL, NULL);
     801           0 :           qh_appendprint(qh, qh_PRINTarea);
     802           0 :           qh->GETarea= True;
     803           0 :           break;
     804           0 :         case 'A':
     805           0 :           qh_option(qh, "FArea-total", NULL, NULL);
     806           0 :           qh->GETarea= True;
     807           0 :           break;
     808           0 :         case 'c':
     809           0 :           qh_option(qh, "Fcoplanars", NULL, NULL);
     810           0 :           qh_appendprint(qh, qh_PRINTcoplanars);
     811           0 :           break;
     812           0 :         case 'C':
     813           0 :           qh_option(qh, "FCentrums", NULL, NULL);
     814           0 :           qh_appendprint(qh, qh_PRINTcentrums);
     815           0 :           break;
     816           0 :         case 'd':
     817           0 :           qh_option(qh, "Fd-cdd-in", NULL, NULL);
     818           0 :           qh->CDDinput= True;
     819           0 :           break;
     820           0 :         case 'D':
     821           0 :           qh_option(qh, "FD-cdd-out", NULL, NULL);
     822           0 :           qh->CDDoutput= True;
     823           0 :           break;
     824           0 :         case 'F':
     825           0 :           qh_option(qh, "FFacets-xridge", NULL, NULL);
     826           0 :           qh_appendprint(qh, qh_PRINTfacets_xridge);
     827           0 :           break;
     828           0 :         case 'i':
     829           0 :           qh_option(qh, "Finner", NULL, NULL);
     830           0 :           qh_appendprint(qh, qh_PRINTinner);
     831           0 :           break;
     832           0 :         case 'I':
     833           0 :           qh_option(qh, "FIDs", NULL, NULL);
     834           0 :           qh_appendprint(qh, qh_PRINTids);
     835           0 :           break;
     836           0 :         case 'm':
     837           0 :           qh_option(qh, "Fmerges", NULL, NULL);
     838           0 :           qh_appendprint(qh, qh_PRINTmerges);
     839           0 :           break;
     840           0 :         case 'M':
     841           0 :           qh_option(qh, "FMaple", NULL, NULL);
     842           0 :           qh_appendprint(qh, qh_PRINTmaple);
     843           0 :           break;
     844           0 :         case 'n':
     845           0 :           qh_option(qh, "Fneighbors", NULL, NULL);
     846           0 :           qh_appendprint(qh, qh_PRINTneighbors);
     847           0 :           break;
     848           0 :         case 'N':
     849           0 :           qh_option(qh, "FNeighbors-vertex", NULL, NULL);
     850           0 :           qh_appendprint(qh, qh_PRINTvneighbors);
     851           0 :           break;
     852           0 :         case 'o':
     853           0 :           qh_option(qh, "Fouter", NULL, NULL);
     854           0 :           qh_appendprint(qh, qh_PRINTouter);
     855           0 :           break;
     856           0 :         case 'O':
     857           0 :           if (qh->PRINToptions1st) {
     858           0 :             qh_option(qh, "FOptions", NULL, NULL);
     859           0 :             qh_appendprint(qh, qh_PRINToptions);
     860             :           }else
     861           0 :             qh->PRINToptions1st= True;
     862           0 :           break;
     863           0 :         case 'p':
     864           0 :           qh_option(qh, "Fpoint-intersect", NULL, NULL);
     865           0 :           qh_appendprint(qh, qh_PRINTpointintersect);
     866           0 :           break;
     867           0 :         case 'P':
     868           0 :           qh_option(qh, "FPoint-nearest", NULL, NULL);
     869           0 :           qh_appendprint(qh, qh_PRINTpointnearest);
     870           0 :           break;
     871           0 :         case 'Q':
     872           0 :           qh_option(qh, "FQhull", NULL, NULL);
     873           0 :           qh_appendprint(qh, qh_PRINTqhull);
     874           0 :           break;
     875           0 :         case 's':
     876           0 :           qh_option(qh, "Fsummary", NULL, NULL);
     877           0 :           qh_appendprint(qh, qh_PRINTsummary);
     878           0 :           break;
     879           0 :         case 'S':
     880           0 :           qh_option(qh, "FSize", NULL, NULL);
     881           0 :           qh_appendprint(qh, qh_PRINTsize);
     882           0 :           qh->GETarea= True;
     883           0 :           break;
     884           0 :         case 't':
     885           0 :           qh_option(qh, "Ftriangles", NULL, NULL);
     886           0 :           qh_appendprint(qh, qh_PRINTtriangles);
     887           0 :           break;
     888           0 :         case 'v':
     889             :           /* option set in qh_initqhull_globals */
     890           0 :           qh_appendprint(qh, qh_PRINTvertices);
     891           0 :           break;
     892           0 :         case 'V':
     893           0 :           qh_option(qh, "FVertex-average", NULL, NULL);
     894           0 :           qh_appendprint(qh, qh_PRINTaverage);
     895           0 :           break;
     896           0 :         case 'x':
     897           0 :           qh_option(qh, "Fxtremes", NULL, NULL);
     898           0 :           qh_appendprint(qh, qh_PRINTextremes);
     899           0 :           break;
     900           0 :         default:
     901           0 :           s--;
     902           0 :           qh_fprintf(qh, qh->ferr, 7012, "qhull option warning: unknown 'F' output option 'F%c', skip to next space\n", (int)s[0]);
     903           0 :           lastwarning= s-1;
     904           0 :           while (*++s && !isspace(*s));
     905           0 :           break;
     906             :         }
     907             :       }
     908           0 :       break;
     909           0 :     case 'G':
     910           0 :       isgeom= True;
     911           0 :       qh_appendprint(qh, qh_PRINTgeom);
     912           0 :       while (*s && !isspace(*s)) {
     913           0 :         switch (*s++) {
     914           0 :         case 'a':
     915           0 :           qh_option(qh, "Gall-points", NULL, NULL);
     916           0 :           qh->PRINTdots= True;
     917           0 :           break;
     918           0 :         case 'c':
     919           0 :           qh_option(qh, "Gcentrums", NULL, NULL);
     920           0 :           qh->PRINTcentrums= True;
     921           0 :           break;
     922           0 :         case 'h':
     923           0 :           qh_option(qh, "Gintersections", NULL, NULL);
     924           0 :           qh->DOintersections= True;
     925           0 :           break;
     926           0 :         case 'i':
     927           0 :           qh_option(qh, "Ginner", NULL, NULL);
     928           0 :           qh->PRINTinner= True;
     929           0 :           break;
     930           0 :         case 'n':
     931           0 :           qh_option(qh, "Gno-planes", NULL, NULL);
     932           0 :           qh->PRINTnoplanes= True;
     933           0 :           break;
     934           0 :         case 'o':
     935           0 :           qh_option(qh, "Gouter", NULL, NULL);
     936           0 :           qh->PRINTouter= True;
     937           0 :           break;
     938           0 :         case 'p':
     939           0 :           qh_option(qh, "Gpoints", NULL, NULL);
     940           0 :           qh->PRINTcoplanar= True;
     941           0 :           break;
     942           0 :         case 'r':
     943           0 :           qh_option(qh, "Gridges", NULL, NULL);
     944           0 :           qh->PRINTridges= True;
     945           0 :           break;
     946           0 :         case 't':
     947           0 :           qh_option(qh, "Gtransparent", NULL, NULL);
     948           0 :           qh->PRINTtransparent= True;
     949           0 :           break;
     950           0 :         case 'v':
     951           0 :           qh_option(qh, "Gvertices", NULL, NULL);
     952           0 :           qh->PRINTspheres= True;
     953           0 :           break;
     954           0 :         case 'D':
     955           0 :           if (!isdigit(*s)) {
     956           0 :             qh_fprintf(qh, qh->ferr, 7004, "qhull option warning: missing dimension for option 'GDn'\n");
     957           0 :             lastwarning= s-2;
     958             :           }else {
     959           0 :             if (qh->DROPdim >= 0) {
     960           0 :               qh_fprintf(qh, qh->ferr, 7013, "qhull option warning: can only drop one dimension.  Previous 'GD%d' ignored\n",
     961             :                    qh->DROPdim);
     962           0 :               lastwarning= s-2;
     963             :             }
     964           0 :             qh->DROPdim= qh_strtol(s, &s);
     965           0 :             qh_option(qh, "GDrop-dim", &qh->DROPdim, NULL);
     966             :           }
     967           0 :           break;
     968           0 :         default:
     969           0 :           s--;
     970           0 :           qh_fprintf(qh, qh->ferr, 7014, "qhull option warning: unknown 'G' geomview option 'G%c', skip to next space\n", (int)s[0]);
     971           0 :           lastwarning= s-1;
     972           0 :           while (*++s && !isspace(*s));
     973           0 :           break;
     974             :         }
     975             :       }
     976           0 :       break;
     977           0 :     case 'P':
     978           0 :       while (*s && !isspace(*s)) {
     979           0 :         switch (*s++) {
     980           0 :         case 'd': case 'D':  /* see qh_initthresholds() */
     981           0 :           key= s[-1];
     982           0 :           i= qh_strtol(s, &s);
     983           0 :           r= 0;
     984           0 :           if (*s == ':') {
     985           0 :             s++;
     986           0 :             r= qh_strtod(s, &s);
     987             :           }
     988           0 :           if (key == 'd')
     989           0 :             qh_option(qh, "Pdrop-facets-dim-less", &i, &r);
     990             :           else
     991           0 :             qh_option(qh, "PDrop-facets-dim-more", &i, &r);
     992           0 :           break;
     993           0 :         case 'g':
     994           0 :           qh_option(qh, "Pgood-facets", NULL, NULL);
     995           0 :           qh->PRINTgood= True;
     996           0 :           break;
     997           0 :         case 'G':
     998           0 :           qh_option(qh, "PGood-facet-neighbors", NULL, NULL);
     999           0 :           qh->PRINTneighbors= True;
    1000           0 :           break;
    1001           0 :         case 'o':
    1002           0 :           qh_option(qh, "Poutput-forced", NULL, NULL);
    1003           0 :           qh->FORCEoutput= True;
    1004           0 :           break;
    1005           0 :         case 'p':
    1006           0 :           qh_option(qh, "Pprecision-ignore", NULL, NULL);
    1007           0 :           qh->PRINTprecision= False;
    1008           0 :           break;
    1009           0 :         case 'A':
    1010           0 :           if (!isdigit(*s)) {
    1011           0 :             qh_fprintf(qh, qh->ferr, 7006, "qhull option warning: missing facet count for keep area option 'PAn'\n");
    1012           0 :             lastwarning= s-2;
    1013             :           }else {
    1014           0 :             qh->KEEParea= qh_strtol(s, &s);
    1015           0 :             qh_option(qh, "PArea-keep", &qh->KEEParea, NULL);
    1016           0 :             qh->GETarea= True;
    1017             :           }
    1018           0 :           break;
    1019           0 :         case 'F':
    1020           0 :           if (!isdigit(*s)) {
    1021           0 :             qh_fprintf(qh, qh->ferr, 7010, "qhull option warning: missing facet area for option 'PFn'\n");
    1022           0 :             lastwarning= s-2;
    1023             :           }else {
    1024           0 :             qh->KEEPminArea= qh_strtod(s, &s);
    1025           0 :             qh_option(qh, "PFacet-area-keep", NULL, &qh->KEEPminArea);
    1026           0 :             qh->GETarea= True;
    1027             :           }
    1028           0 :           break;
    1029           0 :         case 'M':
    1030           0 :           if (!isdigit(*s)) {
    1031           0 :             qh_fprintf(qh, qh->ferr, 7090, "qhull option warning: missing merge count for option 'PMn'\n");
    1032           0 :             lastwarning= s-2;
    1033             :           }else {
    1034           0 :             qh->KEEPmerge= qh_strtol(s, &s);
    1035           0 :             qh_option(qh, "PMerge-keep", &qh->KEEPmerge, NULL);
    1036             :           }
    1037           0 :           break;
    1038           0 :         default:
    1039           0 :           s--;
    1040           0 :           qh_fprintf(qh, qh->ferr, 7015, "qhull option warning: unknown 'P' print option 'P%c', skip to next space\n", (int)s[0]);
    1041           0 :           lastwarning= s-1;
    1042           0 :           while (*++s && !isspace(*s));
    1043           0 :           break;
    1044             :         }
    1045             :       }
    1046           0 :       break;
    1047          20 :     case 'Q':
    1048          20 :       lastproject= -1;
    1049          40 :       while (*s && !isspace(*s)) {
    1050          20 :         switch (*s++) {
    1051           0 :         case 'a':
    1052           0 :           qh_option(qh, "Qallow-short", NULL, NULL);
    1053           0 :           qh->ALLOWshort= True;
    1054           0 :           break;
    1055           5 :         case 'b': case 'B':  /* handled by qh_initthresholds */
    1056           5 :           key= s[-1];
    1057           5 :           if (key == 'b' && *s == 'B') {
    1058           0 :             s++;
    1059           0 :             r= qh_DEFAULTbox;
    1060           0 :             qh->SCALEinput= True;
    1061           0 :             qh_option(qh, "QbBound-unit-box", NULL, &r);
    1062           0 :             break;
    1063             :           }
    1064           5 :           if (key == 'b' && *s == 'b') {
    1065           5 :             s++;
    1066           5 :             qh->SCALElast= True;
    1067           5 :             qh_option(qh, "Qbbound-last", NULL, NULL);
    1068           5 :             break;
    1069             :           }
    1070           0 :           k= qh_strtol(s, &s);
    1071           0 :           r= 0.0;
    1072           0 :           wasproject= False;
    1073           0 :           if (*s == ':') {
    1074           0 :             s++;
    1075           0 :             if ((r= qh_strtod(s, &s)) == 0.0) {
    1076           0 :               t= s;            /* need true dimension for memory allocation */
    1077           0 :               while (*t && !isspace(*t)) {
    1078           0 :                 if (toupper(*t++) == 'B'
    1079           0 :                  && k == qh_strtol(t, &t)
    1080           0 :                  && *t++ == ':'
    1081           0 :                  && qh_strtod(t, &t) == 0.0) {
    1082           0 :                   qh->PROJECTinput++;
    1083           0 :                   trace2((qh, qh->ferr, 2004, "qh_initflags: project dimension %d\n", k));
    1084           0 :                   qh_option(qh, "Qb-project-dim", &k, NULL);
    1085           0 :                   wasproject= True;
    1086           0 :                   lastproject= k;
    1087           0 :                   break;
    1088             :                 }
    1089             :               }
    1090             :             }
    1091             :           }
    1092           0 :           if (!wasproject) {
    1093           0 :             if (lastproject == k && r == 0.0)
    1094           0 :               lastproject= -1;  /* doesn't catch all possible sequences */
    1095           0 :             else if (key == 'b') {
    1096           0 :               qh->SCALEinput= True;
    1097           0 :               if (r == 0.0)
    1098           0 :                 r= -qh_DEFAULTbox;
    1099           0 :               qh_option(qh, "Qbound-dim-low", &k, &r);
    1100             :             }else {
    1101           0 :               qh->SCALEinput= True;
    1102           0 :               if (r == 0.0)
    1103           0 :                 r= qh_DEFAULTbox;
    1104           0 :               qh_option(qh, "QBound-dim-high", &k, &r);
    1105             :             }
    1106             :           }
    1107           0 :           break;
    1108           5 :         case 'c':
    1109           5 :           qh_option(qh, "Qcoplanar-keep", NULL, NULL);
    1110           5 :           qh->KEEPcoplanar= True;
    1111           5 :           break;
    1112           0 :         case 'f':
    1113           0 :           qh_option(qh, "Qfurthest-outside", NULL, NULL);
    1114           0 :           qh->BESToutside= True;
    1115           0 :           break;
    1116           0 :         case 'g':
    1117           0 :           qh_option(qh, "Qgood-facets-only", NULL, NULL);
    1118           0 :           qh->ONLYgood= True;
    1119           0 :           break;
    1120           0 :         case 'i':
    1121           0 :           qh_option(qh, "Qinterior-keep", NULL, NULL);
    1122           0 :           qh->KEEPinside= True;
    1123           0 :           break;
    1124           0 :         case 'm':
    1125           0 :           qh_option(qh, "Qmax-outside-only", NULL, NULL);
    1126           0 :           qh->ONLYmax= True;
    1127           0 :           break;
    1128           0 :         case 'r':
    1129           0 :           qh_option(qh, "Qrandom-outside", NULL, NULL);
    1130           0 :           qh->RANDOMoutside= True;
    1131           0 :           break;
    1132           0 :         case 's':
    1133           0 :           qh_option(qh, "Qsearch-initial-simplex", NULL, NULL);
    1134           0 :           qh->ALLpoints= True;
    1135           0 :           break;
    1136           5 :         case 't':
    1137           5 :           qh_option(qh, "Qtriangulate", NULL, NULL);
    1138           5 :           qh->TRIangulate= True;
    1139           5 :           break;
    1140           0 :         case 'T':
    1141           0 :           qh_option(qh, "QTestPoints", NULL, NULL);
    1142           0 :           if (!isdigit(*s)) {
    1143           0 :             qh_fprintf(qh, qh->ferr, 7091, "qhull option warning: missing number of test points for option 'QTn'\n");
    1144           0 :             lastwarning= s-2;
    1145             :           }else {
    1146           0 :             qh->TESTpoints= qh_strtol(s, &s);
    1147           0 :             qh_option(qh, "QTestPoints", &qh->TESTpoints, NULL);
    1148             :           }
    1149           0 :           break;
    1150           0 :         case 'u':
    1151           0 :           qh_option(qh, "QupperDelaunay", NULL, NULL);
    1152           0 :           qh->UPPERdelaunay= True;
    1153           0 :           break;
    1154           0 :         case 'v':
    1155           0 :           qh_option(qh, "Qvertex-neighbors-convex", NULL, NULL);
    1156           0 :           qh->TESTvneighbors= True;
    1157           0 :           break;
    1158           0 :         case 'x':
    1159           0 :           qh_option(qh, "Qxact-merge", NULL, NULL);
    1160           0 :           qh->MERGEexact= True;
    1161           0 :           break;
    1162           5 :         case 'z':
    1163           5 :           qh_option(qh, "Qz-infinity-point", NULL, NULL);
    1164           5 :           qh->ATinfinity= True;
    1165           5 :           break;
    1166           0 :         case '0':
    1167           0 :           qh_option(qh, "Q0-no-premerge", NULL, NULL);
    1168           0 :           qh->NOpremerge= True;
    1169           0 :           break;
    1170           0 :         case '1':
    1171           0 :           if (!isdigit(*s)) {
    1172           0 :             qh_option(qh, "Q1-angle-merge", NULL, NULL);
    1173           0 :             qh->ANGLEmerge= True;
    1174           0 :             break;
    1175             :           }
    1176           0 :           switch (*s++) {
    1177           0 :           case '0':
    1178           0 :             qh_option(qh, "Q10-no-narrow", NULL, NULL);
    1179           0 :             qh->NOnarrow= True;
    1180           0 :             break;
    1181           0 :           case '1':
    1182           0 :             qh_option(qh, "Q11-trinormals Qtriangulate", NULL, NULL);
    1183           0 :             qh->TRInormals= True;
    1184           0 :             qh->TRIangulate= True;
    1185           0 :             break;
    1186           0 :           case '2':
    1187           0 :             qh_option(qh, "Q12-allow-wide", NULL, NULL);
    1188           0 :             qh->ALLOWwide= True;
    1189           0 :             break;
    1190           0 :           case '4':
    1191             : #ifndef qh_NOmerge
    1192           0 :             qh_option(qh, "Q14-merge-pinched-vertices", NULL, NULL);
    1193           0 :             qh->MERGEpinched= True;
    1194             : #else
    1195             :             /* ignore 'Q14' for q_benchmark testing of difficult cases for Qhull */
    1196             :             qh_fprintf(qh, qh->ferr, 7099, "qhull option warning: option 'Q14-merge-pinched' disabled due to qh_NOmerge\n");
    1197             : #endif
    1198           0 :             break;
    1199           0 :           case '7':
    1200           0 :             qh_option(qh, "Q15-check-duplicates", NULL, NULL);
    1201           0 :             qh->CHECKduplicates= True;
    1202           0 :             break;
    1203           0 :           default:
    1204           0 :             s--;
    1205           0 :             qh_fprintf(qh, qh->ferr, 7016, "qhull option warning: unknown 'Q' qhull option 'Q1%c', skip to next space\n", (int)s[0]);
    1206           0 :             lastwarning= s-1;
    1207           0 :             while (*++s && !isspace(*s));
    1208           0 :             break;
    1209             :           }
    1210           0 :           break;
    1211           0 :         case '2':
    1212           0 :           qh_option(qh, "Q2-no-merge-independent", NULL, NULL);
    1213           0 :           qh->MERGEindependent= False;
    1214           0 :           goto LABELcheckdigit;
    1215             :           break; /* no gcc warnings */
    1216           0 :         case '3':
    1217           0 :           qh_option(qh, "Q3-no-merge-vertices", NULL, NULL);
    1218           0 :           qh->MERGEvertices= False;
    1219           0 :         LABELcheckdigit:
    1220           0 :           if (isdigit(*s)) {
    1221           0 :             qh_fprintf(qh, qh->ferr, 7017, "qhull option warning: can not follow '1', '2', or '3' with a digit.  'Q%c%c' skipped\n", *(s-1), *s);
    1222           0 :             lastwarning= s-2;
    1223           0 :             s++;
    1224             :           }
    1225           0 :           break;
    1226           0 :         case '4':
    1227           0 :           qh_option(qh, "Q4-avoid-old-into-new", NULL, NULL);
    1228           0 :           qh->AVOIDold= True;
    1229           0 :           break;
    1230           0 :         case '5':
    1231           0 :           qh_option(qh, "Q5-no-check-outer", NULL, NULL);
    1232           0 :           qh->SKIPcheckmax= True;
    1233           0 :           break;
    1234           0 :         case '6':
    1235           0 :           qh_option(qh, "Q6-no-concave-merge", NULL, NULL);
    1236           0 :           qh->SKIPconvex= True;
    1237           0 :           break;
    1238           0 :         case '7':
    1239           0 :           qh_option(qh, "Q7-no-breadth-first", NULL, NULL);
    1240           0 :           qh->VIRTUALmemory= True;
    1241           0 :           break;
    1242           0 :         case '8':
    1243           0 :           qh_option(qh, "Q8-no-near-inside", NULL, NULL);
    1244           0 :           qh->NOnearinside= True;
    1245           0 :           break;
    1246           0 :         case '9':
    1247           0 :           qh_option(qh, "Q9-pick-furthest", NULL, NULL);
    1248           0 :           qh->PICKfurthest= True;
    1249           0 :           break;
    1250           0 :         case 'G':
    1251           0 :           i= qh_strtol(s, &t);
    1252           0 :           if (qh->GOODpoint) {
    1253           0 :             qh_fprintf(qh, qh->ferr, 7018, "qhull option warning: good point already defined for option 'QGn'.  Ignored\n");
    1254           0 :             lastwarning= s-2;
    1255           0 :           }else if (s == t) {
    1256           0 :             qh_fprintf(qh, qh->ferr, 7019, "qhull option warning: missing good point id for option 'QGn'.  Ignored\n");
    1257           0 :             lastwarning= s-2;
    1258           0 :           }else if (i < 0 || *s == '-') {
    1259           0 :             qh->GOODpoint= i-1;
    1260           0 :             qh_option(qh, "QGood-if-dont-see-point", &i, NULL);
    1261             :           }else {
    1262           0 :             qh->GOODpoint= i+1;
    1263           0 :             qh_option(qh, "QGood-if-see-point", &i, NULL);
    1264             :           }
    1265           0 :           s= t;
    1266           0 :           break;
    1267           0 :         case 'J':
    1268           0 :           if (!isdigit(*s) && *s != '-')
    1269           0 :             qh->JOGGLEmax= 0.0;
    1270             :           else {
    1271           0 :             qh->JOGGLEmax= (realT) qh_strtod(s, &s);
    1272           0 :             qh_option(qh, "QJoggle", NULL, &qh->JOGGLEmax);
    1273             :           }
    1274           0 :           break;
    1275           0 :         case 'R':
    1276           0 :           if (!isdigit(*s) && *s != '-') {
    1277           0 :             qh_fprintf(qh, qh->ferr, 7020, "qhull option warning: missing random seed for option 'QRn'\n");
    1278           0 :             lastwarning= s-2;
    1279             :           }else {
    1280           0 :             qh->ROTATErandom= i= qh_strtol(s, &s);
    1281           0 :             if (i > 0)
    1282           0 :               qh_option(qh, "QRotate-id", &i, NULL );
    1283           0 :             else if (i < -1)
    1284           0 :               qh_option(qh, "QRandom-seed", &i, NULL );
    1285             :           }
    1286           0 :           break;
    1287           0 :         case 'V':
    1288           0 :           i= qh_strtol(s, &t);
    1289           0 :           if (qh->GOODvertex) {
    1290           0 :             qh_fprintf(qh, qh->ferr, 7021, "qhull option warning: good vertex already defined for option 'QVn'.  Ignored\n");
    1291           0 :             lastwarning= s-2;
    1292           0 :           }else if (s == t) {
    1293           0 :             qh_fprintf(qh, qh->ferr, 7022, "qhull option warning: no good point id given for option 'QVn'.  Ignored\n");
    1294           0 :             lastwarning= s-2;
    1295           0 :           }else if (i < 0) {
    1296           0 :             qh->GOODvertex= i - 1;
    1297           0 :             qh_option(qh, "QV-good-facets-not-point", &i, NULL);
    1298             :           }else {
    1299           0 :             qh_option(qh, "QV-good-facets-point", &i, NULL);
    1300           0 :             qh->GOODvertex= i + 1;
    1301             :           }
    1302           0 :           s= t;
    1303           0 :           break;
    1304           0 :         case 'w':
    1305           0 :           qh_option(qh, "Qwarn-allow", NULL, NULL);
    1306           0 :           qh->ALLOWwarning= True;
    1307           0 :           break;
    1308           0 :         default:
    1309           0 :           s--;
    1310           0 :           qh_fprintf(qh, qh->ferr, 7023, "qhull option warning: unknown 'Q' qhull option 'Q%c', skip to next space\n", (int)s[0]);
    1311           0 :           lastwarning= s-1;
    1312           0 :           while (*++s && !isspace(*s));
    1313           0 :           break;
    1314             :         }
    1315             :       }
    1316          20 :       break;
    1317           0 :     case 'T':
    1318           0 :       while (*s && !isspace(*s)) {
    1319           0 :         if (isdigit(*s) || *s == '-')
    1320           0 :           qh->IStracing= qh_strtol(s, &s);
    1321           0 :         else switch (*s++) {
    1322           0 :         case 'a':
    1323           0 :           qh_option(qh, "Tannotate-output", NULL, NULL);
    1324           0 :           qh->ANNOTATEoutput= True;
    1325           0 :           break;
    1326           0 :         case 'c':
    1327           0 :           qh_option(qh, "Tcheck-frequently", NULL, NULL);
    1328           0 :           qh->CHECKfrequently= True;
    1329           0 :           break;
    1330           0 :         case 'f':
    1331           0 :           qh_option(qh, "Tflush", NULL, NULL);
    1332           0 :           qh->FLUSHprint= True;
    1333           0 :           break;
    1334           0 :         case 's':
    1335           0 :           qh_option(qh, "Tstatistics", NULL, NULL);
    1336           0 :           qh->PRINTstatistics= True;
    1337           0 :           break;
    1338           0 :         case 'v':
    1339           0 :           qh_option(qh, "Tverify", NULL, NULL);
    1340           0 :           qh->VERIFYoutput= True;
    1341           0 :           break;
    1342           0 :         case 'z':
    1343           0 :           if (qh->ferr == qh_FILEstderr) {
    1344             :             /* The C++ interface captures the output in qh_fprint_qhull() */
    1345           0 :             qh_option(qh, "Tz-stdout", NULL, NULL);
    1346           0 :             qh->USEstdout= True;
    1347           0 :           }else if (!qh->fout) {
    1348           0 :             qh_fprintf(qh, qh->ferr, 7024, "qhull option warning: output file undefined(stdout).  Option 'Tz' ignored.\n");
    1349           0 :             lastwarning= s-2;
    1350             :           }else {
    1351           0 :             qh_option(qh, "Tz-stdout", NULL, NULL);
    1352           0 :             qh->USEstdout= True;
    1353           0 :             qh->ferr= qh->fout;
    1354           0 :             qh->qhmem.ferr= qh->fout;
    1355             :           }
    1356           0 :           break;
    1357           0 :         case 'C':
    1358           0 :           if (!isdigit(*s)) {
    1359           0 :             qh_fprintf(qh, qh->ferr, 7025, "qhull option warning: missing point id for cone for trace option 'TCn'\n");
    1360           0 :             lastwarning= s-2;
    1361             :           }else {
    1362           0 :             i= qh_strtol(s, &s);
    1363           0 :             qh_option(qh, "TCone-stop", &i, NULL);
    1364           0 :             qh->STOPcone= i + 1;
    1365             :           }
    1366           0 :           break;
    1367           0 :         case 'F':
    1368           0 :           if (!isdigit(*s)) {
    1369           0 :             qh_fprintf(qh, qh->ferr, 7026, "qhull option warning: missing frequency count for trace option 'TFn'\n");
    1370           0 :             lastwarning= s-2;
    1371             :           }else {
    1372           0 :             qh->REPORTfreq= qh_strtol(s, &s);
    1373           0 :             qh_option(qh, "TFacet-log", &qh->REPORTfreq, NULL);
    1374           0 :             qh->REPORTfreq2= qh->REPORTfreq/2;  /* for tracemerging() */
    1375             :           }
    1376           0 :           break;
    1377           0 :         case 'I':
    1378           0 :           while (isspace(*s))
    1379           0 :             s++;
    1380           0 :           t= qh_skipfilename(qh, s);
    1381             :           {
    1382             :             char filename[qh_FILENAMElen];
    1383             : 
    1384           0 :             qh_copyfilename(qh, filename, (int)sizeof(filename), s, (int)(t-s));   /* WARN64 */
    1385           0 :             s= t;
    1386           0 :             if (!freopen(filename, "r", stdin)) {
    1387           0 :               qh_fprintf(qh, qh->ferr, 6041, "qhull option error: cannot open 'TI' file \"%s\"\n", filename);
    1388           0 :               qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1389             :             }else {
    1390           0 :               qh_option(qh, "TInput-file", NULL, NULL);
    1391           0 :               qh_option(qh, filename, NULL, NULL);
    1392             :             }
    1393             :           }
    1394           0 :           break;
    1395           0 :         case 'O':
    1396           0 :           while (isspace(*s))
    1397           0 :             s++;
    1398           0 :           t= qh_skipfilename(qh, s);
    1399             :           {
    1400             :             char filename[qh_FILENAMElen];
    1401             : 
    1402           0 :             qh_copyfilename(qh, filename, (int)sizeof(filename), s, (int)(t-s));  /* WARN64 */
    1403           0 :             if (!qh->fout) {
    1404           0 :               qh_fprintf(qh, qh->ferr, 7092, "qhull option warning: qh.fout was not set by caller of qh_initflags.  Cannot use option 'TO' to redirect output.  Ignoring option 'TO'\n");
    1405           0 :               lastwarning= s-2;
    1406           0 :             }else if (!freopen(filename, "w", qh->fout)) {
    1407           0 :               qh_fprintf(qh, qh->ferr, 6044, "qhull option error: cannot open file \"%s\" for writing as option 'TO'.  It is already in use or read-only\n", filename);
    1408           0 :               qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1409             :             }else {
    1410           0 :               qh_option(qh, "TOutput-file", NULL, NULL);
    1411           0 :               qh_option(qh, filename, NULL, NULL);
    1412             :             }
    1413           0 :             s= t;
    1414             :           }
    1415           0 :           break;
    1416           0 :         case 'A':
    1417           0 :           if (!isdigit(*s)) {
    1418           0 :             qh_fprintf(qh, qh->ferr, 7093, "qhull option warning: missing count of added points for trace option 'TAn'\n");
    1419           0 :             lastwarning= s-2;
    1420             :           }else {
    1421           0 :             i= qh_strtol(s, &t);
    1422           0 :             qh->STOPadd= i + 1;
    1423           0 :             qh_option(qh, "TA-stop-add", &i, NULL);
    1424             :           }
    1425           0 :           s= t;
    1426           0 :           break;
    1427           0 :         case 'P':
    1428           0 :           if (*s == '-') {
    1429           0 :             if (s[1] == '1' && !isdigit(s[2])) {
    1430           0 :               s += 2;
    1431           0 :               qh->TRACEpoint= qh_IDunknown; /* qh_buildhull done */
    1432           0 :               qh_option(qh, "Trace-point", &qh->TRACEpoint, NULL);
    1433             :             }else {
    1434           0 :               qh_fprintf(qh, qh->ferr, 7100, "qhull option warning: negative point id for trace option 'TPn'.  Expecting 'TP-1' for tracing after qh_buildhull and qh_postmerge\n");
    1435           0 :               lastwarning= s-2;
    1436           0 :               while (isdigit(*(++s)))
    1437             :                 ; /* skip digits */
    1438             :             }
    1439           0 :           }else if (!isdigit(*s)) {
    1440           0 :             qh_fprintf(qh, qh->ferr, 7029, "qhull option warning: missing point id or -1 for trace option 'TPn'\n");
    1441           0 :             lastwarning= s-2;
    1442             :           }else {
    1443           0 :             qh->TRACEpoint= qh_strtol(s, &s);
    1444           0 :             qh_option(qh, "Trace-point", &qh->TRACEpoint, NULL);
    1445             :           }
    1446           0 :           break;
    1447           0 :         case 'M':
    1448           0 :           if (!isdigit(*s)) {
    1449           0 :             qh_fprintf(qh, qh->ferr, 7030, "qhull option warning: missing merge id for trace option 'TMn'\n");
    1450           0 :             lastwarning= s-2;
    1451             :           }else {
    1452           0 :             qh->TRACEmerge= qh_strtol(s, &s);
    1453           0 :             qh_option(qh, "Trace-merge", &qh->TRACEmerge, NULL);
    1454             :           }
    1455           0 :           break;
    1456           0 :         case 'R':
    1457           0 :           if (!isdigit(*s)) {
    1458           0 :             qh_fprintf(qh, qh->ferr, 7031, "qhull option warning: missing rerun count for trace option 'TRn'\n");
    1459           0 :             lastwarning= s-2;
    1460             :           }else {
    1461           0 :             qh->RERUN= qh_strtol(s, &s);
    1462           0 :             qh_option(qh, "TRerun", &qh->RERUN, NULL);
    1463             :           }
    1464           0 :           break;
    1465           0 :         case 'V':
    1466           0 :           i= qh_strtol(s, &t);
    1467           0 :           if (s == t) {
    1468           0 :             qh_fprintf(qh, qh->ferr, 7032, "qhull option warning: missing furthest point id for trace option 'TVn'\n");
    1469           0 :             lastwarning= s-2;
    1470           0 :           }else if (i < 0) {
    1471           0 :             qh->STOPpoint= i - 1;
    1472           0 :             qh_option(qh, "TV-stop-before-point", &i, NULL);
    1473             :           }else {
    1474           0 :             qh->STOPpoint= i + 1;
    1475           0 :             qh_option(qh, "TV-stop-after-point", &i, NULL);
    1476             :           }
    1477           0 :           s= t;
    1478           0 :           break;
    1479           0 :         case 'W':
    1480           0 :           if (!isdigit(*s)) {
    1481           0 :             qh_fprintf(qh, qh->ferr, 7033, "qhull option warning: missing max width for trace option 'TWn'\n");
    1482           0 :             lastwarning= s-2;
    1483             :           }else {
    1484           0 :             qh->TRACEdist= (realT) qh_strtod(s, &s);
    1485           0 :             qh_option(qh, "TWide-trace", NULL, &qh->TRACEdist);
    1486             :           }
    1487           0 :           break;
    1488           0 :         default:
    1489           0 :           s--;
    1490           0 :           qh_fprintf(qh, qh->ferr, 7034, "qhull option warning: unknown 'T' trace option 'T%c', skip to next space\n", (int)s[0]);
    1491           0 :           lastwarning= s-2;
    1492           0 :           while (*++s && !isspace(*s));
    1493           0 :           break;
    1494             :         }
    1495             :       }
    1496           0 :       break;
    1497           0 :     default:
    1498           0 :       qh_fprintf(qh, qh->ferr, 7094, "qhull option warning: unknown option '%c'(%x)\n",
    1499           0 :         (int)s[-1], (int)s[-1]);
    1500           0 :       lastwarning= s-2;
    1501           0 :       break;
    1502             :     }
    1503          25 :     if (s-1 == prev_s && *s && !isspace(*s)) {
    1504           0 :       qh_fprintf(qh, qh->ferr, 7036, "qhull option warning: missing space after option '%c'(%x), reserved for sub-options, ignoring '%c' options to next space\n",
    1505           0 :                (int)*prev_s, (int)*prev_s, (int)*prev_s);
    1506           0 :       lastwarning= s-1;
    1507           0 :       while (*s && !isspace(*s))
    1508           0 :         s++;
    1509             :     }
    1510             :   }
    1511           5 :   if (qh->STOPcone && qh->JOGGLEmax < REALmax/2) {
    1512           0 :     qh_fprintf(qh, qh->ferr, 7078, "qhull option warning: 'TCn' (stopCone) ignored when used with 'QJn' (joggle)\n");
    1513           0 :     lastwarning= command;
    1514             :   }
    1515           5 :   if (isgeom && !qh->FORCEoutput && qh->PRINTout[1]) {
    1516           0 :     qh_fprintf(qh, qh->ferr, 7037, "qhull option warning: additional output formats ('Fc',etc.) are not compatible with Geomview ('G').  Use option 'Po' to override\n");
    1517           0 :     lastwarning= command;
    1518             :   }
    1519           5 :   if (lastwarning && !qh->ALLOWwarning) {
    1520           0 :     qh_fprintf(qh, qh->ferr, 6035, "qhull option error: see previous warnings, use 'Qw' to override: '%s' (last offset %d)\n",
    1521           0 :           command, (int)(lastwarning-command));
    1522           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1523             :   }
    1524           5 :   trace4((qh, qh->ferr, 4093, "qh_initflags: option flags initialized\n"));
    1525             :   /* set derived values in qh_initqhull_globals */
    1526           5 : } /* initflags */
    1527             : 
    1528             : 
    1529             : /*-<a                             href="qh-globa_r.htm#TOC"
    1530             :   >-------------------------------</a><a name="initqhull_buffers">-</a>
    1531             : 
    1532             :   qh_initqhull_buffers(qh)
    1533             :     initialize global memory buffers
    1534             : 
    1535             :   notes:
    1536             :     must match qh_freebuffers()
    1537             : */
    1538           4 : void qh_initqhull_buffers(qhT *qh) {
    1539             :   int k;
    1540             : 
    1541           4 :   qh->TEMPsize= (qh->qhmem.LASTsize - (int)sizeof(setT))/SETelemsize;
    1542           4 :   if (qh->TEMPsize <= 0 || qh->TEMPsize > qh->qhmem.LASTsize)
    1543           0 :     qh->TEMPsize= 8;  /* e.g., if qh_NOmem */
    1544           4 :   qh->other_points= qh_setnew(qh, qh->TEMPsize);
    1545           4 :   qh->del_vertices= qh_setnew(qh, qh->TEMPsize);
    1546           4 :   qh->coplanarfacetset= qh_setnew(qh, qh->TEMPsize);
    1547           4 :   qh->NEARzero= (realT *)qh_memalloc(qh, qh->hull_dim * (int)sizeof(realT));
    1548           4 :   qh->lower_threshold= (realT *)qh_memalloc(qh, (qh->input_dim+1) * (int)sizeof(realT));
    1549           4 :   qh->upper_threshold= (realT *)qh_memalloc(qh, (qh->input_dim+1) * (int)sizeof(realT));
    1550           4 :   qh->lower_bound= (realT *)qh_memalloc(qh, (qh->input_dim+1) * (int)sizeof(realT));
    1551           4 :   qh->upper_bound= (realT *)qh_memalloc(qh, (qh->input_dim+1) * (int)sizeof(realT));
    1552          16 :   for (k=qh->input_dim+1; k--; ) {  /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
    1553          12 :     qh->lower_threshold[k]= -REALmax;
    1554          12 :     qh->upper_threshold[k]= REALmax;
    1555          12 :     qh->lower_bound[k]= -REALmax;
    1556          12 :     qh->upper_bound[k]= REALmax;
    1557             :   }
    1558           4 :   qh->gm_matrix= (coordT *)qh_memalloc(qh, (qh->hull_dim+1) * qh->hull_dim * (int)sizeof(coordT));
    1559           4 :   qh->gm_row= (coordT **)qh_memalloc(qh, (qh->hull_dim+1) * (int)sizeof(coordT *));
    1560           4 : } /* initqhull_buffers */
    1561             : 
    1562             : /*-<a                             href="qh-globa_r.htm#TOC"
    1563             :   >-------------------------------</a><a name="initqhull_globals">-</a>
    1564             : 
    1565             :   qh_initqhull_globals(qh, points, numpoints, dim, ismalloc )
    1566             :     initialize globals
    1567             :     if ismalloc
    1568             :       points were malloc'd and qhull should free at end
    1569             : 
    1570             :   returns:
    1571             :     sets qh.first_point, num_points, input_dim, hull_dim and others
    1572             :     seeds random number generator (seed=1 if tracing)
    1573             :     modifies qh.hull_dim if ((qh.DELAUNAY and qh.PROJECTdelaunay) or qh.PROJECTinput)
    1574             :     adjust user flags as needed
    1575             :     also checks DIM3 dependencies and constants
    1576             : 
    1577             :   notes:
    1578             :     do not use qh_point() since an input transformation may move them elsewhere
    1579             :     qh_initqhull_start() sets default values for non-zero globals
    1580             :     consider duplicate error checks in qh_readpoints.  It is called before qh_initqhull_globals
    1581             : 
    1582             :   design:
    1583             :     initialize points array from input arguments
    1584             :     test for qh.ZEROcentrum
    1585             :       (i.e., use opposite vertex instead of cetrum for convexity testing)
    1586             :     initialize qh.CENTERtype, qh.normal_size,
    1587             :       qh.center_size, qh.TRACEpoint/level,
    1588             :     initialize and test random numbers
    1589             :     qh_initqhull_outputflags() -- adjust and test output flags
    1590             : */
    1591           5 : void qh_initqhull_globals(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc) {
    1592           5 :   int seed, pointsneeded, extra= 0, i, randi, k;
    1593             :   realT randr;
    1594             :   realT factorial;
    1595             : 
    1596             :   time_t timedata;
    1597             : 
    1598           5 :   trace0((qh, qh->ferr, 13, "qh_initqhull_globals: for %s | %s\n", qh->rbox_command,
    1599             :       qh->qhull_command));
    1600           5 :   if (numpoints < 1 || numpoints > qh_POINTSmax) {
    1601           0 :     qh_fprintf(qh, qh->ferr, 6412, "qhull input error (qh_initqhull_globals): expecting between 1 and %d points.  Got %d %d-d points\n",
    1602             :       qh_POINTSmax, numpoints, dim);
    1603           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1604             :     /* same error message in qh_readpoints */
    1605             :   }
    1606           5 :   qh->POINTSmalloc= ismalloc;
    1607           5 :   qh->first_point= points;
    1608           5 :   qh->num_points= numpoints;
    1609           5 :   qh->hull_dim= qh->input_dim= dim;
    1610           5 :   if (!qh->NOpremerge && !qh->MERGEexact && !qh->PREmerge && qh->JOGGLEmax > REALmax/2) {
    1611           5 :     qh->MERGING= True;
    1612           5 :     if (qh->hull_dim <= 4) {
    1613           5 :       qh->PREmerge= True;
    1614           5 :       qh_option(qh, "_pre-merge", NULL, NULL);
    1615             :     }else {
    1616           0 :       qh->MERGEexact= True;
    1617           0 :       qh_option(qh, "Qxact-merge", NULL, NULL);
    1618             :     }
    1619           0 :   }else if (qh->MERGEexact)
    1620           0 :     qh->MERGING= True;
    1621           5 :   if (qh->NOpremerge && (qh->MERGEexact || qh->PREmerge))
    1622           0 :     qh_fprintf(qh, qh->ferr, 7095, "qhull option warning: 'Q0-no-premerge' ignored due to exact merge ('Qx') or pre-merge ('C-n' or 'A-n')\n");
    1623           5 :   if (!qh->NOpremerge && qh->JOGGLEmax > REALmax/2) {
    1624             : #ifdef qh_NOmerge
    1625             :     qh->JOGGLEmax= 0.0;
    1626             : #endif
    1627             :   }
    1628           5 :   if (qh->TRIangulate && qh->JOGGLEmax < REALmax/2 && !qh->PREmerge && !qh->POSTmerge && qh->PRINTprecision)
    1629           0 :     qh_fprintf(qh, qh->ferr, 7038, "qhull option warning: joggle ('QJ') produces simplicial output (i.e., triangles in 2-D).  Unless merging is requested, option 'Qt' has no effect\n");
    1630           5 :   if (qh->JOGGLEmax < REALmax/2 && qh->DELAUNAY && !qh->SCALEinput && !qh->SCALElast) {
    1631           0 :     qh->SCALElast= True;
    1632           0 :     qh_option(qh, "Qbbound-last-qj", NULL, NULL);
    1633             :   }
    1634           5 :   if (qh->MERGING && !qh->POSTmerge && qh->premerge_cos > REALmax/2
    1635           5 :   && qh->premerge_centrum == 0.0) {
    1636           5 :     qh->ZEROcentrum= True;
    1637           5 :     qh->ZEROall_ok= True;
    1638           5 :     qh_option(qh, "_zero-centrum", NULL, NULL);
    1639             :   }
    1640             :   if (qh->JOGGLEmax < REALmax/2 && REALepsilon > 2e-8 && qh->PRINTprecision)
    1641             :     qh_fprintf(qh, qh->ferr, 7039, "qhull warning: real epsilon, %2.2g, is probably too large for joggle('QJn')\nRecompile with double precision reals(see user_r.h).\n",
    1642             :           REALepsilon);
    1643             : #ifdef qh_NOmerge
    1644             :   if (qh->MERGING) {
    1645             :     qh_fprintf(qh, qh->ferr, 6045, "qhull option error: merging not installed (qh_NOmerge) for 'Qx', 'Cn' or 'An')\n");
    1646             :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1647             :   }
    1648             : #endif
    1649           5 :   if (qh->DELAUNAY && qh->KEEPcoplanar && !qh->KEEPinside) {
    1650           5 :     qh->KEEPinside= True;
    1651           5 :     qh_option(qh, "Qinterior-keep", NULL, NULL);
    1652             :   }
    1653           5 :   if (qh->VORONOI && !qh->DELAUNAY) {
    1654           0 :     qh_fprintf(qh, qh->ferr, 6038, "qhull internal error (qh_initqhull_globals): if qh.VORONOI is set, qh.DELAUNAY must be set.  Qhull constructs the Delaunay triangulation in order to compute the Voronoi diagram\n");
    1655           0 :     qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    1656             :   }
    1657           5 :   if (qh->DELAUNAY && qh->HALFspace) {
    1658           0 :     qh_fprintf(qh, qh->ferr, 6046, "qhull option error: can not use Delaunay('d') or Voronoi('v') with halfspace intersection('H')\n");
    1659           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1660             :     /* same error message in qh_readpoints */
    1661             :   }
    1662           5 :   if (!qh->DELAUNAY && (qh->UPPERdelaunay || qh->ATinfinity)) {
    1663           0 :     qh_fprintf(qh, qh->ferr, 6047, "qhull option error: use upper-Delaunay('Qu') or infinity-point('Qz') with Delaunay('d') or Voronoi('v')\n");
    1664           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1665             :   }
    1666           5 :   if (qh->UPPERdelaunay && qh->ATinfinity) {
    1667           0 :     qh_fprintf(qh, qh->ferr, 6048, "qhull option error: can not use infinity-point('Qz') with upper-Delaunay('Qu')\n");
    1668           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1669             :   }
    1670           5 :   if (qh->MERGEpinched && qh->ONLYgood) {
    1671           0 :     qh_fprintf(qh, qh->ferr, 6362, "qhull option error: can not use merge-pinched-vertices ('Q14') with good-facets-only ('Qg')\n");
    1672           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1673             :   }
    1674           5 :   if (qh->MERGEpinched && qh->hull_dim == 2) {
    1675           0 :     trace2((qh, qh->ferr, 2108, "qh_initqhull_globals: disable qh.MERGEpinched for 2-d.  It has no effect"))
    1676           0 :     qh->MERGEpinched= False;
    1677             :   }
    1678           5 :   if (qh->SCALElast && !qh->DELAUNAY && qh->PRINTprecision)
    1679           0 :     qh_fprintf(qh, qh->ferr, 7040, "qhull option warning: option 'Qbb' (scale-last-coordinate) is normally used with 'd' or 'v'\n");
    1680           5 :   qh->DOcheckmax= (!qh->SKIPcheckmax && (qh->MERGING || qh->APPROXhull));
    1681           5 :   qh->KEEPnearinside= (qh->DOcheckmax && !(qh->KEEPinside && qh->KEEPcoplanar)
    1682          10 :                           && !qh->NOnearinside);
    1683           5 :   if (qh->MERGING)
    1684           5 :     qh->CENTERtype= qh_AScentrum;
    1685           0 :   else if (qh->VORONOI)
    1686           0 :     qh->CENTERtype= qh_ASvoronoi;
    1687           5 :   if (qh->TESTvneighbors && !qh->MERGING) {
    1688           0 :     qh_fprintf(qh, qh->ferr, 6049, "qhull option error: test vertex neighbors('Qv') needs a merge option\n");
    1689           0 :     qh_errexit(qh, qh_ERRinput, NULL ,NULL);
    1690             :   }
    1691           5 :   if (qh->PROJECTinput || (qh->DELAUNAY && qh->PROJECTdelaunay)) {
    1692           5 :     qh->hull_dim -= qh->PROJECTinput;
    1693           5 :     if (qh->DELAUNAY) {
    1694           5 :       qh->hull_dim++;
    1695           5 :       if (qh->ATinfinity)
    1696           5 :         extra= 1;
    1697             :     }
    1698             :   }
    1699           5 :   if (qh->hull_dim <= 1) {
    1700           0 :     qh_fprintf(qh, qh->ferr, 6050, "qhull error: dimension %d must be > 1\n", qh->hull_dim);
    1701           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1702             :   }
    1703          10 :   for (k=2, factorial=1.0; k < qh->hull_dim; k++)
    1704           5 :     factorial *= k;
    1705           5 :   qh->AREAfactor= 1.0 / factorial;
    1706           5 :   trace2((qh, qh->ferr, 2005, "qh_initqhull_globals: initialize globals.  input_dim %d, numpoints %d, malloc? %d, projected %d to hull_dim %d\n",
    1707             :         qh->input_dim, numpoints, ismalloc, qh->PROJECTinput, qh->hull_dim));
    1708           5 :   qh->normal_size= qh->hull_dim * (int)sizeof(coordT);
    1709           5 :   qh->center_size= qh->normal_size - (int)sizeof(coordT);
    1710           5 :   pointsneeded= qh->hull_dim+1;
    1711           5 :   if (qh->hull_dim > qh_DIMmergeVertex) {
    1712           0 :     qh->MERGEvertices= False;
    1713           0 :     qh_option(qh, "Q3-no-merge-vertices-dim-high", NULL, NULL);
    1714             :   }
    1715           5 :   if (qh->GOODpoint)
    1716           0 :     pointsneeded++;
    1717             : #ifdef qh_NOtrace
    1718             :   if (qh->IStracing || qh->TRACEmerge || qh->TRACEpoint != qh_IDnone || qh->TRACEdist < REALmax/2) {
    1719             :       qh_fprintf(qh, qh->ferr, 6051, "qhull option error: tracing is not installed (qh_NOtrace in user_r.h).  Trace options 'Tn', 'TMn', 'TPn' and 'TWn' mostly removed.  Continue with 'Qw' (allow warning)\n");
    1720             :       if (!qh->ALLOWwarning)
    1721             :         qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1722             :   }
    1723             : #endif
    1724           5 :   if (qh->RERUN > 1) {
    1725           0 :     qh->TRACElastrun= qh->IStracing; /* qh_build_withrestart duplicates next conditional */
    1726           0 :     if (qh->IStracing && qh->IStracing != -1) {
    1727           0 :       qh_fprintf(qh, qh->ferr, 8162, "qh_initqhull_globals: trace last of TR%d runs at level %d\n", qh->RERUN, qh->IStracing);
    1728           0 :       qh->IStracing= 0;
    1729             :     }
    1730           5 :   }else if (qh->TRACEpoint != qh_IDnone || qh->TRACEdist < REALmax/2 || qh->TRACEmerge) {
    1731           0 :     qh->TRACElevel= (qh->IStracing ? qh->IStracing : 3);
    1732           0 :     qh->IStracing= 0;
    1733             :   }
    1734           5 :   if (qh->ROTATErandom == 0 || qh->ROTATErandom == -1) {
    1735             :     /* coverity[store_truncates_time_t] */
    1736           0 :     seed= (int)time(&timedata);
    1737           0 :     if (qh->ROTATErandom  == -1) {
    1738           0 :       seed= -seed;
    1739           0 :       qh_option(qh, "QRandom-seed", &seed, NULL );
    1740             :     }else
    1741           0 :       qh_option(qh, "QRotate-random", &seed, NULL);
    1742           0 :     qh->ROTATErandom= seed;
    1743             :   }
    1744           5 :   seed= qh->ROTATErandom;
    1745           5 :   if (seed == INT_MIN)    /* default value */
    1746           5 :     seed= 1;
    1747           0 :   else if (seed < 0)
    1748           0 :     seed= -seed;
    1749           5 :   qh_RANDOMseed_(qh, seed);
    1750           5 :   randr= 0.0;
    1751        5005 :   for (i=1000; i--; ) {
    1752        5000 :     randi= qh_RANDOMint;
    1753        5000 :     randr += randi;
    1754        5000 :     if (randi > qh_RANDOMmax) {
    1755           0 :       qh_fprintf(qh, qh->ferr, 8036, "\
    1756             : qhull configuration error (qh_RANDOMmax in user_r.h): random integer %d > qh_RANDOMmax (%.8g)\n",
    1757             :                randi, qh_RANDOMmax);
    1758           0 :       qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1759             :     }
    1760             :   }
    1761           5 :   qh_RANDOMseed_(qh, seed);
    1762           5 :   randr= randr/1000;
    1763           5 :   if (randr < qh_RANDOMmax * 0.1
    1764           5 :   || randr > qh_RANDOMmax * 0.9)
    1765           0 :     qh_fprintf(qh, qh->ferr, 8037, "\
    1766             : qhull configuration warning (qh_RANDOMmax in user_r.h): average of 1000 random integers (%.2g) is much different than expected (%.2g).  Is qh_RANDOMmax (%.2g) wrong?\n",
    1767             :              randr, qh_RANDOMmax * 0.5, qh_RANDOMmax);
    1768           5 :   qh->RANDOMa= 2.0 * qh->RANDOMfactor/qh_RANDOMmax;
    1769           5 :   qh->RANDOMb= 1.0 - qh->RANDOMfactor;
    1770             :   if (qh_HASHfactor < 1.1) {
    1771             :     qh_fprintf(qh, qh->ferr, 6052, "qhull internal error (qh_initqhull_globals): qh_HASHfactor %d must be at least 1.1.  Qhull uses linear hash probing\n",
    1772             :       qh_HASHfactor);
    1773             :     qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    1774             :   }
    1775           5 :   if (numpoints+extra < pointsneeded) {
    1776           1 :     qh_fprintf(qh, qh->ferr, 6214, "qhull input error: not enough points(%d) to construct initial simplex (need %d)\n",
    1777             :             numpoints, pointsneeded);
    1778           1 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1779             :   }
    1780           4 :   qh_initqhull_outputflags(qh);
    1781           4 : } /* initqhull_globals */
    1782             : 
    1783             : /*-<a                             href="qh-globa_r.htm#TOC"
    1784             :   >-------------------------------</a><a name="initqhull_mem">-</a>
    1785             : 
    1786             :   qh_initqhull_mem(qh )
    1787             :     initialize mem_r.c for qhull
    1788             :     qh.hull_dim and qh.normal_size determine some of the allocation sizes
    1789             :     if qh.MERGING,
    1790             :       includes ridgeT
    1791             :     calls qh_user_memsizes (user_r.c) to add up to 10 additional sizes for quick allocation
    1792             :       (see numsizes below)
    1793             : 
    1794             :   returns:
    1795             :     mem_r.c already for qh_memalloc/qh_memfree (errors if called beforehand)
    1796             : 
    1797             :   notes:
    1798             :     qh_produceoutput() prints memsizes
    1799             : 
    1800             : */
    1801           4 : void qh_initqhull_mem(qhT *qh) {
    1802             :   int numsizes;
    1803             :   int i;
    1804             : 
    1805           4 :   numsizes= 8+10;
    1806           4 :   qh_meminitbuffers(qh, qh->IStracing, qh_MEMalign, numsizes,
    1807             :                      qh_MEMbufsize, qh_MEMinitbuf);
    1808           4 :   qh_memsize(qh, (int)sizeof(vertexT));
    1809           4 :   if (qh->MERGING) {
    1810           4 :     qh_memsize(qh, (int)sizeof(ridgeT));
    1811           4 :     qh_memsize(qh, (int)sizeof(mergeT));
    1812             :   }
    1813           4 :   qh_memsize(qh, (int)sizeof(facetT));
    1814           4 :   i= (int)sizeof(setT) + (qh->hull_dim - 1) * SETelemsize;  /* ridge.vertices */
    1815           4 :   qh_memsize(qh, i);
    1816           4 :   qh_memsize(qh, qh->normal_size);        /* normal */
    1817           4 :   i += SETelemsize;                 /* facet.vertices, .ridges, .neighbors */
    1818           4 :   qh_memsize(qh, i);
    1819           4 :   qh_user_memsizes(qh);
    1820           4 :   qh_memsetup(qh);
    1821           4 : } /* initqhull_mem */
    1822             : 
    1823             : /*-<a                             href="qh-globa_r.htm#TOC"
    1824             :   >-------------------------------</a><a name="initqhull_outputflags">-</a>
    1825             : 
    1826             :   qh_initqhull_outputflags
    1827             :     initialize flags concerned with output
    1828             : 
    1829             :   returns:
    1830             :     adjust user flags as needed
    1831             : 
    1832             :   see:
    1833             :     qh_clear_outputflags() resets the flags
    1834             : 
    1835             :   design:
    1836             :     test for qh.PRINTgood (i.e., only print 'good' facets)
    1837             :     check for conflicting print output options
    1838             : */
    1839           4 : void qh_initqhull_outputflags(qhT *qh) {
    1840           4 :   boolT printgeom= False, printmath= False, printcoplanar= False;
    1841             :   int i;
    1842             : 
    1843           4 :   trace3((qh, qh->ferr, 3024, "qh_initqhull_outputflags: %s\n", qh->qhull_command));
    1844           4 :   if (!(qh->PRINTgood || qh->PRINTneighbors)) {
    1845           4 :     if (qh->DELAUNAY || qh->KEEParea || qh->KEEPminArea < REALmax/2 || qh->KEEPmerge
    1846           0 :         || (!qh->ONLYgood && (qh->GOODvertex || qh->GOODpoint))) {
    1847           4 :       qh->PRINTgood= True;
    1848           4 :       qh_option(qh, "Pgood", NULL, NULL);
    1849             :     }
    1850             :   }
    1851           4 :   if (qh->PRINTtransparent) {
    1852           0 :     if (qh->hull_dim != 4 || !qh->DELAUNAY || qh->VORONOI || qh->DROPdim >= 0) {
    1853           0 :       qh_fprintf(qh, qh->ferr, 6215, "qhull option error: transparent Delaunay('Gt') needs 3-d Delaunay('d') w/o 'GDn'\n");
    1854           0 :       qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1855             :     }
    1856           0 :     qh->DROPdim= 3;
    1857           0 :     qh->PRINTridges= True;
    1858             :   }
    1859         120 :   for (i=qh_PRINTEND; i--; ) {
    1860         116 :     if (qh->PRINTout[i] == qh_PRINTgeom)
    1861           0 :       printgeom= True;
    1862         116 :     else if (qh->PRINTout[i] == qh_PRINTmathematica || qh->PRINTout[i] == qh_PRINTmaple)
    1863           0 :       printmath= True;
    1864         116 :     else if (qh->PRINTout[i] == qh_PRINTcoplanars)
    1865           0 :       printcoplanar= True;
    1866         116 :     else if (qh->PRINTout[i] == qh_PRINTpointnearest)
    1867           0 :       printcoplanar= True;
    1868         116 :     else if (qh->PRINTout[i] == qh_PRINTpointintersect && !qh->HALFspace) {
    1869           0 :       qh_fprintf(qh, qh->ferr, 6053, "qhull option error: option 'Fp' is only used for \nhalfspace intersection('Hn,n,n').\n");
    1870           0 :       qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1871         116 :     }else if (qh->PRINTout[i] == qh_PRINTtriangles && (qh->HALFspace || qh->VORONOI)) {
    1872           0 :       qh_fprintf(qh, qh->ferr, 6054, "qhull option error: option 'Ft' is not available for Voronoi vertices ('v') or halfspace intersection ('H')\n");
    1873           0 :       qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1874         116 :     }else if (qh->PRINTout[i] == qh_PRINTcentrums && qh->VORONOI) {
    1875           0 :       qh_fprintf(qh, qh->ferr, 6055, "qhull option error: option 'FC' is not available for Voronoi vertices('v')\n");
    1876           0 :       qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1877         116 :     }else if (qh->PRINTout[i] == qh_PRINTvertices) {
    1878           0 :       if (qh->VORONOI)
    1879           0 :         qh_option(qh, "Fvoronoi", NULL, NULL);
    1880             :       else
    1881           0 :         qh_option(qh, "Fvertices", NULL, NULL);
    1882             :     }
    1883             :   }
    1884           4 :   if (printcoplanar && qh->DELAUNAY && qh->JOGGLEmax < REALmax/2) {
    1885           0 :     if (qh->PRINTprecision)
    1886           0 :       qh_fprintf(qh, qh->ferr, 7041, "qhull option warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n");
    1887             :   }
    1888           4 :   if (printmath && (qh->hull_dim > 3 || qh->VORONOI)) {
    1889           0 :     qh_fprintf(qh, qh->ferr, 6056, "qhull option error: Mathematica and Maple output is only available for 2-d and 3-d convex hulls and 2-d Delaunay triangulations\n");
    1890           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1891             :   }
    1892           4 :   if (printgeom) {
    1893           0 :     if (qh->hull_dim > 4) {
    1894           0 :       qh_fprintf(qh, qh->ferr, 6057, "qhull option error: Geomview output is only available for 2-d, 3-d and 4-d\n");
    1895           0 :       qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1896             :     }
    1897           0 :     if (qh->PRINTnoplanes && !(qh->PRINTcoplanar + qh->PRINTcentrums
    1898           0 :      + qh->PRINTdots + qh->PRINTspheres + qh->DOintersections + qh->PRINTridges)) {
    1899           0 :       qh_fprintf(qh, qh->ferr, 6058, "qhull option error: no output specified for Geomview\n");
    1900           0 :       qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1901             :     }
    1902           0 :     if (qh->VORONOI && (qh->hull_dim > 3 || qh->DROPdim >= 0)) {
    1903           0 :       qh_fprintf(qh, qh->ferr, 6059, "qhull option error: Geomview output for Voronoi diagrams only for 2-d\n");
    1904           0 :       qh_errexit(qh, qh_ERRinput, NULL, NULL);
    1905             :     }
    1906             :     /* can not warn about furthest-site Geomview output: no lower_threshold */
    1907           0 :     if (qh->hull_dim == 4 && qh->DROPdim == -1 &&
    1908           0 :         (qh->PRINTcoplanar || qh->PRINTspheres || qh->PRINTcentrums)) {
    1909           0 :       qh_fprintf(qh, qh->ferr, 7042, "qhull option warning: coplanars, vertices, and centrums output not available for 4-d output(ignored).  Could use 'GDn' instead.\n");
    1910           0 :       qh->PRINTcoplanar= qh->PRINTspheres= qh->PRINTcentrums= False;
    1911             :     }
    1912             :   }
    1913           4 :   if (!qh->KEEPcoplanar && !qh->KEEPinside && !qh->ONLYgood) {
    1914           0 :     if ((qh->PRINTcoplanar && qh->PRINTspheres) || printcoplanar) {
    1915           0 :       if (qh->QHULLfinished) {
    1916           0 :         qh_fprintf(qh, qh->ferr, 7072, "qhull output warning: ignoring coplanar points, option 'Qc' was not set for the first run of qhull.\n");
    1917             :       }else {
    1918           0 :         qh->KEEPcoplanar= True;
    1919           0 :         qh_option(qh, "Qcoplanar", NULL, NULL);
    1920             :       }
    1921             :     }
    1922             :   }
    1923           4 :   qh->PRINTdim= qh->hull_dim;
    1924           4 :   if (qh->DROPdim >=0) {    /* after Geomview checks */
    1925           0 :     if (qh->DROPdim < qh->hull_dim) {
    1926           0 :       qh->PRINTdim--;
    1927           0 :       if (!printgeom || qh->hull_dim < 3)
    1928           0 :         qh_fprintf(qh, qh->ferr, 7043, "qhull option warning: drop dimension 'GD%d' is only available for 3-d/4-d Geomview\n", qh->DROPdim);
    1929             :     }else
    1930           0 :       qh->DROPdim= -1;
    1931           4 :   }else if (qh->VORONOI) {
    1932           0 :     qh->DROPdim= qh->hull_dim-1;
    1933           0 :     qh->PRINTdim= qh->hull_dim-1;
    1934             :   }
    1935           4 : } /* qh_initqhull_outputflags */
    1936             : 
    1937             : /*-<a                             href="qh-globa_r.htm#TOC"
    1938             :   >-------------------------------</a><a name="initqhull_start">-</a>
    1939             : 
    1940             :   qh_initqhull_start(qh, infile, outfile, errfile )
    1941             :     allocate memory if needed and call qh_initqhull_start2()
    1942             : */
    1943           5 : void qh_initqhull_start(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile) {
    1944             : 
    1945           5 :   qh_initstatistics(qh);
    1946           5 :   qh_initqhull_start2(qh, infile, outfile, errfile);
    1947           5 : } /* initqhull_start */
    1948             : 
    1949             : /*-<a                             href="qh-globa_r.htm#TOC"
    1950             :   >-------------------------------</a><a name="initqhull_start2">-</a>
    1951             : 
    1952             :   qh_initqhull_start2(qh, infile, outfile, errfile )
    1953             :     start initialization of qhull
    1954             :     initialize statistics, stdio, default values for global variables
    1955             :     assumes qh is allocated
    1956             :   notes:
    1957             :     report errors elsewhere, error handling and g_qhull_output [Qhull.cpp, QhullQh()] not in initialized
    1958             :   see:
    1959             :     qh_maxmin() determines the precision constants
    1960             :     qh_freeqhull()
    1961             : */
    1962           5 : void qh_initqhull_start2(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile) {
    1963             :   time_t timedata;
    1964             :   int seed;
    1965             : 
    1966           5 :   qh_CPUclock; /* start the clock(for qh_clock).  One-shot. */
    1967             :   /* memset is the same in qh_freeqhull() and qh_initqhull_start2() */
    1968           5 :   memset((char *)qh, 0, sizeof(qhT)-sizeof(qhmemT)-sizeof(qhstatT));   /* every field is 0, FALSE, NULL */
    1969           5 :   qh->NOerrexit= True;
    1970           5 :   qh->DROPdim= -1;
    1971           5 :   qh->ferr= errfile;
    1972           5 :   qh->fin= infile;
    1973           5 :   qh->fout= outfile;
    1974           5 :   qh->furthest_id= qh_IDunknown;
    1975             : #ifndef qh_NOmerge
    1976           5 :   qh->JOGGLEmax= REALmax;
    1977             : #else
    1978             :   qh->JOGGLEmax= 0.0;  /* Joggle ('QJ') if qh_NOmerge */
    1979             : #endif
    1980           5 :   qh->KEEPminArea= REALmax;
    1981           5 :   qh->last_low= REALmax;
    1982           5 :   qh->last_high= REALmax;
    1983           5 :   qh->last_newhigh= REALmax;
    1984           5 :   qh->last_random= 1; /* reentrant only */
    1985           5 :   qh->lastcpu= 0.0;
    1986           5 :   qh->max_outside= 0.0;
    1987           5 :   qh->max_vertex= 0.0;
    1988           5 :   qh->MAXabs_coord= 0.0;
    1989           5 :   qh->MAXsumcoord= 0.0;
    1990           5 :   qh->MAXwidth= -REALmax;
    1991           5 :   qh->MERGEindependent= True;
    1992           5 :   qh->MINdenom_1= fmax_(1.0/REALmax, REALmin); /* used by qh_scalepoints */
    1993           5 :   qh->MINoutside= 0.0;
    1994           5 :   qh->MINvisible= REALmax;
    1995           5 :   qh->MAXcoplanar= REALmax;
    1996           5 :   qh->outside_err= REALmax;
    1997           5 :   qh->premerge_centrum= 0.0;
    1998           5 :   qh->premerge_cos= REALmax;
    1999           5 :   qh->PRINTprecision= True;
    2000           5 :   qh->PRINTradius= 0.0;
    2001           5 :   qh->postmerge_cos= REALmax;
    2002           5 :   qh->postmerge_centrum= 0.0;
    2003           5 :   qh->ROTATErandom= INT_MIN;
    2004           5 :   qh->MERGEvertices= True;
    2005           5 :   qh->totarea= 0.0;
    2006           5 :   qh->totvol= 0.0;
    2007           5 :   qh->TRACEdist= REALmax;
    2008           5 :   qh->TRACEpoint= qh_IDnone;    /* recompile to trace a point, or use 'TPn' */
    2009           5 :   qh->tracefacet_id= UINT_MAX;  /* recompile to trace a facet, set to UINT_MAX when done, see userprintf_r.c/qh_fprintf */
    2010           5 :   qh->traceridge_id= UINT_MAX;  /* recompile to trace a ridge, set to UINT_MAX when done, see userprintf_r.c/qh_fprintf */
    2011           5 :   qh->tracevertex_id= UINT_MAX; /* recompile to trace a vertex, set to UINT_MAX when done, see userprintf_r.c/qh_fprintf */
    2012             :   /* coverity[store_truncates_time_t] */
    2013           5 :   seed= (int)time(&timedata);
    2014           5 :   qh_RANDOMseed_(qh, seed);
    2015           5 :   qh->run_id= qh_RANDOMint;
    2016           5 :   if(!qh->run_id)
    2017           0 :       qh->run_id++;  /* guarantee non-zero */
    2018           5 :   qh_option(qh, "run-id", &qh->run_id, NULL);
    2019           5 :   strcat(qh->qhull, "qhull");
    2020           5 : } /* initqhull_start2 */
    2021             : 
    2022             : /*-<a                             href="qh-globa_r.htm#TOC"
    2023             :   >-------------------------------</a><a name="initthresholds">-</a>
    2024             : 
    2025             :   qh_initthresholds(qh, commandString )
    2026             :     set thresholds for printing and scaling from commandString
    2027             : 
    2028             :   returns:
    2029             :     sets qh.GOODthreshold or qh.SPLITthreshold if 'Pd0D1' used
    2030             : 
    2031             :   see:
    2032             :     qh_initflags(), 'Qbk' 'QBk' 'Pdk' and 'PDk'
    2033             :     qh_inthresholds()
    2034             : 
    2035             :   design:
    2036             :     for each 'Pdn' or 'PDn' option
    2037             :       check syntax
    2038             :       set qh.lower_threshold or qh.upper_threshold
    2039             :     set qh.GOODthreshold if an unbounded threshold is used
    2040             :     set qh.SPLITthreshold if a bounded threshold is used
    2041             : */
    2042           4 : void qh_initthresholds(qhT *qh, char *command) {
    2043             :   realT value;
    2044             :   int idx, maxdim, k;
    2045           4 :   char *s= command; /* non-const due to strtol */
    2046           4 :   char *lastoption, *lastwarning= NULL;
    2047             :   char key;
    2048             : 
    2049           4 :   maxdim= qh->input_dim;
    2050           4 :   if (qh->DELAUNAY && (qh->PROJECTdelaunay || qh->PROJECTinput))
    2051           4 :     maxdim++;
    2052          28 :   while (*s) {
    2053          24 :     if (*s == '-')
    2054           0 :       s++;
    2055          24 :     if (*s == 'P') {
    2056           0 :       lastoption= s++;
    2057           0 :       while (*s && !isspace(key= *s++)) {
    2058           0 :         if (key == 'd' || key == 'D') {
    2059           0 :           if (!isdigit(*s)) {
    2060           0 :             qh_fprintf(qh, qh->ferr, 7044, "qhull option warning: no dimension given for Print option 'P%c' at: %s.  Ignored\n",
    2061             :                     key, s-1);
    2062           0 :             lastwarning= lastoption;
    2063           0 :             continue;
    2064             :           }
    2065           0 :           idx= qh_strtol(s, &s);
    2066           0 :           if (idx >= qh->hull_dim) {
    2067           0 :             qh_fprintf(qh, qh->ferr, 7045, "qhull option warning: dimension %d for Print option 'P%c' is >= %d.  Ignored\n",
    2068             :                 idx, key, qh->hull_dim);
    2069           0 :             lastwarning= lastoption;
    2070           0 :             continue;
    2071             :           }
    2072           0 :           if (*s == ':') {
    2073           0 :             s++;
    2074           0 :             value= qh_strtod(s, &s);
    2075           0 :             if (fabs((double)value) > 1.0) {
    2076           0 :               qh_fprintf(qh, qh->ferr, 7046, "qhull option warning: value %2.4g for Print option 'P%c' is > +1 or < -1.  Ignored\n",
    2077             :                       value, key);
    2078           0 :               lastwarning= lastoption;
    2079           0 :               continue;
    2080             :             }
    2081             :           }else
    2082           0 :             value= 0.0;
    2083           0 :           if (key == 'd')
    2084           0 :             qh->lower_threshold[idx]= value;
    2085             :           else
    2086           0 :             qh->upper_threshold[idx]= value;
    2087             :         }
    2088             :       }
    2089          24 :     }else if (*s == 'Q') {
    2090          16 :       lastoption= s++;
    2091          32 :       while (*s && !isspace(key= *s++)) {
    2092          16 :         if (key == 'b' && *s == 'B') {
    2093           0 :           s++;
    2094           0 :           for (k=maxdim; k--; ) {
    2095           0 :             qh->lower_bound[k]= -qh_DEFAULTbox;
    2096           0 :             qh->upper_bound[k]= qh_DEFAULTbox;
    2097             :           }
    2098          16 :         }else if (key == 'b' && *s == 'b')
    2099           4 :           s++;
    2100          12 :         else if (key == 'b' || key == 'B') {
    2101           0 :           if (!isdigit(*s)) {
    2102           0 :             qh_fprintf(qh, qh->ferr, 7047, "qhull option warning: no dimension given for Qhull option 'Q%c'\n",
    2103             :                     key);
    2104           0 :             lastwarning= lastoption;
    2105           0 :             continue;
    2106             :           }
    2107           0 :           idx= qh_strtol(s, &s);
    2108           0 :           if (idx >= maxdim) {
    2109           0 :             qh_fprintf(qh, qh->ferr, 7048, "qhull option warning: dimension %d for Qhull option 'Q%c' is >= %d.  Ignored\n",
    2110             :                 idx, key, maxdim);
    2111           0 :             lastwarning= lastoption;
    2112           0 :             continue;
    2113             :           }
    2114           0 :           if (*s == ':') {
    2115           0 :             s++;
    2116           0 :             value= qh_strtod(s, &s);
    2117           0 :           }else if (key == 'b')
    2118           0 :             value= -qh_DEFAULTbox;
    2119             :           else
    2120           0 :             value= qh_DEFAULTbox;
    2121           0 :           if (key == 'b')
    2122           0 :             qh->lower_bound[idx]= value;
    2123             :           else
    2124           0 :             qh->upper_bound[idx]= value;
    2125             :         }
    2126             :       }
    2127             :     }else {
    2128          32 :       while (*s && !isspace(*s))
    2129          24 :         s++;
    2130             :     }
    2131          32 :     while (isspace(*s))
    2132           8 :       s++;
    2133             :   }
    2134          16 :   for (k=qh->hull_dim; k--; ) {
    2135          12 :     if (qh->lower_threshold[k] > -REALmax/2) {
    2136           0 :       qh->GOODthreshold= True;
    2137           0 :       if (qh->upper_threshold[k] < REALmax/2) {
    2138           0 :         qh->SPLITthresholds= True;
    2139           0 :         qh->GOODthreshold= False;
    2140           0 :         break;
    2141             :       }
    2142          12 :     }else if (qh->upper_threshold[k] < REALmax/2)
    2143           0 :       qh->GOODthreshold= True;
    2144             :   }
    2145           4 :   if (lastwarning && !qh->ALLOWwarning) {
    2146           0 :     qh_fprintf(qh, qh->ferr, 6036, "qhull option error: see previous warnings, use 'Qw' to override: '%s' (last offset %d)\n",
    2147           0 :       command, (int)(lastwarning-command));
    2148           0 :     qh_errexit(qh, qh_ERRinput, NULL, NULL);
    2149             :   }
    2150           4 : } /* initthresholds */
    2151             : 
    2152             : /*-<a                             href="qh-globa_r.htm#TOC"
    2153             :   >-------------------------------</a><a name="lib_check">-</a>
    2154             : 
    2155             :   qh_lib_check( qhullLibraryType, qhTsize, vertexTsize, ridgeTsize, facetTsize, setTsize, qhmemTsize )
    2156             :     Report error if library does not agree with caller
    2157             : 
    2158             :   notes:
    2159             :     NOerrors -- qh_lib_check can not call qh_errexit()
    2160             : */
    2161           5 : void qh_lib_check(int qhullLibraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize) {
    2162           5 :     int last_errcode= qh_ERRnone;
    2163             : 
    2164             : #if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)  /* user_r.h */
    2165             :     /*_CrtSetBreakAlloc(744);*/  /* Break at memalloc {744}, or 'watch' _crtBreakAlloc */
    2166             :     _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) );
    2167             :     _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    2168             :     _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
    2169             :     _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    2170             :     _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
    2171             :     _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    2172             :     _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
    2173             : #endif
    2174             : 
    2175           5 :     if (qhullLibraryType==QHULL_NON_REENTRANT) { /* 0 */
    2176           0 :       qh_fprintf_stderr(6257, "qh_lib_check: Incorrect qhull library called.  Caller uses non-reentrant Qhull with a static qhT.  Qhull library is reentrant.\n");
    2177           0 :       last_errcode= 6257;
    2178           5 :     }else if (qhullLibraryType==QHULL_QH_POINTER) { /* 1 */
    2179           0 :       qh_fprintf_stderr(6258, "qh_lib_check: Incorrect qhull library called.  Caller uses non-reentrant Qhull with a dynamic qhT via qh_QHpointer.  Qhull library is reentrant.\n");
    2180           0 :       last_errcode= 6258;
    2181           5 :     }else if (qhullLibraryType != QHULL_REENTRANT) { /* 2 */
    2182           0 :       qh_fprintf_stderr(6262, "qh_lib_check: Expecting qhullLibraryType QHULL_NON_REENTRANT(0), QHULL_QH_POINTER(1), or QHULL_REENTRANT(2).  Got %d\n", qhullLibraryType);
    2183           0 :       last_errcode= 6262;
    2184             :     }
    2185           5 :     if (qhTsize != (int)sizeof(qhT)) {
    2186           0 :       qh_fprintf_stderr(6249, "qh_lib_check: Incorrect qhull library called.  Size of qhT for caller is %d, but for qhull library is %d.\n", qhTsize, (int)sizeof(qhT));
    2187           0 :       last_errcode= 6249;
    2188             :     }
    2189           5 :     if (vertexTsize != (int)sizeof(vertexT)) {
    2190           0 :       qh_fprintf_stderr(6250, "qh_lib_check: Incorrect qhull library called.  Size of vertexT for caller is %d, but for qhull library is %d.\n", vertexTsize, (int)sizeof(vertexT));
    2191           0 :       last_errcode= 6250;
    2192             :     }
    2193           5 :     if (ridgeTsize != (int)sizeof(ridgeT)) {
    2194           0 :       qh_fprintf_stderr(6251, "qh_lib_check: Incorrect qhull library called.  Size of ridgeT for caller is %d, but for qhull library is %d.\n", ridgeTsize, (int)sizeof(ridgeT));
    2195           0 :       last_errcode= 6251;
    2196             :     }
    2197           5 :     if (facetTsize != (int)sizeof(facetT)) {
    2198           0 :       qh_fprintf_stderr(6252, "qh_lib_check: Incorrect qhull library called.  Size of facetT for caller is %d, but for qhull library is %d.\n", facetTsize, (int)sizeof(facetT));
    2199           0 :       last_errcode= 6252;
    2200             :     }
    2201           5 :     if (setTsize && setTsize != (int)sizeof(setT)) {
    2202           0 :       qh_fprintf_stderr(6253, "qh_lib_check: Incorrect qhull library called.  Size of setT for caller is %d, but for qhull library is %d.\n", setTsize, (int)sizeof(setT));
    2203           0 :       last_errcode= 6253;
    2204             :     }
    2205           5 :     if (qhmemTsize && qhmemTsize != sizeof(qhmemT)) {
    2206           0 :       qh_fprintf_stderr(6254, "qh_lib_check: Incorrect qhull library called.  Size of qhmemT for caller is %d, but for qhull library is %d.\n", qhmemTsize, (int)sizeof(qhmemT));
    2207           0 :       last_errcode= 6254;
    2208             :     }
    2209           5 :     if (last_errcode) {
    2210           0 :       qh_fprintf_stderr(6259, "qhull internal error (qh_lib_check): Cannot continue due to QH%d.  '%s' is not reentrant (e.g., qhull.so) or out-of-date.  Exit with %d\n",
    2211             :             last_errcode, qh_version2, last_errcode - 6200);
    2212           0 :       qh_exit(last_errcode - 6200);  /* can not use qh_errexit(), must be less than 255 */
    2213             :     }
    2214           5 : } /* lib_check */
    2215             : 
    2216             : /*-<a                             href="qh-globa_r.htm#TOC"
    2217             :   >-------------------------------</a><a name="option">-</a>
    2218             : 
    2219             :   qh_option(qh, option, intVal, realVal )
    2220             :     add an option description to qh.qhull_options
    2221             : 
    2222             :   notes:
    2223             :     NOerrors -- qh_option can not call qh_errexit() [qh_initqhull_start2]
    2224             :     will be printed with statistics ('Ts') and errors
    2225             :     strlen(option) < 40
    2226             : */
    2227          79 : void qh_option(qhT *qh, const char *option, int *i, realT *r) {
    2228             :   char buf[200];
    2229             :   int buflen, remainder;
    2230             : 
    2231          79 :   if (strlen(option) > sizeof(buf)-30-30) {
    2232           0 :     qh_fprintf(qh, qh->ferr, 6408, "qhull internal error (qh_option): option (%d chars) has more than %d chars.  May overflow temporary buffer.  Option '%s'\n",
    2233           0 :         (int)strlen(option), (int)sizeof(buf)-30-30, option);
    2234           0 :     qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    2235             :   }
    2236          79 :   sprintf(buf, "  %s", option);
    2237          79 :   if (i)
    2238           5 :     sprintf(buf+strlen(buf), " %d", *i);
    2239          79 :   if (r)
    2240          30 :     sprintf(buf+strlen(buf), " %2.2g", *r);
    2241          79 :   buflen= (int)strlen(buf);   /* WARN64 */
    2242          79 :   qh->qhull_optionlen += buflen;
    2243          79 :   remainder= (int)(sizeof(qh->qhull_options) - strlen(qh->qhull_options)) - 1;    /* WARN64 */
    2244          79 :   maximize_(remainder, 0);
    2245          79 :   if (qh->qhull_optionlen >= qh_OPTIONline && remainder > 0) {
    2246          15 :     strncat(qh->qhull_options, "\n", (unsigned int)remainder);
    2247          15 :     --remainder;
    2248          15 :     qh->qhull_optionlen= buflen;
    2249             :   }
    2250          79 :   if (buflen > remainder) {
    2251           0 :     trace1((qh, qh->ferr, 1058, "qh_option: option would overflow qh.qhull_options. Truncated '%s'\n", buf));
    2252             :   }
    2253          79 :   strncat(qh->qhull_options, buf, (unsigned int)remainder);
    2254          79 : } /* option */
    2255             : 
    2256             : /*-<a                             href="qh-globa_r.htm#TOC"
    2257             :   >-------------------------------</a><a name="zero">-</a>
    2258             : 
    2259             :   qh_zero( qh, errfile )
    2260             :     Initialize and zero Qhull's memory for qh_new_qhull()
    2261             : 
    2262             :   notes:
    2263             :     Not needed in global_r.c because static variables are initialized to zero
    2264             : */
    2265           0 : void qh_zero(qhT *qh, FILE *errfile) {
    2266           0 :     memset((char *)qh, 0, sizeof(qhT));   /* every field is 0, FALSE, NULL */
    2267           0 :     qh->NOerrexit= True;
    2268           0 :     qh_meminit(qh, errfile);
    2269           0 : } /* zero */
    2270             : 

Generated by: LCOV version 1.14