ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/dmessage.h
Revision: 2.1
Committed: Wed Aug 14 20:05:23 2024 UTC (8 months, 2 weeks ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
feat(rxpict): Added new C++ picture rendering tool with multi-processing and spectral output

File Contents

# Content
1 /*
2 * dmessage.h
3 * panlib
4 *
5 * Depends on <stdio.h>
6 *
7 * Debug and error message logging and recovery.
8 *
9 * Created by gward on Thu May 10 2001.
10 * Modified by plonghurst on Thursday Feb 15 2007.
11 * Copyright (c) 2001 Anyhere Software. All rights reserved.
12 *
13 */
14
15 #ifndef _DMESSAGE_H_
16 #define _DMESSAGE_H_
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 /********************
23 * Type Definitions *
24 ********************/
25
26 /***********************************************************************
27 * Debug message classes
28 *
29 * If you are unsure what class to report, guess on the high side, which
30 * is less serious. For example, report an error like DMCdata even
31 * when you think it's DMCsystem, unless you really know.
32 * That way, more serious errors will be recorded from higher in the call
33 * tree. The vast majority of errors fall into the DMCdata class.
34 */
35 typedef enum {
36 DMCassert, /* assertion failure */
37 DMCmemory, /* out of memory */
38 DMCsystem, /* system error */
39 DMCparameter, /* program parameter error */
40 DMCresource, /* file/resource unavailable */
41 DMCdata, /* data error */
42 DMCinput, /* input error */
43 DMCwarning, /* warning message */
44 DMCinfo, /* informative output */
45 DMCtrace, /* trace point */
46 DMCnerr /* no error (terminator) */
47 } DMsgClass;
48
49 /***********************************************************************
50 * Message flags: record, write to logfile, send to stderr,
51 * alert user, exit program, abort
52 */
53 typedef enum {
54 DMFrecord=01, DMFlog=02, DMFstderr=04,
55 DMFalert=010, DMFexit=020, DMFabort=040
56 } DMsgFlag;
57
58 /************************
59 * Functions and Macros *
60 ************************/
61
62 /***********************************************************************
63 * int
64 * dmessage(int cls, const char *msg, const char *file, int line);
65 *
66 * Basic call interface to debug message handler. The file name
67 * and line number are generally taken from the ANSI-C __FILE__
68 * and __LINE__ predefined macros. The message class are taken
69 * from the list above, and the message should not contain newlines.
70 * All DMsgClass classes except DMCassert are recoverable and
71 * dmessage() will return. The return value is an or'ing of
72 * DMsgFlags according to what was done.
73 */
74 #ifdef __cplusplus
75 extern int dmessage(DMsgClass cls, const char *msg,
76 const char *file = NULL, int line = 0);
77 #else
78 extern int dmessage(DMsgClass cls, const char *msg,
79 const char *file, int line);
80 #endif
81
82 /***********************************************************************
83 * int
84 * DMESG(int cls, const char *msg)
85 *
86 * Basic macro call for message reporting. What actually happens to
87 * the message depends on the current settings, controlled by
88 * global variables described in the next section.
89 */
90 #define DMESG(cls, msg) dmessage(cls, msg, __FILE__, __LINE__)
91
92 /***********************************************************************
93 * int
94 * DTEST(int cnd, int cls, const char *msg)
95 *
96 * Conditional call to DMESG() for convenience. Zero is returned if
97 * the condition (cnd) evaluates to zero, and a collection of DMsgFlags
98 * saying what was done if the condition evaluates to non-zero.
99 */
100 #define DTEST(cnd, cls, msg) ((cnd) ? DMESG(cls, msg) : 0)
101
102 /***********************************************************************
103 * int
104 * DMESGF(int cls, const char *fmt, va_list..)
105 *
106 * Formatting version of DMESG() takes printf(3) format string
107 * and a variable argument list to format the message.
108 */
109 #define DMESGF(cls, fmt, val) (sprintf(dmessage_buf, fmt, val), \
110 DMESG(cls, dmessage_buf))
111
112 /***********************************************************************
113 * int
114 * DTESTF(int cnd, DMsgClass cls, const char *fmt, va_list..)
115 *
116 * Formatting version of DTEST() takes printf(3) format string
117 * and a variable argument list to format the message, but only
118 * if the condition (cnd) evaluates to non-zero.
119 */
120 #define DTESTF(cnd, cls, fmt, val) \
121 ((cnd) ? DMESGF(cls, fmt, val) : 0)
122
123 /***********************************************************************
124 * int
125 * DRESET()
126 *
127 * Reset last error message class. Call before potential error-
128 * producing subroutine, then call DMESC() or DMESCF() afterwards.
129 */
130 #define DRESET() (dmessage_last_class = DMCnerr)
131
132 /***********************************************************************
133 * int
134 * DMESC(int cls, const char *msg)
135 *
136 * Report only if this error is a higher priority than any since
137 * DRESET() was last called.
138 */
139 #define DMESC(cls, msg) DTEST((cls) < dmessage_last_class, \
140 cls, msg)
141
142 /***********************************************************************
143 * int
144 * DMESCF(int cls, const char *fmt, va_list..)
145 *
146 * Formatting version of DMESC() takes printf(3) format string, but
147 * only reports if this error is higher priority than any since
148 * DRESET() was last called.
149 */
150 #define DMESCF(cls, fmt, val) DTESTF((cls) < dmessage_last_class, \
151 cls, fmt, val)
152
153 /***********************************************************************
154 * void
155 * DASSERT(int cnd)
156 *
157 * Replacement for assert() macro; calls DTEST() with DMCassert class
158 * if asc yeilds 0. If NDEBUG is defined, the macro becomes a no-op.
159 */
160 #ifdef NDEBUG
161 #define DASSERT(asc) ((void)0)
162 #else
163 #if defined(__STDC__) || defined(__cplusplus)
164 #define DASSERT(asc) ((void)DTESTF(!(asc), DMCassert, \
165 "assertion failed ! (%s)", #asc))
166 #else
167 #define DASSERT(asc) ((void)DTESTF(!(asc), DMCassert, \
168 "assertion failed ! (%s)", "asc"))
169 #endif
170 #endif
171
172 /*********************
173 * Global Variabless *
174 *********************/
175
176 /***********************************************************************
177 * char dmessage_buf[DM_BUF_LEN]
178 *
179 * Buffer to hold formatted message contents temporarily.
180 */
181 #define DM_BUF_LEN 1024
182
183 extern char dmessage_buf[DM_BUF_LEN];
184
185 /***********************************************************************
186 * const char * dmessage_class_name[]
187 *
188 * The name of each of class in DMsgClass.
189 */
190 extern const char * dmessage_class_name[];
191
192 /***********************************************************************
193 * int dmessage_class_flags[]
194 *
195 * Flags indicating what to do with each message class. By default,
196 * the most recent message will be stored in the dmessage_last[] array
197 * (DMFrecord), but if other flags are set, the message will be sent
198 * other places as well. These flags are available to be altered by the
199 * controlling application, and will not be changed from their initial
200 * defaults (DMFrecord at minimum) by any of the dmessage routines.
201 * Beware: if the DMrecord flag is turned off for a given class and
202 * dmessage() fails to do anything, it will return zero and
203 * the DTEST() and DTESTF() macro calls may return zero even
204 * though their condition evaluated to non-zero. This problem is
205 * avoided by keeping DMrecord set for all classes.
206 */
207 extern int dmessage_class_flags[];
208
209 /***********************************************************************
210 * int dmessage_class_done[]
211 *
212 * Flags indicating what was last done with each message class.
213 * In other words, the last result of dmessage() for each class.
214 */
215 extern int dmessage_class_done[];
216
217 /***********************************************************************
218 * const char * dmessage_file[]
219 *
220 * Most recent file reported for each error class.
221 */
222 extern const char * dmessage_file[];
223
224 /***********************************************************************
225 * int dmessage_line[]
226 *
227 * Most recent line number reported for each error class.
228 */
229 extern int dmessage_line[];
230
231 /***********************************************************************
232 * const char * dmessage_record[]
233 *
234 * Most recent message for each class with the DMFrecord flag set,
235 * exactly as passed to dmessage(). If no message of
236 * a given class has been reported, then the corresponding
237 * dmessage_record pointer will be NULL.
238 */
239 extern const char * dmessage_record[];
240
241 /***********************************************************************
242 * int dmessage_last_class
243 *
244 * The lowest class message reported so far, set to DMCnerr initially.
245 * The DMESG_LAST macro provides convenient access to most recent error.
246 */
247 extern DMsgClass dmessage_last_class;
248
249 #define DMESG_LAST (dmessage_record[dmessage_last_class])
250
251 /***********************************************************************
252 * FILE * dmessage_logfp
253 *
254 * Pointer to open log file. Each message is preceeded by the file
255 * name, line number, and class for log file and stderr output. Data
256 * is flushed after each message. If this pointer is NULL (the default),
257 * then logging is disabled even for classes with the DMFlog flag set.
258 */
259 extern FILE * dmessage_logfp;
260
261 /***********************************************************************
262 * int (*dmessage_call)(DMsgClass cls, const char *msg,
263 * const char *file, int line)
264 *
265 * Pointer to function called by dmessage() to share error handling.
266 * If assigned, this function is called with the same arguments passed
267 * to dmessage(), independent of the class flag settings. The returned
268 * value is then used as a mask on the class flags to turn off some or
269 * all of the default actions. The flagged actions are considered
270 * "done" and set accordingly in the dmessage_class_done global.
271 * Defaults to NULL.
272 */
273 extern int (*dmessage_call)(DMsgClass cls, const char *msg,
274 const char *file, int line);
275
276 /***********************************************************************
277 * int (*dmessage_alert)(const char *msg)
278 *
279 * Pointer to function called by dmessage() to alert user.
280 * The function should return non-zero if the user was notified,
281 * or zero if the message could not be displayed for some reason.
282 * Defaults to NULL, which results in no DMFalert action.
283 */
284 extern int (*dmessage_alert)(const char *msg);
285
286 /***********************************************************************
287 * void (*dmessage_exit)(int status)
288 *
289 * Pointer to function called by dmessage() for classes with the
290 * DMFexit flag set, which is usually reserved for the DMCmemory class.
291 * Defaults to system exit() function, but may be reassigned by the
292 * controlling application. Assigning a value of NULL causes dmessage()
293 * to return from these calls, which might result in a memory fault if
294 * your program does not check for NULL pointer values. In general,
295 * library authors should NOT assume the DMCmemory class calls exit().
296 */
297 extern void (*dmessage_exit)(int status);
298
299 /***********************************************************************
300 * void (*dmessage_abort)()
301 *
302 * Pointer to function called by dmessage() for classes with the
303 * DMFabort flag set, which is usually reserved for the DMCassert class.
304 * Defaults to system abort() function, but may be reassigned by the
305 * controlling application. Assigning a value of NULL causes dmessage()
306 * to return from these calls, which will probably prove disasterous.
307 * A better idea if the program wants to continue is to use setjmp() and
308 * longjmp() to recover control at a lower point in the call tree. If
309 * assigned, this call should never return.
310 */
311 extern void (*dmessage_abort)();
312
313 #ifdef __cplusplus
314 }
315 #endif
316
317 #endif /* ! _DMESSAGE_H_ */