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

# User Rev Content
1 greg 2.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_ */