4 error.c - error reporting code for Imager
9 int new_fatal; // non-zero if errors are fatal
10 int old_fatal = i_set_failure_fatal(new_fatal);
11 i_set_argv0("name of your program");
12 extern void error_cb(char const *);
14 old_ecb = i_set_error_cb(error_cb);
16 extern void failed_cb(char **errors);
17 old_fcb = i_set_failed_cb(failed_cb);
18 if (!i_something(...)) {
19 char **errors = i_errors();
23 undef_int i_something(...) {
25 if (!some_lower_func(...)) {
26 return i_failed("could not something");
30 undef_int some_lower_func(...) {
31 if (somethingelse_failed()) {
32 i_push_error("could not somethingelse");
40 This module provides the C level error handling functionality for
43 A few functions return or pass in a char **, this is a NULL terminated
44 list of pointers to error messages (which are NUL terminated strings,
45 just as it normal in C :). Even though these aren't passed as char
46 const * const * pointers, don't modify the strings or the pointers.
48 The interface as currently defined isn't thread safe, unfortunately.
50 This code uses Imager's mymalloc() for memory allocation, so out of
51 memory errors are I<always> fatal.
55 These functions form the interface that a user of Imager sees (from
56 C). The Perl level won't use all of this.
67 /* we never actually use the last item - it's the NULL terminator */
69 char *error_stack[ERRSTK];
70 int error_sp = ERRSTK - 1;
71 /* we track the amount of space used each string, so we don't reallocate
72 space unless we need to.
73 This also means that a memory tracking library may see the memory
74 allocated for this as a leak. */
75 int error_space[ERRSTK];
77 static i_error_cb error_cb;
78 static i_failed_cb failed_cb;
79 static int failures_fatal;
83 =item i_set_argv0(char const *program)
85 Sets the name of the program to be displayed in fatal error messages.
87 The simplest way to use this is just:
91 when your program starts.
93 void i_set_argv0(char const *name) {
96 char *dupl = mymalloc(strlen(name)+1);
104 =item i_set_failure_fatal(int failure_fatal)
106 If failure_fatal is non-zero then any future failures will result in
107 Imager exiting your program with a message describing the failure.
109 Returns the previous setting.
113 int i_set_failures_fatal(int fatal) {
114 int old = failures_fatal;
115 failures_fatal = fatal;
121 =item i_set_error_cb(i_error_cb)
123 Sets a callback function that is called each time an error is pushed
124 onto the error stack.
126 Returns the previous callback.
128 i_set_failed_cb() is probably more useful.
132 i_error_cb i_set_error_cb(i_error_cb cb) {
133 i_error_cb old = error_cb;
140 =item i_set_failed_cb(i_failed_cb cb)
142 Sets a callback function that is called each time an Imager function
145 Returns the previous callback.
149 i_failed_cb i_set_failed_cb(i_failed_cb cb) {
150 i_failed_cb old = failed_cb;
159 Returns a pointer to the first element of an array of error messages,
160 terminated by a NULL pointer. The highest level message is first.
165 return error_stack + error_sp;
171 =head1 INTERNAL FUNCTIONS
173 These functions are called by Imager to report errors through the
176 It may be desirable to have functions to mark the stack and reset to
181 =item i_clear_error()
183 Called by any imager function before doing any other processing.
186 void i_clear_error() {
191 =item i_push_error(char const *msg)
193 Called by an imager function to push an error message onto the stack.
195 No message is pushed if the stack is full (since this means someone
196 forgot to call i_clear_error(), or that a function that doesn't do
197 error handling is calling function that does.).
201 void i_push_error(char const *msg) {
202 int size = strlen(msg)+1;
205 /* bad, bad programmer */
209 if (error_space[error_sp] < size) {
210 if (error_stack[error_sp])
211 myfree(error_stack[error_sp]);
212 /* memory allocated on the following line is only ever release when
213 we need a bigger string */
214 error_stack[error_sp] = mymalloc(size);
215 error_space[error_sp] = size;
217 strcpy(error_stack[error_sp], msg);
224 =item i_failed(char const *msg)
226 Called by Imager code to indicate that a top-level has failed.
230 Calls the current failed callback, if any.
232 Aborts the program with an error, if failures have been set to be fatal.
234 Returns zero if it does not abort.
238 int i_failed(char const *msg) {
242 failed_cb(error_stack + error_sp);
243 if (failures_fatal) {
245 fprintf(stderr, "%s: ", argv0);
246 fputs("error:\n", stderr);
247 while (error_stack[error_sp]) {
248 fprintf(stderr, " %s\n", error_stack[error_sp]);
262 This interface isn't thread safe.
266 Tony Cook <tony@develop-help.com>
268 Stack concept by Arnar Mar Hrafnkelsson <addi@umich.edu>