CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
QhullQh.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
4 ** $Id: //main/2015/qhull/src/libqhullcpp/QhullQh.cpp#2 $$Change: 2010 $
5 ** $DateTime: 2015/10/19 22:23:22 $$Author: bbarber $
6 **
7 ****************************************************************************/
8 
9 #
10 
11 
12 
13 #include "QhullError.h"
14 #include "QhullQh.h"
15 #include "QhullStat.h"
16 // #include "Qhull.h"
17 
18 #include <sstream>
19 #include <iostream>
20 
21 #include <stdarg.h>
22 
23 using std::cerr;
24 using std::string;
25 using std::vector;
26 using std::ostream;
27 
28 #ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
29 #pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
30 #pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
31 #endif
32 
33 namespace orgQhull {
34 
35 #
36 const double QhullQh::
37 default_factor_epsilon= 1.0;
38 
39 #
40 
41 QhullQh::
43 QhullQh()
44 : qhull_status(qh_ERRnone)
45 , qhull_message()
46 , error_stream(0)
47 , output_stream(0)
48 , factor_epsilon(QhullQh::default_factor_epsilon)
49 , use_output_stream(false)
50 {
51  // NOerrors: TRY_QHULL_ not needed since these routines do not call qh_errexit()
52  qh_meminit(this, NULL);
53  qh_initstatistics(this);
54  qh_initqhull_start2(this, NULL, NULL, qh_FILEstderr); // Initialize qhT
55  this->ISqhullQh= True;
56 }//QhullQh
57 
58 QhullQh::
59 ~QhullQh()
60 {
61  qh_freeqhull(this, qh_ALL); // sets qh.NOerrexit. Clears struct *qh_qh including run_id
62 }//~QhullQh
63 
64 #
65 
66 void QhullQh::
72 checkAndFreeQhullMemory()
73 {
74 #ifdef qh_NOmem
75  qh_freeqhull(this, qh_ALL);
76 #else
77  qh_memcheck(this);
78  qh_freeqhull(this, !qh_ALL);
79  countT curlong;
80  countT totlong;
81  qh_memfreeshort(this, &curlong, &totlong);
82  if (curlong || totlong)
83  throw QhullError(10026, "Qhull error: qhull did not free %d bytes of long memory (%d pieces).", totlong, curlong);
84 #endif
85 }//checkAndFreeQhullMemory
86 
87 #
88 
89 void QhullQh::
90 appendQhullMessage(const string &s)
91 {
92  if(output_stream && use_output_stream && this->USEstdout){
93  *output_stream << s;
94  }else if(error_stream){
95  *error_stream << s;
96  }else{
97  qhull_message += s;
98  }
99 }//appendQhullMessage
100 
102 void QhullQh::
103 clearQhullMessage()
104 {
105  qhull_status= qh_ERRnone;
106  qhull_message.clear();
107  RoadError::clearGlobalLog();
108 }//clearQhullMessage
109 
111 bool QhullQh::
112 hasQhullMessage() const
113 {
114  return (!qhull_message.empty() || qhull_status!=qh_ERRnone);
115  //FIXUP QH11006 -- inconsistent usage with Rbox. hasRboxMessage just tests rbox_status. No appendRboxMessage()
116 }
117 
118 void QhullQh::
119 maybeThrowQhullMessage(int exitCode)
120 {
121  if(!NOerrexit){
122  if(qhull_message.size()>0){
123  qhull_message.append("\n");
124  }
125  if(exitCode || qhull_status==qh_ERRnone){
126  qhull_status= 10073;
127  }else{
128  qhull_message.append("QH10073: ");
129  }
130  qhull_message.append("Cannot call maybeThrowQhullMessage() from QH_TRY_(). Or missing 'qh->NOerrexit=true;' after QH_TRY_(){...}.");
131  }
132  if(qhull_status==qh_ERRnone){
133  qhull_status= exitCode;
134  }
135  if(qhull_status!=qh_ERRnone){
136  QhullError e(qhull_status, qhull_message);
137  clearQhullMessage();
138  throw e; // FIXUP QH11007: copy constructor is expensive if logging
139  }
140 }//maybeThrowQhullMessage
141 
142 void QhullQh::
143 maybeThrowQhullMessage(int exitCode, int noThrow) throw()
144 {
145  QHULL_UNUSED(noThrow);
146 
147  if(qhull_status==qh_ERRnone){
148  qhull_status= exitCode;
149  }
150  if(qhull_status!=qh_ERRnone){
151  QhullError e(qhull_status, qhull_message);
152  e.logErrorLastResort();
153  }
154 }//maybeThrowQhullMessage
155 
157 std::string QhullQh::
158 qhullMessage() const
159 {
160  if(qhull_message.empty() && qhull_status!=qh_ERRnone){
161  return "qhull: no message for error. Check cerr or error stream\n";
162  }else{
163  return qhull_message;
164  }
165 }//qhullMessage
166 
167 int QhullQh::
168 qhullStatus() const
169 {
170  return qhull_status;
171 }//qhullStatus
172 
173 void QhullQh::
174 setErrorStream(ostream *os)
175 {
176  error_stream= os;
177 }//setErrorStream
178 
180 void QhullQh::
181 setOutputStream(ostream *os)
182 {
183  output_stream= os;
184  use_output_stream= (os!=0);
185 }//setOutputStream
186 
187 }//namespace orgQhull
188 
189 /*-<a href="qh_qh-user.htm#TOC"
190  >-------------------------------</a><a name="qh_fprintf">-</a>
191 
192  qh_fprintf(qhT *qh, fp, msgcode, format, list of args )
193  replaces qh_fprintf() in userprintf_r.c
194 
195 notes:
196  only called from libqhull
197  same as fprintf() and RboxPoints.qh_fprintf_rbox()
198  fgets() is not trapped like fprintf()
199  Do not throw errors from here. Use qh_errexit;
200 */
201 extern "C"
202 void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
203  va_list args;
204 
205  using namespace orgQhull;
206 
207  if(!qh->ISqhullQh){
208  qh_fprintf_stderr(10025, "Qhull error: qh_fprintf called from a Qhull instance without QhullQh defined\n");
209  qh_exit(10025);
210  }
211  QhullQh *qhullQh= static_cast<QhullQh *>(qh);
212  va_start(args, fmt);
213  if(msgcode<MSG_OUTPUT || fp == qh_FILEstderr){
214  if(msgcode>=MSG_ERROR && msgcode<MSG_WARNING){
215  if(qhullQh->qhull_status<MSG_ERROR || qhullQh->qhull_status>=MSG_WARNING){
216  qhullQh->qhull_status= msgcode;
217  }
218  }
219  char newMessage[MSG_MAXLEN];
220  // RoadError will add the message tag
221  vsnprintf(newMessage, sizeof(newMessage), fmt, args);
222  qhullQh->appendQhullMessage(newMessage);
223  va_end(args);
224  return;
225  }
226  if(qhullQh->output_stream && qhullQh->use_output_stream){
227  char newMessage[MSG_MAXLEN];
228  vsnprintf(newMessage, sizeof(newMessage), fmt, args);
229  *qhullQh->output_stream << newMessage;
230  va_end(args);
231  return;
232  }
233  // FIXUP QH11008: how do users trap messages and handle input? A callback?
234  char newMessage[MSG_MAXLEN];
235  vsnprintf(newMessage, sizeof(newMessage), fmt, args);
236  qhullQh->appendQhullMessage(newMessage);
237  va_end(args);
238 } /* qh_fprintf */
QhullRidge – Qhull's ridge structure, ridgeT, as a C++ class.
Definition: Coordinates.cpp:20
void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt,...)
Definition: QhullQh.cpp:202