Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 334 lines (263 sloc) 7.919 kb
606237f C level error handling code
Tony Cook authored
1 /*
2 =head1 NAME
3
4 error.c - error reporting code for Imager
5
6 =head1 SYNOPSIS
7
8 // user code:
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 *);
13 i_error_cb old_ecb;
14 old_ecb = i_set_error_cb(error_cb);
15 i_failed_cb old_fcb;
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();
20 }
21
22 // imager code:
23 undef_int i_something(...) {
24 i_clear_error();
25 if (!some_lower_func(...)) {
26 return i_failed("could not something");
27 }
28 return 1;
29 }
30 undef_int some_lower_func(...) {
31 if (somethingelse_failed()) {
32 i_push_error("could not somethingelse");
33 return 0;
34 }
35 return 1;
36 }
37
38 =head1 DESCRIPTION
39
40 This module provides the C level error handling functionality for
41 Imager.
42
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
43 A few functions return or pass in an i_errmsg *, this is list of error
44 structures, terminated by an entry with a NULL msg value, each of
45 which contains a msg and an error code. Even though these aren't
46 passed as i_errmsg const * pointers, don't modify the strings
47 or the pointers.
606237f C level error handling code
Tony Cook authored
48
49 The interface as currently defined isn't thread safe, unfortunately.
50
51 This code uses Imager's mymalloc() for memory allocation, so out of
52 memory errors are I<always> fatal.
53
54 =head1 INTERFACE
55
56 These functions form the interface that a user of Imager sees (from
57 C). The Perl level won't use all of this.
58
59 =over
60
61 =cut
62 */
63
9c852bc @tonycoz WIP context objects
authored
64 #include "imageri.h"
606237f C level error handling code
Tony Cook authored
65 #include <stdio.h>
66 #include <stdlib.h>
67
68 /*
fa56d5a @tonycoz add i_errors()/im_errors() to the API
authored
69 =item im_errors(ctx)
70 =synopsis i_errmsg *errors = im_errors(aIMCTX);
71 =synopsis i_errmsg *errors = i_errors();
606237f C level error handling code
Tony Cook authored
72
73 Returns a pointer to the first element of an array of error messages,
74 terminated by a NULL pointer. The highest level message is first.
75
fa56d5a @tonycoz add i_errors()/im_errors() to the API
authored
76 Also callable as C<i_errors()>.
77
606237f C level error handling code
Tony Cook authored
78 =cut
79 */
9c852bc @tonycoz WIP context objects
authored
80 i_errmsg *im_errors(im_context_t ctx) {
81 return ctx->error_stack + ctx->error_sp;
82 }
83
606237f C level error handling code
Tony Cook authored
84 /*
85 =back
86
87 =head1 INTERNAL FUNCTIONS
88
89 These functions are called by Imager to report errors through the
90 above interface.
91
92 It may be desirable to have functions to mark the stack and reset to
93 the mark.
94
95 =over
96
934c0e3 @tonycoz fill out documentation
authored
97 =item im_clear_error(ctx)
98 X<im_clear_error API>X<i_clear_error API>
99 =synopsis im_clear_error(aIMCTX);
6cfee9d API documentation (mostly)
Tony Cook authored
100 =synopsis i_clear_error();
92bda63 - start of external Imager API access:
Tony Cook authored
101 =category Error handling
102
103 Clears the error stack.
104
5715f7c huge spelling update and spell checking patch
Tony Cook authored
105 Called by any Imager function before doing any other processing.
606237f C level error handling code
Tony Cook authored
106
934c0e3 @tonycoz fill out documentation
authored
107 Also callable as C<i_clear_error()>.
108
92bda63 - start of external Imager API access:
Tony Cook authored
109 =cut
110 */
9c852bc @tonycoz WIP context objects
authored
111
112 void
113 im_clear_error(im_context_t ctx) {
cd4b0b2 have error.c free a non-leak when using the debug malloc
Tony Cook authored
114 #ifdef IMAGER_DEBUG_MALLOC
115 int i;
116
9c852bc @tonycoz WIP context objects
authored
117 for (i = 0; i < IM_ERROR_COUNT; ++i) {
118 if (ctx->error_space[i]) {
119 myfree(ctx->error_stack[i].msg);
120 ctx->error_stack[i].msg = NULL;
121 ctx->error_space[i] = 0;
cd4b0b2 have error.c free a non-leak when using the debug malloc
Tony Cook authored
122 }
123 }
124 #endif
9c852bc @tonycoz WIP context objects
authored
125 ctx->error_sp = IM_ERROR_COUNT-1;
126 }
127
606237f C level error handling code
Tony Cook authored
128 /*
934c0e3 @tonycoz fill out documentation
authored
129 =item im_push_error(ctx, code, message)
130 X<im_push_error API>X<i_push_error API>
6cfee9d API documentation (mostly)
Tony Cook authored
131 =synopsis i_push_error(0, "Yep, it's broken");
132 =synopsis i_push_error(errno, "Error writing");
934c0e3 @tonycoz fill out documentation
authored
133 =synopsis im_push_error(aIMCTX, 0, "Something is wrong");
92bda63 - start of external Imager API access:
Tony Cook authored
134 =category Error handling
135
6cfee9d API documentation (mostly)
Tony Cook authored
136 Called by an Imager function to push an error message onto the stack.
606237f C level error handling code
Tony Cook authored
137
138 No message is pushed if the stack is full (since this means someone
139 forgot to call i_clear_error(), or that a function that doesn't do
140 error handling is calling function that does.).
141
142 =cut
143 */
9c852bc @tonycoz WIP context objects
authored
144 void
145 im_push_error(im_context_t ctx, int code, char const *msg) {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
146 size_t size = strlen(msg)+1;
606237f C level error handling code
Tony Cook authored
147
9c852bc @tonycoz WIP context objects
authored
148 if (ctx->error_sp <= 0)
606237f C level error handling code
Tony Cook authored
149 /* bad, bad programmer */
150 return;
151
9c852bc @tonycoz WIP context objects
authored
152 --ctx->error_sp;
153 if (ctx->error_alloc[ctx->error_sp] < size) {
154 if (ctx->error_stack[ctx->error_sp].msg)
155 myfree(ctx->error_stack[ctx->error_sp].msg);
f0960b1 - added integer overflow checks to many memory allocation calls
Tony Cook authored
156 /* memory allocated on the following line is only ever released when
606237f C level error handling code
Tony Cook authored
157 we need a bigger string */
f0960b1 - added integer overflow checks to many memory allocation calls
Tony Cook authored
158 /* size is size (len+1) of an existing string, overflow would mean
159 the system is broken anyway */
9c852bc @tonycoz WIP context objects
authored
160 ctx->error_stack[ctx->error_sp].msg = mymalloc(size); /* checked 17jul05 tonyc */
161 ctx->error_alloc[ctx->error_sp] = size;
606237f C level error handling code
Tony Cook authored
162 }
9c852bc @tonycoz WIP context objects
authored
163 strcpy(ctx->error_stack[ctx->error_sp].msg, msg);
164 ctx->error_stack[ctx->error_sp].code = code;
165 }
606237f C level error handling code
Tony Cook authored
166
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
167 /*
934c0e3 @tonycoz fill out documentation
authored
168 =item im_push_errorvf(ctx, code, format, args)
169 X<im_push_error_vf API>X<i_push_errorvf API>
170 =synopsis va_args args;
171 =synopsis va_start(args, lastarg);
172 =synopsis im_push_errorvf(ctx, code, format, args);
92bda63 - start of external Imager API access:
Tony Cook authored
173 =category Error handling
174
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
175 Intended for use by higher level functions, takes a varargs pointer
176 and a format to produce the finally pushed error message.
177
6cfee9d API documentation (mostly)
Tony Cook authored
178 Does not support perl specific format codes.
179
934c0e3 @tonycoz fill out documentation
authored
180 Also callable as C<i_push_errorvf(code, format, args)>
181
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
182 =cut
183 */
9c852bc @tonycoz WIP context objects
authored
184 void
185 im_push_errorvf(im_context_t ctx, int code, char const *fmt, va_list ap) {
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
186 char buf[1024];
86c8d19 @tonycoz [rt #69147] detect and use snprintf() more
authored
187 #if defined(IMAGER_VSNPRINTF)
188 vsnprintf(buf, sizeof(buf), fmt, ap);
189 #elif defined(_MSC_VER)
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
190 _vsnprintf(buf, sizeof(buf), fmt, ap);
191 #else
192 /* is there a way to detect vsnprintf()?
193 for this and other functions we need some mechanism to handle
194 detection (like perl's Configure, or autoconf)
195 */
196 vsprintf(buf, fmt, ap);
197 #endif
9c852bc @tonycoz WIP context objects
authored
198 im_push_error(ctx, code, buf);
199 }
200
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
201 /*
202 =item i_push_errorf(int code, char const *fmt, ...)
6cfee9d API documentation (mostly)
Tony Cook authored
203 =synopsis i_push_errorf(errno, "Cannot open file %s: %d", filename, errno);
92bda63 - start of external Imager API access:
Tony Cook authored
204 =category Error handling
205
5715f7c huge spelling update and spell checking patch
Tony Cook authored
206 A version of i_push_error() that does printf() like formatting.
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
207
6cfee9d API documentation (mostly)
Tony Cook authored
208 Does not support perl specific format codes.
209
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
210 =cut
211 */
9c852bc @tonycoz WIP context objects
authored
212 void
213 i_push_errorf(int code, char const *fmt, ...) {
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
214 va_list ap;
215 va_start(ap, fmt);
216 i_push_errorvf(code, fmt, ap);
217 va_end(ap);
606237f C level error handling code
Tony Cook authored
218 }
219
934c0e3 @tonycoz fill out documentation
authored
220 /*
221 =item im_push_errorf(ctx, code, char const *fmt, ...)
222 =synopsis im_push_errorf(aIMCTX, errno, "Cannot open file %s: %d", filename, errno);
223 =category Error handling
224
225 A version of im_push_error() that does printf() like formatting.
226
227 Does not support perl specific format codes.
228
229 =cut
230 */
9c852bc @tonycoz WIP context objects
authored
231 void
232 im_push_errorf(im_context_t ctx, int code, char const *fmt, ...) {
233 va_list ap;
234 va_start(ap, fmt);
235 im_push_errorvf(ctx, code, fmt, ap);
236 va_end(ap);
237 }
238
f0960b1 - added integer overflow checks to many memory allocation calls
Tony Cook authored
239 #ifdef IMAGER_I_FAILED
240 #error "This isn't used and is untested"
241
606237f C level error handling code
Tony Cook authored
242 /*
243 =item i_failed(char const *msg)
244
245 Called by Imager code to indicate that a top-level has failed.
246
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
247 msg can be NULL, in which case no error is pushed.
606237f C level error handling code
Tony Cook authored
248
249 Calls the current failed callback, if any.
250
251 Aborts the program with an error, if failures have been set to be fatal.
252
253 Returns zero if it does not abort.
254
255 =cut
256 */
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
257 int i_failed(int code, char const *msg) {
606237f C level error handling code
Tony Cook authored
258 if (msg)
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
259 i_push_error(code, msg);
606237f C level error handling code
Tony Cook authored
260 if (failed_cb)
261 failed_cb(error_stack + error_sp);
262 if (failures_fatal) {
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
263 int sp;
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
264 size_t total; /* total length of error messages */
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
265 char *full; /* full message for logging */
606237f C level error handling code
Tony Cook authored
266 if (argv0)
267 fprintf(stderr, "%s: ", argv0);
268 fputs("error:\n", stderr);
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
269 sp = error_sp;
270 while (error_stack[sp].msg) {
a743c0a Removed a bunch of unused variables and fixed an attempt to print out a
Arnar Mar Hrafnkelsson authored
271 fprintf(stderr, " %s\n", error_stack[sp].msg);
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
272 ++sp;
273 }
274 /* we want to log the error too, build an error message to hand to
b1e9695 long delayed renaming of m_fatal() to i_fatal() to match Imager's
Tony Cook authored
275 i_fatal() */
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
276 total = 1; /* remember the NUL */
277 for (sp = error_sp; error_stack[sp].msg; ++sp) {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
278 size_t new_total += strlen(error_stack[sp].msg) + 2;
279 if (new_total < total) {
280 /* overflow, somehow */
281 break;
282 }
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
283 }
a6c4734 changed malloc to mymalloc in error.c and Added reading from scalars for...
Arnar Mar Hrafnkelsson authored
284 full = mymalloc(total);
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
285 if (!full) {
286 /* just quit, at least it's on stderr */
287 exit(EXIT_FAILURE);
288 }
289 *full = 0;
290 for (sp = error_sp; error_stack[sp].msg; ++sp) {
291 strcat(full, error_stack[sp].msg);
292 strcat(full, ": ");
606237f C level error handling code
Tony Cook authored
293 }
c5cf761 added error codes and calls to m_fatal() on fatal errors
Tony Cook authored
294 /* lose the extra ": " */
295 full[strlen(full)-2] = '\0';
b1e9695 long delayed renaming of m_fatal() to i_fatal() to match Imager's
Tony Cook authored
296 i_fatal(EXIT_FAILURE, "%s", full);
606237f C level error handling code
Tony Cook authored
297 }
298
299 return 0;
300 }
301
f0960b1 - added integer overflow checks to many memory allocation calls
Tony Cook authored
302 #endif
303
606237f C level error handling code
Tony Cook authored
304 /*
b3afeed - an integer division meant that preview scaling to below 1 pixel
Tony Cook authored
305 =item im_assert_fail(file, line, message)
306
307 Called when an im_assert() assertion fails.
308
309 =cut
310 */
311
312 void
313 im_assert_fail(char const *file, int line, char const *message) {
314 fprintf(stderr, "Assertion failed line %d file %s: %s\n",
315 line, file, message);
9c852bc @tonycoz WIP context objects
authored
316 abort();
b3afeed - an integer division meant that preview scaling to below 1 pixel
Tony Cook authored
317 }
318
319 /*
606237f C level error handling code
Tony Cook authored
320 =back
321
322 =head1 BUGS
323
324 This interface isn't thread safe.
325
326 =head1 AUTHOR
327
328 Tony Cook <tony@develop-help.com>
329
330 Stack concept by Arnar Mar Hrafnkelsson <addi@umich.edu>
331
332 =cut
333 */
Something went wrong with that request. Please try again.