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