]> granicus.if.org Git - imagemagick/blob - magick/exception.c
(no commit message)
[imagemagick] / magick / exception.c
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 %                               John Cristy                                   %
17 %                                July 1993                                    %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2010 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 %    http://www.imagemagick.org/script/license.php                            %
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 \f
40 /*
41   Include declarations.
42 */
43 #include "magick/studio.h"
44 #include "magick/client.h"
45 #include "magick/exception.h"
46 #include "magick/exception-private.h"
47 #include "magick/hashmap.h"
48 #include "magick/locale_.h"
49 #include "magick/log.h"
50 #include "magick/magick.h"
51 #include "magick/memory_.h"
52 #include "magick/string_.h"
53 #include "magick/utility.h"
54 \f
55 /*
56   Forward declarations.
57 */
58 #if defined(__cplusplus) || defined(c_plusplus)
59 extern "C" {
60 #endif
61
62 static void
63   DefaultErrorHandler(const ExceptionType,const char *,const char *),
64   DefaultFatalErrorHandler(const ExceptionType,const char *,const char *),
65   DefaultWarningHandler(const ExceptionType,const char *,const char *);
66
67 #if defined(__cplusplus) || defined(c_plusplus)
68 }
69 #endif
70 \f
71 /*
72   Global declarations.
73 */
74 static ErrorHandler
75   error_handler = DefaultErrorHandler;
76
77 static FatalErrorHandler
78   fatal_error_handler = DefaultFatalErrorHandler;
79
80 static WarningHandler
81   warning_handler = DefaultWarningHandler;
82 \f
83 /*
84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85 %                                                                             %
86 %                                                                             %
87 %                                                                             %
88 %   A c q u i r e E x c e p t i o n I n f o                                   %
89 %                                                                             %
90 %                                                                             %
91 %                                                                             %
92 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93 %
94 %  AcquireExceptionInfo() allocates the ExceptionInfo structure.
95 %
96 %  The format of the AcquireExceptionInfo method is:
97 %
98 %      ExceptionInfo *AcquireExceptionInfo(void)
99 %
100 */
101 MagickExport ExceptionInfo *AcquireExceptionInfo(void)
102 {
103   ExceptionInfo
104     *exception;
105
106   exception=(ExceptionInfo *) AcquireAlignedMemory(1,sizeof(*exception));
107   if (exception == (ExceptionInfo *) NULL)
108     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
109   GetExceptionInfo(exception);
110   exception->relinquish=MagickTrue;
111   return(exception);
112 }
113 \f
114 /*
115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116 %                                                                             %
117 %                                                                             %
118 %                                                                             %
119 %   C l e a r M a g i c k E x c e p t i o n                                   %
120 %                                                                             %
121 %                                                                             %
122 %                                                                             %
123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124 %
125 %  ClearMagickException() clears any exception that may not have been caught
126 %  yet.
127 %
128 %  The format of the ClearMagickException method is:
129 %
130 %      ClearMagickException(ExceptionInfo *exception)
131 %
132 %  A description of each parameter follows:
133 %
134 %    o exception: the exception info.
135 %
136 */
137
138 static void *DestroyExceptionElement(void *exception)
139 {
140   register ExceptionInfo
141     *p;
142
143   p=(ExceptionInfo *) exception;
144   if (p->reason != (char *) NULL)
145     p->reason=DestroyString(p->reason);
146   if (p->description != (char *) NULL)
147     p->description=DestroyString(p->description);
148   p=(ExceptionInfo *) RelinquishMagickMemory(p);
149   return((void *) NULL);
150 }
151
152 MagickExport void ClearMagickException(ExceptionInfo *exception)
153 {
154   register ExceptionInfo
155     *p;
156
157   assert(exception != (ExceptionInfo *) NULL);
158   assert(exception->signature == MagickSignature);
159   if (exception->exceptions  == (void *) NULL)
160     return;
161   LockSemaphoreInfo(exception->semaphore);
162   p=(ExceptionInfo *) RemoveLastElementFromLinkedList((LinkedListInfo *)
163     exception->exceptions);
164   while (p != (ExceptionInfo *) NULL)
165   {
166     (void) DestroyExceptionElement(p);
167     p=(ExceptionInfo *) RemoveLastElementFromLinkedList((LinkedListInfo *)
168       exception->exceptions);
169   }
170   exception->severity=UndefinedException;
171   exception->reason=(char *) NULL;
172   exception->description=(char *) NULL;
173   UnlockSemaphoreInfo(exception->semaphore);
174   errno=0;
175 }
176 \f
177 /*
178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179 %                                                                             %
180 %                                                                             %
181 %                                                                             %
182 %   C a t c h E x c e p t i o n                                               %
183 %                                                                             %
184 %                                                                             %
185 %                                                                             %
186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187 %
188 %  CatchException() returns if no exceptions is found otherwise it reports
189 %  the exception as a warning, error, or fatal depending on the severity.
190 %
191 %  The format of the CatchException method is:
192 %
193 %      CatchException(ExceptionInfo *exception)
194 %
195 %  A description of each parameter follows:
196 %
197 %    o exception: the exception info.
198 %
199 */
200 MagickExport void CatchException(ExceptionInfo *exception)
201 {
202   register const ExceptionInfo
203     *p;
204
205   assert(exception != (ExceptionInfo *) NULL);
206   assert(exception->signature == MagickSignature);
207   if (exception->exceptions  == (void *) NULL)
208     return;
209   LockSemaphoreInfo(exception->semaphore);
210   ResetLinkedListIterator((LinkedListInfo *) exception->exceptions);
211   p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
212     exception->exceptions);
213   while (p != (const ExceptionInfo *) NULL)
214   {
215     if ((p->severity >= WarningException) && (p->severity < ErrorException))
216       MagickWarning(p->severity,p->reason,p->description);
217     if ((p->severity >= ErrorException) && (p->severity < FatalErrorException))
218       MagickError(p->severity,p->reason,p->description);
219     if (exception->severity >= FatalErrorException)
220       MagickFatalError(p->severity,p->reason,p->description);
221     p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
222       exception->exceptions);
223   }
224   UnlockSemaphoreInfo(exception->semaphore);
225   ClearMagickException(exception);
226 }
227 \f
228 /*
229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230 %                                                                             %
231 %                                                                             %
232 %                                                                             %
233 +   D e f a u l t E r r o r H a n d l e r                                     %
234 %                                                                             %
235 %                                                                             %
236 %                                                                             %
237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238 %
239 %  DefaultErrorHandler() displays an error reason.
240 %
241 %  The format of the DefaultErrorHandler method is:
242 %
243 %      void MagickError(const ExceptionType severity,const char *reason,
244 %        const char *description)
245 %
246 %  A description of each parameter follows:
247 %
248 %    o severity: Specifies the numeric error category.
249 %
250 %    o reason: Specifies the reason to display before terminating the
251 %      program.
252 %
253 %    o description: Specifies any description to the reason.
254 %
255 */
256 static void DefaultErrorHandler(const ExceptionType magick_unused(severity),
257   const char *reason,const char *description)
258 {
259   if (reason == (char *) NULL)
260     return;
261   (void) fprintf(stderr,"%s: %s",GetClientName(),reason);
262   if (description != (char *) NULL)
263     (void) fprintf(stderr," (%s)",description);
264   (void) fprintf(stderr,".\n");
265   (void) fflush(stderr);
266 }
267 \f
268 /*
269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270 %                                                                             %
271 %                                                                             %
272 %                                                                             %
273 +   D e f a u l t F a t a l E r r o r H a n d l e r                           %
274 %                                                                             %
275 %                                                                             %
276 %                                                                             %
277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278 %
279 %  DefaultFatalErrorHandler() displays an error reason and then terminates the
280 %  program.
281 %
282 %  The format of the DefaultFatalErrorHandler method is:
283 %
284 %      void MagickFatalError(const ExceptionType severity,const char *reason,
285 %        const char *description)
286 %
287 %  A description of each parameter follows:
288 %
289 %    o severity: Specifies the numeric error category.
290 %
291 %    o reason: Specifies the reason to display before terminating the
292 %      program.
293 %
294 %    o description: Specifies any description to the reason.
295 %
296 */
297 static void DefaultFatalErrorHandler(
298   const ExceptionType magick_unused(severity),
299   const char *reason,const char *description)
300 {
301   if (reason == (char *) NULL)
302     return;
303   (void) fprintf(stderr,"%s: %s",GetClientName(),reason);
304   if (description != (char *) NULL)
305     (void) fprintf(stderr," (%s)",description);
306   (void) fprintf(stderr,".\n");
307   (void) fflush(stderr);
308   MagickCoreTerminus();
309   exit(1);
310 }
311 \f
312 /*
313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314 %                                                                             %
315 %                                                                             %
316 %                                                                             %
317 +   D e f a u l t W a r n i n g H a n d l e r                                 %
318 %                                                                             %
319 %                                                                             %
320 %                                                                             %
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322 %
323 %  DefaultWarningHandler() displays a warning reason.
324 %
325 %  The format of the DefaultWarningHandler method is:
326 %
327 %      void DefaultWarningHandler(const ExceptionType severity,
328 %        const char *reason,const char *description)
329 %
330 %  A description of each parameter follows:
331 %
332 %    o severity: Specifies the numeric warning category.
333 %
334 %    o reason: Specifies the reason to display before terminating the
335 %      program.
336 %
337 %    o description: Specifies any description to the reason.
338 %
339 */
340 static void DefaultWarningHandler(const ExceptionType magick_unused(severity),
341   const char *reason,const char *description)
342 {
343   if (reason == (char *) NULL)
344     return;
345   (void) fprintf(stderr,"%s: %s",GetClientName(),reason);
346   if (description != (char *) NULL)
347     (void) fprintf(stderr," (%s)",description);
348   (void) fprintf(stderr,".\n");
349   (void) fflush(stderr);
350 }
351 \f
352 /*
353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
354 %                                                                             %
355 %                                                                             %
356 %                                                                             %
357 %   D e s t r o y E x c e p t i o n I n f o                                   %
358 %                                                                             %
359 %                                                                             %
360 %                                                                             %
361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
362 %
363 %  DestroyExceptionInfo() deallocates memory associated with an exception.
364 %
365 %  The format of the DestroyExceptionInfo method is:
366 %
367 %      ExceptionInfo *DestroyExceptionInfo(ExceptionInfo *exception)
368 %
369 %  A description of each parameter follows:
370 %
371 %    o exception: the exception info.
372 %
373 */
374 MagickExport ExceptionInfo *DestroyExceptionInfo(ExceptionInfo *exception)
375 {
376   MagickBooleanType
377     relinquish;
378
379   assert(exception != (ExceptionInfo *) NULL);
380   assert(exception->signature == MagickSignature);
381   if (exception->semaphore == (SemaphoreInfo *) NULL)
382     AcquireSemaphoreInfo(&exception->semaphore);
383   LockSemaphoreInfo(exception->semaphore);
384   exception->severity=UndefinedException;
385   if (exception->exceptions != (void *) NULL)
386     exception->exceptions=(void *) DestroyLinkedList((LinkedListInfo *)
387       exception->exceptions,DestroyExceptionElement);
388   relinquish=exception->relinquish;
389   if (exception->relinquish != MagickFalse)
390     exception->signature=(~MagickSignature);
391   UnlockSemaphoreInfo(exception->semaphore);
392   DestroySemaphoreInfo(&exception->semaphore);
393   if (relinquish != MagickFalse)
394     exception=(ExceptionInfo *) RelinquishMagickMemory(exception);
395   return(exception);
396 }
397 \f
398 /*
399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400 %                                                                             %
401 %                                                                             %
402 %                                                                             %
403 %   G e t E x c e p t i o n I n f o                                           %
404 %                                                                             %
405 %                                                                             %
406 %                                                                             %
407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 %
409 %  GetExceptionInfo() initializes an exception to default values.
410 %
411 %  The format of the GetExceptionInfo method is:
412 %
413 %      GetExceptionInfo(ExceptionInfo *exception)
414 %
415 %  A description of each parameter follows:
416 %
417 %    o exception: the exception info.
418 %
419 */
420 MagickExport void GetExceptionInfo(ExceptionInfo *exception)
421 {
422   assert(exception != (ExceptionInfo *) NULL);
423   (void) ResetMagickMemory(exception,0,sizeof(*exception));
424   exception->severity=UndefinedException;
425   exception->exceptions=(void *) NewLinkedList(0);
426   exception->semaphore=AllocateSemaphoreInfo();
427   exception->signature=MagickSignature;
428 }
429 \f
430 /*
431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432 %                                                                             %
433 %                                                                             %
434 %                                                                             %
435 %   G e t E x c e p t i o n M e s s a g e                                     %
436 %                                                                             %
437 %                                                                             %
438 %                                                                             %
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440 %
441 %  GetExceptionMessage() returns the error message defined by the specified
442 %  error code.
443 %
444 %  The format of the GetExceptionMessage method is:
445 %
446 %      char *GetExceptionMessage(const int error)
447 %
448 %  A description of each parameter follows:
449 %
450 %    o error: the error code.
451 %
452 */
453 MagickExport char *GetExceptionMessage(const int error)
454 {
455   char
456     exception[MaxTextExtent];
457
458 #if defined(MAGICKCORE_HAVE_STRERROR_R)
459   (void) strerror_r(error,exception,sizeof(exception));
460 #else
461   (void) CopyMagickString(exception,strerror(error),sizeof(exception));
462 #endif
463   return(ConstantString(exception));
464 }
465 \f
466 /*
467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
468 %                                                                             %
469 %                                                                             %
470 %                                                                             %
471 %   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                         %
472 %                                                                             %
473 %                                                                             %
474 %                                                                             %
475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
476 %
477 %  GetLocaleExceptionMessage() converts a enumerated exception severity and tag
478 %  to a message in the current locale.
479 %
480 %  The format of the GetLocaleExceptionMessage method is:
481 %
482 %      const char *GetLocaleExceptionMessage(const ExceptionType severity,
483 %        const char *tag)
484 %
485 %  A description of each parameter follows:
486 %
487 %    o severity: the severity of the exception.
488 %
489 %    o tag: the message tag.
490 %
491 */
492
493 static const char *ExceptionSeverityToTag(const ExceptionType severity)
494 {
495   switch (severity)
496   {
497     case ResourceLimitWarning: return("Resource/Limit/Warning/");
498     case TypeWarning: return("Type/Warning/");
499     case OptionWarning: return("Option/Warning/");
500     case DelegateWarning: return("Delegate/Warning/");
501     case MissingDelegateWarning: return("Missing/Delegate/Warning/");
502     case CorruptImageWarning: return("Corrupt/Image/Warning/");
503     case FileOpenWarning: return("File/Open/Warning/");
504     case BlobWarning: return("Blob/Warning/");
505     case StreamWarning: return("Stream/Warning/");
506     case CacheWarning: return("Cache/Warning/");
507     case CoderWarning: return("Coder/Warning/");
508     case FilterWarning: return("Filter/Warning/");
509     case ModuleWarning: return("Module/Warning/");
510     case DrawWarning: return("Draw/Warning/");
511     case ImageWarning: return("Image/Warning/");
512     case WandWarning: return("Wand/Warning/");
513     case XServerWarning: return("XServer/Warning/");
514     case MonitorWarning: return("Monitor/Warning/");
515     case RegistryWarning: return("Registry/Warning/");
516     case ConfigureWarning: return("Configure/Warning/");
517     case PolicyWarning: return("Policy/Warning/");
518     case ResourceLimitError: return("Resource/Limit/Error/");
519     case TypeError: return("Type/Error/");
520     case OptionError: return("Option/Error/");
521     case DelegateError: return("Delegate/Error/");
522     case MissingDelegateError: return("Missing/Delegate/Error/");
523     case CorruptImageError: return("Corrupt/Image/Error/");
524     case FileOpenError: return("File/Open/Error/");
525     case BlobError: return("Blob/Error/");
526     case StreamError: return("Stream/Error/");
527     case CacheError: return("Cache/Error/");
528     case CoderError: return("Coder/Error/");
529     case FilterError: return("Filter/Error/");
530     case ModuleError: return("Module/Error/");
531     case DrawError: return("Draw/Error/");
532     case ImageError: return("Image/Error/");
533     case WandError: return("Wand/Error/");
534     case XServerError: return("XServer/Error/");
535     case MonitorError: return("Monitor/Error/");
536     case RegistryError: return("Registry/Error/");
537     case ConfigureError: return("Configure/Error/");
538     case PolicyError: return("Policy/Error/");
539     case ResourceLimitFatalError: return("Resource/Limit/FatalError/");
540     case TypeFatalError: return("Type/FatalError/");
541     case OptionFatalError: return("Option/FatalError/");
542     case DelegateFatalError: return("Delegate/FatalError/");
543     case MissingDelegateFatalError: return("Missing/Delegate/FatalError/");
544     case CorruptImageFatalError: return("Corrupt/Image/FatalError/");
545     case FileOpenFatalError: return("File/Open/FatalError/");
546     case BlobFatalError: return("Blob/FatalError/");
547     case StreamFatalError: return("Stream/FatalError/");
548     case CacheFatalError: return("Cache/FatalError/");
549     case CoderFatalError: return("Coder/FatalError/");
550     case FilterFatalError: return("Filter/FatalError/");
551     case ModuleFatalError: return("Module/FatalError/");
552     case DrawFatalError: return("Draw/FatalError/");
553     case ImageFatalError: return("Image/FatalError/");
554     case WandFatalError: return("Wand/FatalError/");
555     case XServerFatalError: return("XServer/FatalError/");
556     case MonitorFatalError: return("Monitor/FatalError/");
557     case RegistryFatalError: return("Registry/FatalError/");
558     case ConfigureFatalError: return("Configure/FatalError/");
559     case PolicyFatalError: return("Policy/FatalError/");
560     default: break;
561   }
562   return("");
563 }
564
565 MagickExport const char *GetLocaleExceptionMessage(const ExceptionType severity,
566   const char *tag)
567 {
568   char
569     message[MaxTextExtent];
570
571   const char
572     *locale_message;
573
574   assert(tag != (const char *) NULL);
575   (void) FormatMagickString(message,MaxTextExtent,"Exception/%s%s",
576     ExceptionSeverityToTag(severity),tag);
577   locale_message=GetLocaleMessage(message);
578   if (locale_message == (const char *) NULL)
579     return(tag);
580   if (locale_message == message)
581     return(tag);
582   return(locale_message);
583 }
584 \f
585 /*
586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587 %                                                                             %
588 %                                                                             %
589 %                                                                             %
590 %   I n h e r i t E x c e p t i o n                                           %
591 %                                                                             %
592 %                                                                             %
593 %                                                                             %
594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
595 %
596 %  InheritException() inherits an exception from a related exception.
597 %
598 %  The format of the InheritException method is:
599 %
600 %      InheritException(ExceptionInfo *exception,const ExceptionInfo *relative)
601 %
602 %  A description of each parameter follows:
603 %
604 %    o exception: the exception info.
605 %
606 %    o relative: the related exception info.
607 %
608 */
609 MagickExport void InheritException(ExceptionInfo *exception,
610   const ExceptionInfo *relative)
611 {
612   register const ExceptionInfo
613     *p;
614
615   assert(exception != (ExceptionInfo *) NULL);
616   assert(exception->signature == MagickSignature);
617   assert(relative != (ExceptionInfo *) NULL);
618   assert(relative->signature == MagickSignature);
619   if (relative->exceptions == (void *) NULL)
620     return;
621   LockSemaphoreInfo(exception->semaphore);
622   ResetLinkedListIterator((LinkedListInfo *) relative->exceptions);
623   p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
624     relative->exceptions);
625   while (p != (const ExceptionInfo *) NULL)
626   {
627     (void) ThrowException(exception,p->severity,p->reason,p->description);
628     p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
629       relative->exceptions);
630   }
631   UnlockSemaphoreInfo(exception->semaphore);
632 }
633 \f
634 /*
635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636 %                                                                             %
637 %                                                                             %
638 %                                                                             %
639 %   M a g i c k E r r o r                                                     %
640 %                                                                             %
641 %                                                                             %
642 %                                                                             %
643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644 %
645 %  MagickError() calls the exception handler methods with an error reason.
646 %
647 %  The format of the MagickError method is:
648 %
649 %      void MagickError(const ExceptionType error,const char *reason,
650 %        const char *description)
651 %
652 %  A description of each parameter follows:
653 %
654 %    o exception: Specifies the numeric error category.
655 %
656 %    o reason: Specifies the reason to display before terminating the
657 %      program.
658 %
659 %    o description: Specifies any description to the reason.
660 %
661 */
662 MagickExport void MagickError(const ExceptionType error,const char *reason,
663   const char *description)
664 {
665   if (error_handler != (ErrorHandler) NULL)
666     (*error_handler)(error,reason,description);
667 }
668 \f
669 /*
670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671 %                                                                             %
672 %                                                                             %
673 %                                                                             %
674 %   M a g i c k F a t al E r r o r                                            %
675 %                                                                             %
676 %                                                                             %
677 %                                                                             %
678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 %
680 %  MagickFatalError() calls the fatal exception handler methods with an error
681 %  reason.
682 %
683 %  The format of the MagickError method is:
684 %
685 %      void MagickFatalError(const ExceptionType error,const char *reason,
686 %        const char *description)
687 %
688 %  A description of each parameter follows:
689 %
690 %    o exception: Specifies the numeric error category.
691 %
692 %    o reason: Specifies the reason to display before terminating the
693 %      program.
694 %
695 %    o description: Specifies any description to the reason.
696 %
697 */
698 MagickExport void MagickFatalError(const ExceptionType error,const char *reason,
699   const char *description)
700 {
701   if (fatal_error_handler != (ErrorHandler) NULL)
702     (*fatal_error_handler)(error,reason,description);
703 }
704 \f
705 /*
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707 %                                                                             %
708 %                                                                             %
709 %                                                                             %
710 %   M a g i c k W a r n i n g                                                 %
711 %                                                                             %
712 %                                                                             %
713 %                                                                             %
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715 %
716 %  MagickWarning() calls the warning handler methods with a warning reason.
717 %
718 %  The format of the MagickWarning method is:
719 %
720 %      void MagickWarning(const ExceptionType warning,const char *reason,
721 %        const char *description)
722 %
723 %  A description of each parameter follows:
724 %
725 %    o warning: the warning severity.
726 %
727 %    o reason: Define the reason for the warning.
728 %
729 %    o description: Describe the warning.
730 %
731 */
732 MagickExport void MagickWarning(const ExceptionType warning,const char *reason,
733   const char *description)
734 {
735   if (warning_handler != (WarningHandler) NULL)
736     (*warning_handler)(warning,reason,description);
737 }
738 \f
739 /*
740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741 %                                                                             %
742 %                                                                             %
743 %                                                                             %
744 %   S e t E r r o r H a n d l e r                                             %
745 %                                                                             %
746 %                                                                             %
747 %                                                                             %
748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
749 %
750 %  SetErrorHandler() sets the exception handler to the specified method
751 %  and returns the previous exception handler.
752 %
753 %  The format of the SetErrorHandler method is:
754 %
755 %      ErrorHandler SetErrorHandler(ErrorHandler handler)
756 %
757 %  A description of each parameter follows:
758 %
759 %    o handler: the method to handle errors.
760 %
761 */
762 MagickExport ErrorHandler SetErrorHandler(ErrorHandler handler)
763 {
764   ErrorHandler
765     previous_handler;
766
767   previous_handler=error_handler;
768   error_handler=handler;
769   return(previous_handler);
770 }
771 \f
772 /*
773 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
774 %                                                                             %
775 %                                                                             %
776 %                                                                             %
777 %   S e t F a t a l E r r o r H a n d l e r                                   %
778 %                                                                             %
779 %                                                                             %
780 %                                                                             %
781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
782 %
783 %  SetFatalErrorHandler() sets the fatal exception handler to the specified
784 %  method and returns the previous fatal exception handler.
785 %
786 %  The format of the SetErrorHandler method is:
787 %
788 %      ErrorHandler SetErrorHandler(ErrorHandler handler)
789 %
790 %  A description of each parameter follows:
791 %
792 %    o handler: the method to handle errors.
793 %
794 */
795 MagickExport FatalErrorHandler SetFatalErrorHandler(FatalErrorHandler handler)
796 {
797   FatalErrorHandler
798     previous_handler;
799
800   previous_handler=fatal_error_handler;
801   fatal_error_handler=handler;
802   return(previous_handler);
803 }
804 \f
805 /*
806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
807 %                                                                             %
808 %                                                                             %
809 %                                                                             %
810 %   S e t W a r n i n g H a n d l e r                                         %
811 %                                                                             %
812 %                                                                             %
813 %                                                                             %
814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
815 %
816 %  SetWarningHandler() sets the warning handler to the specified method
817 %  and returns the previous warning handler.
818 %
819 %  The format of the SetWarningHandler method is:
820 %
821 %      ErrorHandler SetWarningHandler(ErrorHandler handler)
822 %
823 %  A description of each parameter follows:
824 %
825 %    o handler: the method to handle warnings.
826 %
827 */
828 MagickExport WarningHandler SetWarningHandler(WarningHandler handler)
829 {
830   WarningHandler
831     previous_handler;
832
833   previous_handler=warning_handler;
834   warning_handler=handler;
835   return(previous_handler);
836 }
837 \f
838 /*
839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
840 %                                                                             %
841 %                                                                             %
842 %                                                                             %
843 %   T h r o w E x c e p t i o n                                               %
844 %                                                                             %
845 %                                                                             %
846 %                                                                             %
847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
848 %
849 %  ThrowException() throws an exception with the specified severity code,
850 %  reason, and optional description.
851 %
852 %  The format of the ThrowException method is:
853 %
854 %      MagickBooleanType ThrowException(ExceptionInfo *exception,
855 %        const ExceptionType severity,const char *reason,
856 %        const char *description)
857 %
858 %  A description of each parameter follows:
859 %
860 %    o exception: the exception info.
861 %
862 %    o severity: the severity of the exception.
863 %
864 %    o reason: the reason for the exception.
865 %
866 %    o description: the exception description.
867 %
868 */
869 MagickExport MagickBooleanType ThrowException(ExceptionInfo *exception,
870   const ExceptionType severity,const char *reason,const char *description)
871 {
872   register ExceptionInfo
873     *p;
874
875   assert(exception != (ExceptionInfo *) NULL);
876   assert(exception->signature == MagickSignature);
877   p=(ExceptionInfo *) GetLastValueInLinkedList((LinkedListInfo *)
878     exception->exceptions);
879   if ((p != (ExceptionInfo *) NULL) && (p->severity == severity) &&
880       (LocaleCompare(exception->reason,reason) == 0) &&
881       (LocaleCompare(exception->description,description) == 0))
882     return(MagickTrue);
883   p=(ExceptionInfo *) AcquireAlignedMemory(1,sizeof(*p));
884   if (p == (ExceptionInfo *) NULL)
885     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
886   (void) ResetMagickMemory(p,0,sizeof(*p));
887   p->severity=severity;
888   if (reason != (const char *) NULL)
889     p->reason=ConstantString(reason);
890   if (description != (const char *) NULL)
891     p->description=ConstantString(description);
892   p->signature=MagickSignature;
893   (void) AppendValueToLinkedList((LinkedListInfo *) exception->exceptions,p);
894   exception->severity=p->severity;
895   exception->reason=p->reason;
896   exception->description=p->description;
897   return(MagickTrue);
898 }
899 \f
900 /*
901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
902 %                                                                             %
903 %                                                                             %
904 %                                                                             %
905 %   T h r o w M a g i c k E x c e p t i o n                                   %
906 %                                                                             %
907 %                                                                             %
908 %                                                                             %
909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
910 %
911 %  ThrowMagickException logs an exception as determined by the log configuration
912 %  file.  If an error occurs, MagickFalse is returned otherwise MagickTrue.
913 %
914 %  The format of the ThrowMagickException method is:
915 %
916 %      MagickBooleanType ThrowFileException(ExceptionInfo *exception,
917 %        const char *module,const char *function,const unsigned long line,
918 %        const ExceptionType severity,const char *tag,const char *format,...)
919 %
920 %  A description of each parameter follows:
921 %
922 %    o exception: the exception info.
923 %
924 %    o filename: the source module filename.
925 %
926 %    o function: the function name.
927 %
928 %    o line: the line number of the source module.
929 %
930 %    o severity: Specifies the numeric error category.
931 %
932 %    o tag: the locale tag.
933 %
934 %    o format: the output format.
935 %
936 */
937
938 MagickExport MagickBooleanType ThrowMagickExceptionList(
939   ExceptionInfo *exception,const char *module,const char *function,
940   const unsigned long line,const ExceptionType severity,const char *tag,
941   const char *format,va_list operands)
942 {
943   char
944     message[MaxTextExtent],
945     path[MaxTextExtent],
946     reason[MaxTextExtent];
947
948   const char
949     *locale;
950
951   int
952     n;
953
954   MagickBooleanType
955     status;
956
957   size_t
958     length;
959
960   assert(exception != (ExceptionInfo *) NULL);
961   assert(exception->signature == MagickSignature);
962   locale=GetLocaleExceptionMessage(severity,tag);
963   (void) CopyMagickString(reason,locale,MaxTextExtent);
964   (void) ConcatenateMagickString(reason," ",MaxTextExtent);
965   length=strlen(reason);
966 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
967   n=vsnprintf(reason+length,MaxTextExtent-length,format,operands);
968 #else
969   n=vsprintf(reason+length,format,operands);
970 #endif
971   if (n < 0)
972     reason[MaxTextExtent-1]='\0';
973   status=LogMagickEvent(ExceptionEvent,module,function,line,"%s",reason);
974   GetPathComponent(module,TailPath,path);
975   (void) FormatMagickString(message,MaxTextExtent,"%s @ %s/%s/%ld",reason,path,
976     function,line);
977   (void) ThrowException(exception,severity,message,(char *) NULL);
978   return(status);
979 }
980
981 MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception,
982   const char *module,const char *function,const unsigned long line,
983   const ExceptionType severity,const char *tag,const char *format,...)
984 {
985   MagickBooleanType
986     status;
987
988   va_list
989     operands;
990
991   va_start(operands,format);
992   status=ThrowMagickExceptionList(exception,module,function,line,severity,tag,
993     format,operands);
994   va_end(operands);
995   return(status);
996 }