ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/dmessage.h
Revision: 2.2
Committed: Sun Jun 1 03:25:17 2025 UTC (4 days, 14 hours ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.1: +1 -0 lines
Log Message:
chore: Added missing RCSid line

File Contents

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