/src/imagemagick/MagickCore/exception.c
Line | Count | Source |
1 | | /* |
2 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
3 | | % % |
4 | | % % |
5 | | % % |
6 | | % EEEEE X X CCCC EEEEE PPPP TTTTT IIIII OOO N N % |
7 | | % E X X C E P P T I O O NN N % |
8 | | % EEE X C EEE PPPP T I O O N N N % |
9 | | % E X X C E P T I O O N NN % |
10 | | % EEEEE X X CCCC EEEEE P T IIIII OOO N N % |
11 | | % % |
12 | | % % |
13 | | % MagickCore Exception Methods % |
14 | | % % |
15 | | % Software Design % |
16 | | % Cristy % |
17 | | % July 1993 % |
18 | | % % |
19 | | % % |
20 | | % Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization % |
21 | | % dedicated to making software imaging solutions freely available. % |
22 | | % % |
23 | | % You may not use this file except in compliance with the License. You may % |
24 | | % obtain a copy of the License at % |
25 | | % % |
26 | | % https://imagemagick.org/license/ % |
27 | | % % |
28 | | % Unless required by applicable law or agreed to in writing, software % |
29 | | % distributed under the License is distributed on an "AS IS" BASIS, % |
30 | | % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
31 | | % See the License for the specific language governing permissions and % |
32 | | % limitations under the License. % |
33 | | % % |
34 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
35 | | % |
36 | | % |
37 | | % |
38 | | */ |
39 | | |
40 | | /* |
41 | | Include declarations. |
42 | | */ |
43 | | #include "MagickCore/studio.h" |
44 | | #include "MagickCore/client.h" |
45 | | #include "MagickCore/exception.h" |
46 | | #include "MagickCore/exception-private.h" |
47 | | #include "MagickCore/linked-list.h" |
48 | | #include "MagickCore/locale_.h" |
49 | | #include "MagickCore/log.h" |
50 | | #include "MagickCore/magick.h" |
51 | | #include "MagickCore/memory_.h" |
52 | | #include "MagickCore/memory-private.h" |
53 | | #include "MagickCore/semaphore.h" |
54 | | #include "MagickCore/string_.h" |
55 | | #include "MagickCore/utility.h" |
56 | | #include "MagickCore/utility-private.h" |
57 | | |
58 | | /* |
59 | | Define declarations. |
60 | | */ |
61 | 44.2M | #define MaxExceptionList 64 |
62 | | |
63 | | /* |
64 | | Forward declarations. |
65 | | */ |
66 | | #if defined(__cplusplus) || defined(c_plusplus) |
67 | | extern "C" { |
68 | | #endif |
69 | | |
70 | | static void |
71 | | DefaultErrorHandler(const ExceptionType,const char *,const char *), |
72 | | DefaultFatalErrorHandler(const ExceptionType,const char *,const char *) |
73 | | magick_attribute((__noreturn__)), |
74 | | DefaultWarningHandler(const ExceptionType,const char *,const char *); |
75 | | |
76 | | #if defined(__cplusplus) || defined(c_plusplus) |
77 | | } |
78 | | #endif |
79 | | |
80 | | /* |
81 | | Global declarations. |
82 | | */ |
83 | | static ErrorHandler |
84 | | error_handler = DefaultErrorHandler; |
85 | | |
86 | | static FatalErrorHandler |
87 | | fatal_error_handler = DefaultFatalErrorHandler; |
88 | | |
89 | | static WarningHandler |
90 | | warning_handler = DefaultWarningHandler; |
91 | | |
92 | | /* |
93 | | Static declarations. |
94 | | */ |
95 | | static SemaphoreInfo |
96 | | *exception_semaphore = (SemaphoreInfo *) NULL; |
97 | | |
98 | | /* |
99 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
100 | | % % |
101 | | % % |
102 | | % % |
103 | | % A c q u i r e E x c e p t i o n I n f o % |
104 | | % % |
105 | | % % |
106 | | % % |
107 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
108 | | % |
109 | | % AcquireExceptionInfo() allocates the ExceptionInfo structure. |
110 | | % |
111 | | % The format of the AcquireExceptionInfo method is: |
112 | | % |
113 | | % ExceptionInfo *AcquireExceptionInfo(void) |
114 | | % |
115 | | */ |
116 | | MagickExport ExceptionInfo *AcquireExceptionInfo(void) |
117 | 100M | { |
118 | 100M | ExceptionInfo |
119 | 100M | *exception; |
120 | | |
121 | 100M | exception=(ExceptionInfo *) AcquireCriticalMemory(sizeof(*exception)); |
122 | 100M | InitializeExceptionInfo(exception); |
123 | 100M | exception->relinquish=MagickTrue; |
124 | 100M | return(exception); |
125 | 100M | } |
126 | | |
127 | | /* |
128 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
129 | | % % |
130 | | % % |
131 | | % % |
132 | | % C l e a r M a g i c k E x c e p t i o n % |
133 | | % % |
134 | | % % |
135 | | % % |
136 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
137 | | % |
138 | | % ClearMagickException() clears any exception that may not have been caught |
139 | | % yet. |
140 | | % |
141 | | % The format of the ClearMagickException method is: |
142 | | % |
143 | | % void ClearMagickException(ExceptionInfo *exception) |
144 | | % |
145 | | % A description of each parameter follows: |
146 | | % |
147 | | % o exception: the exception info. |
148 | | % |
149 | | */ |
150 | | |
151 | | static void *DestroyExceptionElement(void *exception) |
152 | 4.80M | { |
153 | 4.80M | ExceptionInfo |
154 | 4.80M | *p; |
155 | | |
156 | 4.80M | p=(ExceptionInfo *) exception; |
157 | 4.80M | if (p->reason != (char *) NULL) |
158 | 4.80M | p->reason=DestroyString(p->reason); |
159 | 4.80M | if (p->description != (char *) NULL) |
160 | 135 | p->description=DestroyString(p->description); |
161 | 4.80M | p=(ExceptionInfo *) RelinquishMagickMemory(p); |
162 | 4.80M | return((void *) NULL); |
163 | 4.80M | } |
164 | | |
165 | | MagickExport void ClearMagickException(ExceptionInfo *exception) |
166 | 35.8k | { |
167 | 35.8k | assert(exception != (ExceptionInfo *) NULL); |
168 | 35.8k | assert(exception->signature == MagickCoreSignature); |
169 | 35.8k | if (exception->exceptions == (void *) NULL) |
170 | 0 | return; |
171 | 35.8k | LockSemaphoreInfo(exception->semaphore); |
172 | 35.8k | ClearLinkedList((LinkedListInfo *) exception->exceptions, |
173 | 35.8k | DestroyExceptionElement); |
174 | 35.8k | exception->severity=UndefinedException; |
175 | 35.8k | exception->reason=(char *) NULL; |
176 | 35.8k | exception->description=(char *) NULL; |
177 | 35.8k | UnlockSemaphoreInfo(exception->semaphore); |
178 | 35.8k | errno=0; |
179 | 35.8k | } |
180 | | |
181 | | /* |
182 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
183 | | % % |
184 | | % % |
185 | | % % |
186 | | % C a t c h E x c e p t i o n % |
187 | | % % |
188 | | % % |
189 | | % % |
190 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
191 | | % |
192 | | % CatchException() returns if no exceptions is found otherwise it reports |
193 | | % the exception as a warning, error, or fatal depending on the severity. |
194 | | % |
195 | | % The format of the CatchException method is: |
196 | | % |
197 | | % void CatchException(ExceptionInfo *exception) |
198 | | % |
199 | | % A description of each parameter follows: |
200 | | % |
201 | | % o exception: the exception info. |
202 | | % |
203 | | */ |
204 | | MagickExport void CatchException(ExceptionInfo *exception) |
205 | 35.8k | { |
206 | 35.8k | LinkedListInfo |
207 | 35.8k | *exceptions; |
208 | | |
209 | 35.8k | const ExceptionInfo |
210 | 35.8k | *p; |
211 | | |
212 | 35.8k | assert(exception != (ExceptionInfo *) NULL); |
213 | 35.8k | assert(exception->signature == MagickCoreSignature); |
214 | 35.8k | if (exception->exceptions == (void *) NULL) |
215 | 0 | return; |
216 | 35.8k | LockSemaphoreInfo(exception->semaphore); |
217 | 35.8k | exceptions=(LinkedListInfo *) exception->exceptions; |
218 | 35.8k | ResetLinkedListIterator(exceptions); |
219 | 35.8k | p=(const ExceptionInfo *) GetNextValueInLinkedList(exceptions); |
220 | 107k | while (p != (const ExceptionInfo *) NULL) |
221 | 71.9k | { |
222 | 71.9k | if ((p->severity >= WarningException) && (p->severity < ErrorException)) |
223 | 717 | MagickWarning(p->severity,p->reason,p->description); |
224 | 71.9k | if ((p->severity >= ErrorException) && (p->severity < FatalErrorException)) |
225 | 71.2k | MagickError(p->severity,p->reason,p->description); |
226 | 71.9k | if (p->severity >= FatalErrorException) |
227 | 0 | MagickFatalError(p->severity,p->reason,p->description); |
228 | 71.9k | p=(const ExceptionInfo *) GetNextValueInLinkedList(exceptions); |
229 | 71.9k | } |
230 | 35.8k | UnlockSemaphoreInfo(exception->semaphore); |
231 | 35.8k | ClearMagickException(exception); |
232 | 35.8k | } |
233 | | |
234 | | /* |
235 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
236 | | % % |
237 | | % % |
238 | | % % |
239 | | % C l o n e E x c e p t i o n I n f o % |
240 | | % % |
241 | | % % |
242 | | % % |
243 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
244 | | % |
245 | | % CloneExceptionInfo() clones the ExceptionInfo structure. |
246 | | % |
247 | | % The format of the CloneExceptionInfo method is: |
248 | | % |
249 | | % ExceptionInfo *CloneException(ExceptionInfo *exception) |
250 | | % |
251 | | % A description of each parameter follows: |
252 | | % |
253 | | % o exception: the exception info. |
254 | | % |
255 | | */ |
256 | | MagickExport ExceptionInfo *CloneExceptionInfo(ExceptionInfo *exception) |
257 | 0 | { |
258 | 0 | ExceptionInfo |
259 | 0 | *clone_exception; |
260 | |
|
261 | 0 | clone_exception=(ExceptionInfo *) AcquireCriticalMemory(sizeof(*exception)); |
262 | 0 | InitializeExceptionInfo(clone_exception); |
263 | 0 | InheritException(clone_exception,exception); |
264 | 0 | clone_exception->relinquish=MagickTrue; |
265 | 0 | return(clone_exception); |
266 | 0 | } |
267 | | |
268 | | /* |
269 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
270 | | % % |
271 | | % % |
272 | | % % |
273 | | + D e f a u l t E r r o r H a n d l e r % |
274 | | % % |
275 | | % % |
276 | | % % |
277 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
278 | | % |
279 | | % DefaultErrorHandler() displays an error reason. |
280 | | % |
281 | | % The format of the DefaultErrorHandler method is: |
282 | | % |
283 | | % void MagickError(const ExceptionType severity,const char *reason, |
284 | | % const char *description) |
285 | | % |
286 | | % A description of each parameter follows: |
287 | | % |
288 | | % o severity: Specifies the numeric error category. |
289 | | % |
290 | | % o reason: Specifies the reason to display before terminating the |
291 | | % program. |
292 | | % |
293 | | % o description: Specifies any description to the reason. |
294 | | % |
295 | | */ |
296 | | static void DefaultErrorHandler(const ExceptionType magick_unused(severity), |
297 | | const char *reason,const char *description) |
298 | 71.2k | { |
299 | 71.2k | magick_unreferenced(severity); |
300 | | |
301 | 71.2k | if (reason == (char *) NULL) |
302 | 0 | return; |
303 | 71.2k | (void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason); |
304 | 71.2k | if (description != (char *) NULL) |
305 | 0 | (void) FormatLocaleFile(stderr," (%s)",description); |
306 | 71.2k | (void) FormatLocaleFile(stderr,".\n"); |
307 | 71.2k | (void) fflush(stderr); |
308 | 71.2k | } |
309 | | |
310 | | /* |
311 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
312 | | % % |
313 | | % % |
314 | | % % |
315 | | + D e f a u l t F a t a l E r r o r H a n d l e r % |
316 | | % % |
317 | | % % |
318 | | % % |
319 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
320 | | % |
321 | | % DefaultFatalErrorHandler() displays an error reason and then terminates the |
322 | | % program. |
323 | | % |
324 | | % The format of the DefaultFatalErrorHandler method is: |
325 | | % |
326 | | % void MagickFatalError(const ExceptionType severity,const char *reason, |
327 | | % const char *description) |
328 | | % |
329 | | % A description of each parameter follows: |
330 | | % |
331 | | % o severity: Specifies the numeric error category. |
332 | | % |
333 | | % o reason: Specifies the reason to display before terminating the program. |
334 | | % |
335 | | % o description: Specifies any description to the reason. |
336 | | % |
337 | | */ |
338 | | static void DefaultFatalErrorHandler(const ExceptionType severity, |
339 | | const char *reason,const char *description) |
340 | 0 | { |
341 | 0 | (void) FormatLocaleFile(stderr,"%s:",GetClientName()); |
342 | 0 | if (reason != (char *) NULL) |
343 | 0 | (void) FormatLocaleFile(stderr," %s",reason); |
344 | 0 | if (description != (char *) NULL) |
345 | 0 | (void) FormatLocaleFile(stderr," (%s)",description); |
346 | 0 | (void) FormatLocaleFile(stderr,".\n"); |
347 | 0 | (void) fflush(stderr); |
348 | 0 | MagickCoreTerminus(); |
349 | 0 | exit((int) (severity-FatalErrorException)+1); |
350 | 0 | } |
351 | | |
352 | | /* |
353 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
354 | | % % |
355 | | % % |
356 | | % % |
357 | | + D e f a u l t W a r n i n g H a n d l e r % |
358 | | % % |
359 | | % % |
360 | | % % |
361 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
362 | | % |
363 | | % DefaultWarningHandler() displays a warning reason. |
364 | | % |
365 | | % The format of the DefaultWarningHandler method is: |
366 | | % |
367 | | % void DefaultWarningHandler(const ExceptionType severity, |
368 | | % const char *reason,const char *description) |
369 | | % |
370 | | % A description of each parameter follows: |
371 | | % |
372 | | % o severity: Specifies the numeric warning category. |
373 | | % |
374 | | % o reason: Specifies the reason to display before terminating the |
375 | | % program. |
376 | | % |
377 | | % o description: Specifies any description to the reason. |
378 | | % |
379 | | */ |
380 | | static void DefaultWarningHandler(const ExceptionType magick_unused(severity), |
381 | | const char *reason,const char *description) |
382 | 717 | { |
383 | 717 | magick_unreferenced(severity); |
384 | | |
385 | 717 | if (reason == (char *) NULL) |
386 | 0 | return; |
387 | 717 | (void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason); |
388 | 717 | if (description != (char *) NULL) |
389 | 0 | (void) FormatLocaleFile(stderr," (%s)",description); |
390 | 717 | (void) FormatLocaleFile(stderr,".\n"); |
391 | 717 | (void) fflush(stderr); |
392 | 717 | } |
393 | | |
394 | | /* |
395 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
396 | | % % |
397 | | % % |
398 | | % % |
399 | | % D e s t r o y E x c e p t i o n I n f o % |
400 | | % % |
401 | | % % |
402 | | % % |
403 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
404 | | % |
405 | | % DestroyExceptionInfo() deallocates memory associated with an exception. |
406 | | % |
407 | | % The format of the DestroyExceptionInfo method is: |
408 | | % |
409 | | % ExceptionInfo *DestroyExceptionInfo(ExceptionInfo *exception) |
410 | | % |
411 | | % A description of each parameter follows: |
412 | | % |
413 | | % o exception: the exception info. |
414 | | % |
415 | | */ |
416 | | MagickExport ExceptionInfo *DestroyExceptionInfo(ExceptionInfo *exception) |
417 | 100M | { |
418 | 100M | MagickBooleanType |
419 | 100M | relinquish; |
420 | | |
421 | 100M | assert(exception != (ExceptionInfo *) NULL); |
422 | 100M | assert(exception->signature == MagickCoreSignature); |
423 | 100M | if (exception->semaphore == (SemaphoreInfo *) NULL) |
424 | 0 | ActivateSemaphoreInfo(&exception->semaphore); |
425 | 100M | LockSemaphoreInfo(exception->semaphore); |
426 | 100M | exception->severity=UndefinedException; |
427 | 100M | if (exception->relinquish != MagickFalse) |
428 | 100M | { |
429 | 100M | exception->signature=(~MagickCoreSignature); |
430 | 100M | if (exception->exceptions != (void *) NULL) |
431 | 100M | exception->exceptions=(void *) DestroyLinkedList((LinkedListInfo *) |
432 | 100M | exception->exceptions,DestroyExceptionElement); |
433 | 100M | } |
434 | 0 | else |
435 | 0 | if (exception->exceptions != (void *) NULL) |
436 | 0 | ClearLinkedList((LinkedListInfo *) exception->exceptions, |
437 | 0 | DestroyExceptionElement); |
438 | 100M | relinquish=exception->relinquish; |
439 | 100M | UnlockSemaphoreInfo(exception->semaphore); |
440 | 100M | if (relinquish != MagickFalse) |
441 | 100M | { |
442 | 100M | RelinquishSemaphoreInfo(&exception->semaphore); |
443 | 100M | exception=(ExceptionInfo *) RelinquishMagickMemory(exception); |
444 | 100M | } |
445 | 100M | return(exception); |
446 | 100M | } |
447 | | |
448 | | /* |
449 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
450 | | % % |
451 | | % % |
452 | | % % |
453 | | + E x e c e p t i o n C o m p o n e n t G e n e s i s % |
454 | | % % |
455 | | % % |
456 | | % % |
457 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
458 | | % |
459 | | % ExceptionComponentGenesis() instantiates the exception component. |
460 | | % |
461 | | % The format of the ExceptionComponentGenesis method is: |
462 | | % |
463 | | % MagickBooleanType ExceptionComponentGenesis(void) |
464 | | % |
465 | | */ |
466 | | MagickPrivate MagickBooleanType ExceptionComponentGenesis(void) |
467 | 296 | { |
468 | 296 | if (exception_semaphore == (SemaphoreInfo *) NULL) |
469 | 296 | exception_semaphore=AcquireSemaphoreInfo(); |
470 | 296 | return(MagickTrue); |
471 | 296 | } |
472 | | |
473 | | /* |
474 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
475 | | % % |
476 | | % % |
477 | | % % |
478 | | + E x c e p t i o n C o m p o n e n t T e r m i n u s % |
479 | | % % |
480 | | % % |
481 | | % % |
482 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
483 | | % |
484 | | % ExceptionComponentTerminus() destroys the exception component. |
485 | | % |
486 | | % The format of the ExceptionComponentTerminus method is: |
487 | | % |
488 | | % void ExceptionComponentTerminus(void) |
489 | | % |
490 | | */ |
491 | | MagickPrivate void ExceptionComponentTerminus(void) |
492 | 0 | { |
493 | 0 | if (exception_semaphore == (SemaphoreInfo *) NULL) |
494 | 0 | ActivateSemaphoreInfo(&exception_semaphore); |
495 | 0 | LockSemaphoreInfo(exception_semaphore); |
496 | 0 | UnlockSemaphoreInfo(exception_semaphore); |
497 | 0 | RelinquishSemaphoreInfo(&exception_semaphore); |
498 | 0 | } |
499 | | |
500 | | /* |
501 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
502 | | % % |
503 | | % % |
504 | | % % |
505 | | % G e t E x c e p t i o n M e s s a g e % |
506 | | % % |
507 | | % % |
508 | | % % |
509 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
510 | | % |
511 | | % GetExceptionMessage() returns the error message defined by the specified |
512 | | % error code. |
513 | | % |
514 | | % The format of the GetExceptionMessage method is: |
515 | | % |
516 | | % char *GetExceptionMessage(const int error) |
517 | | % |
518 | | % A description of each parameter follows: |
519 | | % |
520 | | % o error: the error code. |
521 | | % |
522 | | */ |
523 | | MagickExport char *GetExceptionMessage(const int error) |
524 | 56.9k | { |
525 | 56.9k | char |
526 | 56.9k | exception[MagickPathExtent]; |
527 | | |
528 | 56.9k | *exception='\0'; |
529 | 56.9k | #if defined(MAGICKCORE_HAVE_STRERROR_R) |
530 | | #if !defined(MAGICKCORE_STRERROR_R_CHAR_P) |
531 | | (void) strerror_r(error,exception,sizeof(exception)); |
532 | | #else |
533 | 56.9k | (void) CopyMagickString(exception,strerror_r(error,exception, |
534 | 56.9k | sizeof(exception)),sizeof(exception)); |
535 | 56.9k | #endif |
536 | | #elif defined(MAGICKCORE_WINDOWS_SUPPORT) |
537 | | strerror_s(exception,sizeof(exception),error); |
538 | | #else |
539 | | (void) CopyMagickString(exception,strerror(error),sizeof(exception)); |
540 | | #endif |
541 | 56.9k | return(ConstantString(exception)); |
542 | 56.9k | } |
543 | | |
544 | | /* |
545 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
546 | | % % |
547 | | % % |
548 | | % % |
549 | | % G e t L o c a l e E x c e p t i o n M e s s a g e % |
550 | | % % |
551 | | % % |
552 | | % % |
553 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
554 | | % |
555 | | % GetLocaleExceptionMessage() converts a enumerated exception severity and tag |
556 | | % to a message in the current locale. |
557 | | % |
558 | | % The format of the GetLocaleExceptionMessage method is: |
559 | | % |
560 | | % const char *GetLocaleExceptionMessage(const ExceptionType severity, |
561 | | % const char *tag) |
562 | | % |
563 | | % A description of each parameter follows: |
564 | | % |
565 | | % o severity: the severity of the exception. |
566 | | % |
567 | | % o tag: the message tag. |
568 | | % |
569 | | */ |
570 | | |
571 | | static const char *ExceptionSeverityToTag(const ExceptionType severity) |
572 | 39.4M | { |
573 | 39.4M | switch (severity) |
574 | 39.4M | { |
575 | 31.9k | case ResourceLimitWarning: return("Resource/Limit/Warning/"); |
576 | 852 | case TypeWarning: return("Type/Warning/"); |
577 | 216k | case OptionWarning: return("Option/Warning/"); |
578 | 0 | case DelegateWarning: return("Delegate/Warning/"); |
579 | 38.1k | case MissingDelegateWarning: return("Missing/Delegate/Warning/"); |
580 | 6.23M | case CorruptImageWarning: return("Corrupt/Image/Warning/"); |
581 | 0 | case FileOpenWarning: return("File/Open/Warning/"); |
582 | 0 | case BlobWarning: return("Blob/Warning/"); |
583 | 0 | case StreamWarning: return("Stream/Warning/"); |
584 | 0 | case CacheWarning: return("Cache/Warning/"); |
585 | 20.8M | case CoderWarning: return("Coder/Warning/"); |
586 | 0 | case FilterWarning: return("Filter/Warning/"); |
587 | 0 | case ModuleWarning: return("Module/Warning/"); |
588 | 0 | case DrawWarning: return("Draw/Warning/"); |
589 | 0 | case ImageWarning: return("Image/Warning/"); |
590 | 0 | case WandWarning: return("Wand/Warning/"); |
591 | 0 | case XServerWarning: return("XServer/Warning/"); |
592 | 0 | case MonitorWarning: return("Monitor/Warning/"); |
593 | 0 | case RegistryWarning: return("Registry/Warning/"); |
594 | 632 | case ConfigureWarning: return("Configure/Warning/"); |
595 | 0 | case PolicyWarning: return("Policy/Warning/"); |
596 | 10.3k | case ResourceLimitError: return("Resource/Limit/Error/"); |
597 | 79.4k | case TypeError: return("Type/Error/"); |
598 | 285k | case OptionError: return("Option/Error/"); |
599 | 75.2k | case DelegateError: return("Delegate/Error/"); |
600 | 10.9k | case MissingDelegateError: return("Missing/Delegate/Error/"); |
601 | 3.75M | case CorruptImageError: return("Corrupt/Image/Error/"); |
602 | 1.65k | case FileOpenError: return("File/Open/Error/"); |
603 | 42.1k | case BlobError: return("Blob/Error/"); |
604 | 1.78k | case StreamError: return("Stream/Error/"); |
605 | 217k | case CacheError: return("Cache/Error/"); |
606 | 7.49M | case CoderError: return("Coder/Error/"); |
607 | 0 | case FilterError: return("Filter/Error/"); |
608 | 0 | case ModuleError: return("Module/Error/"); |
609 | 41.2k | case DrawError: return("Draw/Error/"); |
610 | 87.6k | case ImageError: return("Image/Error/"); |
611 | 0 | case WandError: return("Wand/Error/"); |
612 | 0 | case XServerError: return("XServer/Error/"); |
613 | 0 | case MonitorError: return("Monitor/Error/"); |
614 | 0 | case RegistryError: return("Registry/Error/"); |
615 | 0 | case ConfigureError: return("Configure/Error/"); |
616 | 0 | case PolicyError: return("Policy/Error/"); |
617 | 0 | case ResourceLimitFatalError: return("Resource/Limit/FatalError/"); |
618 | 0 | case TypeFatalError: return("Type/FatalError/"); |
619 | 0 | case OptionFatalError: return("Option/FatalError/"); |
620 | 0 | case DelegateFatalError: return("Delegate/FatalError/"); |
621 | 0 | case MissingDelegateFatalError: return("Missing/Delegate/FatalError/"); |
622 | 0 | case CorruptImageFatalError: return("Corrupt/Image/FatalError/"); |
623 | 0 | case FileOpenFatalError: return("File/Open/FatalError/"); |
624 | 0 | case BlobFatalError: return("Blob/FatalError/"); |
625 | 0 | case StreamFatalError: return("Stream/FatalError/"); |
626 | 0 | case CacheFatalError: return("Cache/FatalError/"); |
627 | 0 | case CoderFatalError: return("Coder/FatalError/"); |
628 | 0 | case FilterFatalError: return("Filter/FatalError/"); |
629 | 0 | case ModuleFatalError: return("Module/FatalError/"); |
630 | 0 | case DrawFatalError: return("Draw/FatalError/"); |
631 | 0 | case ImageFatalError: return("Image/FatalError/"); |
632 | 0 | case WandFatalError: return("Wand/FatalError/"); |
633 | 0 | case XServerFatalError: return("XServer/FatalError/"); |
634 | 0 | case MonitorFatalError: return("Monitor/FatalError/"); |
635 | 0 | case RegistryFatalError: return("Registry/FatalError/"); |
636 | 0 | case ConfigureFatalError: return("Configure/FatalError/"); |
637 | 0 | case PolicyFatalError: return("Policy/FatalError/"); |
638 | 0 | default: break; |
639 | 39.4M | } |
640 | 0 | return(""); |
641 | 39.4M | } |
642 | | |
643 | | MagickExport const char *GetLocaleExceptionMessage(const ExceptionType severity, |
644 | | const char *tag) |
645 | 39.4M | { |
646 | 39.4M | char |
647 | 39.4M | message[MagickPathExtent]; |
648 | | |
649 | 39.4M | const char |
650 | 39.4M | *locale_message; |
651 | | |
652 | 39.4M | assert(tag != (const char *) NULL); |
653 | 39.4M | (void) FormatLocaleString(message,MagickPathExtent,"Exception/%s%s", |
654 | 39.4M | ExceptionSeverityToTag(severity),tag); |
655 | 39.4M | locale_message=GetLocaleMessage(message); |
656 | 39.4M | if (locale_message == (const char *) NULL) |
657 | 0 | return(tag); |
658 | 39.4M | if (locale_message == message) |
659 | 39.4M | return(tag); |
660 | 0 | return(locale_message); |
661 | 39.4M | } |
662 | | |
663 | | /* |
664 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
665 | | % % |
666 | | % % |
667 | | % % |
668 | | % I n h e r i t E x c e p t i o n % |
669 | | % % |
670 | | % % |
671 | | % % |
672 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
673 | | % |
674 | | % InheritException() inherits an exception from a related exception. |
675 | | % |
676 | | % The format of the InheritException method is: |
677 | | % |
678 | | % void InheritException(ExceptionInfo *exception,const ExceptionInfo *relative) |
679 | | % |
680 | | % A description of each parameter follows: |
681 | | % |
682 | | % o exception: the exception info. |
683 | | % |
684 | | % o relative: the related exception info. |
685 | | % |
686 | | */ |
687 | | MagickExport void InheritException(ExceptionInfo *exception, |
688 | | const ExceptionInfo *relative) |
689 | 0 | { |
690 | 0 | const ExceptionInfo |
691 | 0 | *p; |
692 | |
|
693 | 0 | assert(exception != (ExceptionInfo *) NULL); |
694 | 0 | assert(exception->signature == MagickCoreSignature); |
695 | 0 | assert(relative != (ExceptionInfo *) NULL); |
696 | 0 | assert(relative->signature == MagickCoreSignature); |
697 | 0 | assert(exception != relative); |
698 | 0 | if (relative->exceptions == (void *) NULL) |
699 | 0 | return; |
700 | 0 | LockSemaphoreInfo(relative->semaphore); |
701 | 0 | ResetLinkedListIterator((LinkedListInfo *) relative->exceptions); |
702 | 0 | p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) |
703 | 0 | relative->exceptions); |
704 | 0 | while (p != (const ExceptionInfo *) NULL) |
705 | 0 | { |
706 | 0 | (void) ThrowException(exception,p->severity,p->reason,p->description); |
707 | 0 | p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) |
708 | 0 | relative->exceptions); |
709 | 0 | } |
710 | 0 | UnlockSemaphoreInfo(relative->semaphore); |
711 | 0 | } |
712 | | |
713 | | /* |
714 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
715 | | % % |
716 | | % % |
717 | | % % |
718 | | % I n i t i a l i z e t E x c e p t i o n I n f o % |
719 | | % % |
720 | | % % |
721 | | % % |
722 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
723 | | % |
724 | | % InitializeExceptionInfo() initializes an exception to default values. |
725 | | % |
726 | | % The format of the InitializeExceptionInfo method is: |
727 | | % |
728 | | % void InitializeExceptionInfo(ExceptionInfo *exception) |
729 | | % |
730 | | % A description of each parameter follows: |
731 | | % |
732 | | % o exception: the exception info. |
733 | | % |
734 | | */ |
735 | | MagickPrivate void InitializeExceptionInfo(ExceptionInfo *exception) |
736 | 100M | { |
737 | 100M | assert(exception != (ExceptionInfo *) NULL); |
738 | 100M | (void) memset(exception,0,sizeof(*exception)); |
739 | 100M | exception->severity=UndefinedException; |
740 | 100M | exception->exceptions=(void *) NewLinkedList(0); |
741 | 100M | exception->semaphore=AcquireSemaphoreInfo(); |
742 | 100M | exception->signature=MagickCoreSignature; |
743 | 100M | } |
744 | | |
745 | | /* |
746 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
747 | | % % |
748 | | % % |
749 | | % % |
750 | | % M a g i c k E r r o r % |
751 | | % % |
752 | | % % |
753 | | % % |
754 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
755 | | % |
756 | | % MagickError() calls the exception handler methods with an error reason. |
757 | | % |
758 | | % The format of the MagickError method is: |
759 | | % |
760 | | % void MagickError(const ExceptionType error,const char *reason, |
761 | | % const char *description) |
762 | | % |
763 | | % A description of each parameter follows: |
764 | | % |
765 | | % o exception: Specifies the numeric error category. |
766 | | % |
767 | | % o reason: Specifies the reason to display before terminating the |
768 | | % program. |
769 | | % |
770 | | % o description: Specifies any description to the reason. |
771 | | % |
772 | | */ |
773 | | MagickExport void MagickError(const ExceptionType error,const char *reason, |
774 | | const char *description) |
775 | 71.2k | { |
776 | 71.2k | if (error_handler != (ErrorHandler) NULL) |
777 | 71.2k | (*error_handler)(error,reason,description); |
778 | 71.2k | } |
779 | | |
780 | | /* |
781 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
782 | | % % |
783 | | % % |
784 | | % % |
785 | | % M a g i c k F a t al E r r o r % |
786 | | % % |
787 | | % % |
788 | | % % |
789 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
790 | | % |
791 | | % MagickFatalError() calls the fatal exception handler methods with an error |
792 | | % reason. |
793 | | % |
794 | | % The format of the MagickError method is: |
795 | | % |
796 | | % void MagickFatalError(const ExceptionType error,const char *reason, |
797 | | % const char *description) |
798 | | % |
799 | | % A description of each parameter follows: |
800 | | % |
801 | | % o exception: Specifies the numeric error category. |
802 | | % |
803 | | % o reason: Specifies the reason to display before terminating the |
804 | | % program. |
805 | | % |
806 | | % o description: Specifies any description to the reason. |
807 | | % |
808 | | */ |
809 | | MagickExport void MagickFatalError(const ExceptionType error,const char *reason, |
810 | | const char *description) |
811 | 0 | { |
812 | 0 | if (fatal_error_handler != (FatalErrorHandler) NULL) |
813 | 0 | (*fatal_error_handler)(error,reason,description); |
814 | 0 | MagickCoreTerminus(); |
815 | 0 | exit(1); |
816 | 0 | } |
817 | | |
818 | | /* |
819 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
820 | | % % |
821 | | % % |
822 | | % % |
823 | | % M a g i c k W a r n i n g % |
824 | | % % |
825 | | % % |
826 | | % % |
827 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
828 | | % |
829 | | % MagickWarning() calls the warning handler methods with a warning reason. |
830 | | % |
831 | | % The format of the MagickWarning method is: |
832 | | % |
833 | | % void MagickWarning(const ExceptionType warning,const char *reason, |
834 | | % const char *description) |
835 | | % |
836 | | % A description of each parameter follows: |
837 | | % |
838 | | % o warning: the warning severity. |
839 | | % |
840 | | % o reason: Define the reason for the warning. |
841 | | % |
842 | | % o description: Describe the warning. |
843 | | % |
844 | | */ |
845 | | MagickExport void MagickWarning(const ExceptionType warning,const char *reason, |
846 | | const char *description) |
847 | 717 | { |
848 | 717 | if (warning_handler != (WarningHandler) NULL) |
849 | 717 | (*warning_handler)(warning,reason,description); |
850 | 717 | } |
851 | | |
852 | | /* |
853 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
854 | | % % |
855 | | % % |
856 | | % % |
857 | | % S e t E r r o r H a n d l e r % |
858 | | % % |
859 | | % % |
860 | | % % |
861 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
862 | | % |
863 | | % SetErrorHandler() sets the exception handler to the specified method |
864 | | % and returns the previous exception handler. |
865 | | % |
866 | | % The format of the SetErrorHandler method is: |
867 | | % |
868 | | % ErrorHandler SetErrorHandler(ErrorHandler handler) |
869 | | % |
870 | | % A description of each parameter follows: |
871 | | % |
872 | | % o handler: the method to handle errors. |
873 | | % |
874 | | */ |
875 | | MagickExport ErrorHandler SetErrorHandler(ErrorHandler handler) |
876 | 0 | { |
877 | 0 | ErrorHandler |
878 | 0 | previous_handler; |
879 | |
|
880 | 0 | if (exception_semaphore == (SemaphoreInfo *) NULL) |
881 | 0 | ActivateSemaphoreInfo(&exception_semaphore); |
882 | 0 | LockSemaphoreInfo(exception_semaphore); |
883 | 0 | previous_handler=error_handler; |
884 | 0 | error_handler=handler; |
885 | 0 | UnlockSemaphoreInfo(exception_semaphore); |
886 | 0 | return(previous_handler); |
887 | 0 | } |
888 | | |
889 | | /* |
890 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
891 | | % % |
892 | | % % |
893 | | % % |
894 | | % S e t F a t a l E r r o r H a n d l e r % |
895 | | % % |
896 | | % % |
897 | | % % |
898 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
899 | | % |
900 | | % SetFatalErrorHandler() sets the fatal exception handler to the specified |
901 | | % method and returns the previous fatal exception handler. |
902 | | % |
903 | | % The format of the SetErrorHandler method is: |
904 | | % |
905 | | % ErrorHandler SetErrorHandler(ErrorHandler handler) |
906 | | % |
907 | | % A description of each parameter follows: |
908 | | % |
909 | | % o handler: the method to handle errors. |
910 | | % |
911 | | */ |
912 | | MagickExport FatalErrorHandler SetFatalErrorHandler(FatalErrorHandler handler) |
913 | 592 | { |
914 | 592 | FatalErrorHandler |
915 | 592 | previous_handler; |
916 | | |
917 | 592 | if (exception_semaphore == (SemaphoreInfo *) NULL) |
918 | 0 | ActivateSemaphoreInfo(&exception_semaphore); |
919 | 592 | LockSemaphoreInfo(exception_semaphore); |
920 | 592 | previous_handler=fatal_error_handler; |
921 | 592 | fatal_error_handler=handler; |
922 | 592 | UnlockSemaphoreInfo(exception_semaphore); |
923 | 592 | return(previous_handler); |
924 | 592 | } |
925 | | |
926 | | /* |
927 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
928 | | % % |
929 | | % % |
930 | | % % |
931 | | % S e t W a r n i n g H a n d l e r % |
932 | | % % |
933 | | % % |
934 | | % % |
935 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
936 | | % |
937 | | % SetWarningHandler() sets the warning handler to the specified method |
938 | | % and returns the previous warning handler. |
939 | | % |
940 | | % The format of the SetWarningHandler method is: |
941 | | % |
942 | | % ErrorHandler SetWarningHandler(ErrorHandler handler) |
943 | | % |
944 | | % A description of each parameter follows: |
945 | | % |
946 | | % o handler: the method to handle warnings. |
947 | | % |
948 | | */ |
949 | | MagickExport WarningHandler SetWarningHandler(WarningHandler handler) |
950 | 0 | { |
951 | 0 | WarningHandler |
952 | 0 | previous_handler; |
953 | |
|
954 | 0 | if (exception_semaphore == (SemaphoreInfo *) NULL) |
955 | 0 | ActivateSemaphoreInfo(&exception_semaphore); |
956 | 0 | LockSemaphoreInfo(exception_semaphore); |
957 | 0 | previous_handler=warning_handler; |
958 | 0 | warning_handler=handler; |
959 | 0 | UnlockSemaphoreInfo(exception_semaphore); |
960 | 0 | return(previous_handler); |
961 | 0 | } |
962 | | |
963 | | /* |
964 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
965 | | % % |
966 | | % % |
967 | | % % |
968 | | % T h r o w E x c e p t i o n % |
969 | | % % |
970 | | % % |
971 | | % % |
972 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
973 | | % |
974 | | % ThrowException() throws an exception with the specified severity code, |
975 | | % reason, and optional description. |
976 | | % |
977 | | % The format of the ThrowException method is: |
978 | | % |
979 | | % MagickBooleanType ThrowException(ExceptionInfo *exception, |
980 | | % const ExceptionType severity,const char *reason, |
981 | | % const char *description) |
982 | | % |
983 | | % A description of each parameter follows: |
984 | | % |
985 | | % o exception: the exception info. |
986 | | % |
987 | | % o severity: the severity of the exception. |
988 | | % |
989 | | % o reason: the reason for the exception. |
990 | | % |
991 | | % o description: the exception description. |
992 | | % |
993 | | */ |
994 | | MagickExport MagickBooleanType ThrowException(ExceptionInfo *exception, |
995 | | const ExceptionType severity,const char *reason,const char *description) |
996 | 39.4M | { |
997 | 39.4M | LinkedListInfo |
998 | 39.4M | *exceptions; |
999 | | |
1000 | 39.4M | ExceptionInfo |
1001 | 39.4M | *p; |
1002 | | |
1003 | 39.4M | assert(exception != (ExceptionInfo *) NULL); |
1004 | 39.4M | assert(exception->signature == MagickCoreSignature); |
1005 | 39.4M | LockSemaphoreInfo(exception->semaphore); |
1006 | 39.4M | exceptions=(LinkedListInfo *) exception->exceptions; |
1007 | 39.4M | if (GetNumberOfElementsInLinkedList(exceptions) > MaxExceptionList) |
1008 | 33.4M | { |
1009 | 33.4M | if (severity < ErrorException) |
1010 | 22.9M | { |
1011 | 22.9M | UnlockSemaphoreInfo(exception->semaphore); |
1012 | 22.9M | return(MagickTrue); |
1013 | 22.9M | } |
1014 | 10.5M | p=(ExceptionInfo *) GetLastValueInLinkedList(exceptions); |
1015 | 10.5M | if (p->severity >= ErrorException) |
1016 | 10.4M | { |
1017 | 10.4M | UnlockSemaphoreInfo(exception->semaphore); |
1018 | 10.4M | return(MagickTrue); |
1019 | 10.4M | } |
1020 | 10.5M | } |
1021 | 5.98M | p=(ExceptionInfo *) GetLastValueInLinkedList(exceptions); |
1022 | 5.98M | if ((p != (ExceptionInfo *) NULL) && (p->severity == severity) && |
1023 | 4.59M | (LocaleCompare(exception->reason,reason) == 0) && |
1024 | 1.18M | (LocaleCompare(exception->description,description) == 0)) |
1025 | 1.18M | { |
1026 | 1.18M | UnlockSemaphoreInfo(exception->semaphore); |
1027 | 1.18M | return(MagickTrue); |
1028 | 1.18M | } |
1029 | 4.80M | p=(ExceptionInfo *) AcquireMagickMemory(sizeof(*p)); |
1030 | 4.80M | if (p == (ExceptionInfo *) NULL) |
1031 | 0 | { |
1032 | 0 | UnlockSemaphoreInfo(exception->semaphore); |
1033 | 0 | ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); |
1034 | 0 | } |
1035 | 4.80M | (void) memset(p,0,sizeof(*p)); |
1036 | 4.80M | p->severity=severity; |
1037 | 4.80M | if (reason != (const char *) NULL) |
1038 | 4.80M | p->reason=ConstantString(reason); |
1039 | 4.80M | if (description != (const char *) NULL) |
1040 | 135 | p->description=ConstantString(description); |
1041 | 4.80M | p->signature=MagickCoreSignature; |
1042 | 4.80M | (void) AppendValueToLinkedList(exceptions,p); |
1043 | 4.80M | if (p->severity > exception->severity) |
1044 | 895k | { |
1045 | 895k | exception->severity=p->severity; |
1046 | 895k | exception->reason=p->reason; |
1047 | 895k | exception->description=p->description; |
1048 | 895k | } |
1049 | 4.80M | UnlockSemaphoreInfo(exception->semaphore); |
1050 | 4.80M | if (GetNumberOfElementsInLinkedList(exceptions) == MaxExceptionList) |
1051 | 31.8k | (void) ThrowMagickException(exception,GetMagickModule(), |
1052 | 31.8k | ResourceLimitWarning,"TooManyExceptions", |
1053 | 31.8k | "(exception processing is suspended)"); |
1054 | 4.80M | return(MagickTrue); |
1055 | 4.80M | } |
1056 | | |
1057 | | /* |
1058 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
1059 | | % % |
1060 | | % % |
1061 | | % % |
1062 | | % T h r o w M a g i c k E x c e p t i o n % |
1063 | | % % |
1064 | | % % |
1065 | | % % |
1066 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
1067 | | % |
1068 | | % ThrowMagickException logs an exception as determined by the log |
1069 | | % configuration file. If an error occurs, MagickFalse is returned |
1070 | | % otherwise MagickTrue. |
1071 | | % |
1072 | | % The format of the ThrowMagickException method is: |
1073 | | % |
1074 | | % MagickBooleanType ThrowFileException(ExceptionInfo *exception, |
1075 | | % const char *module,const char *function,const size_t line, |
1076 | | % const ExceptionType severity,const char *tag,const char *format,...) |
1077 | | % |
1078 | | % A description of each parameter follows: |
1079 | | % |
1080 | | % o exception: the exception info. |
1081 | | % |
1082 | | % o filename: the source module filename. |
1083 | | % |
1084 | | % o function: the function name. |
1085 | | % |
1086 | | % o line: the line number of the source module. |
1087 | | % |
1088 | | % o severity: Specifies the numeric error category. |
1089 | | % |
1090 | | % o tag: the locale tag. |
1091 | | % |
1092 | | % o format: the output format. |
1093 | | % |
1094 | | */ |
1095 | | |
1096 | | MagickExport MagickBooleanType ThrowMagickExceptionList( |
1097 | | ExceptionInfo *exception,const char *module,const char *function, |
1098 | | const size_t line,const ExceptionType severity,const char *tag, |
1099 | | const char *format,va_list operands) |
1100 | 39.4M | { |
1101 | 39.4M | char |
1102 | 39.4M | message[MagickPathExtent], |
1103 | 39.4M | path[MagickPathExtent], |
1104 | 39.4M | reason[MagickPathExtent]; |
1105 | | |
1106 | 39.4M | const char |
1107 | 39.4M | *locale, |
1108 | 39.4M | *type; |
1109 | | |
1110 | 39.4M | int |
1111 | 39.4M | n; |
1112 | | |
1113 | 39.4M | MagickBooleanType |
1114 | 39.4M | status; |
1115 | | |
1116 | 39.4M | size_t |
1117 | 39.4M | length; |
1118 | | |
1119 | 39.4M | assert(exception != (ExceptionInfo *) NULL); |
1120 | 39.4M | assert(exception->signature == MagickCoreSignature); |
1121 | 39.4M | locale=GetLocaleExceptionMessage(severity,tag); |
1122 | 39.4M | (void) CopyMagickString(reason,locale,MagickPathExtent); |
1123 | 39.4M | (void) ConcatenateMagickString(reason," ",MagickPathExtent); |
1124 | 39.4M | length=strlen(reason); |
1125 | 39.4M | #if defined(MAGICKCORE_HAVE_VSNPRINTF) |
1126 | 39.4M | n=vsnprintf(reason+length,MagickPathExtent-length,format,operands); |
1127 | | #else |
1128 | | n=vsprintf(reason+length,format,operands); |
1129 | | #endif |
1130 | 39.4M | if (n < 0) |
1131 | 0 | reason[MagickPathExtent-1]='\0'; |
1132 | 39.4M | status=LogMagickEvent(ExceptionEvent,module,function,line,"%s",reason); |
1133 | 39.4M | GetPathComponent(module,TailPath,path); |
1134 | 39.4M | type="undefined"; |
1135 | 39.4M | if ((severity >= WarningException) && (severity < ErrorException)) |
1136 | 27.3M | type="warning"; |
1137 | 39.4M | if ((severity >= ErrorException) && (severity < FatalErrorException)) |
1138 | 12.1M | type="error"; |
1139 | 39.4M | if (severity >= FatalErrorException) |
1140 | 0 | type="fatal"; |
1141 | 39.4M | (void) FormatLocaleString(message,MagickPathExtent,"%s @ %s/%s/%s/%.20g", |
1142 | 39.4M | reason,type,path,function,(double) line); |
1143 | 39.4M | (void) ThrowException(exception,severity,message,(char *) NULL); |
1144 | 39.4M | return(status); |
1145 | 39.4M | } |
1146 | | |
1147 | | MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, |
1148 | | const char *module,const char *function,const size_t line, |
1149 | | const ExceptionType severity,const char *tag,const char *format,...) |
1150 | 39.4M | { |
1151 | 39.4M | MagickBooleanType |
1152 | 39.4M | status; |
1153 | | |
1154 | 39.4M | va_list |
1155 | 39.4M | operands; |
1156 | | |
1157 | 39.4M | va_start(operands,format); |
1158 | 39.4M | status=ThrowMagickExceptionList(exception,module,function,line,severity,tag, |
1159 | 39.4M | format,operands); |
1160 | | va_end(operands); |
1161 | 39.4M | return(status); |
1162 | 39.4M | } |