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