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