blob: e7d4d5a92cd8148f4443047a7cd9de870184fa60 [file] [log] [blame]
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% EEEEE X X CCCC EEEEE PPPP TTTTT IIIII OOO N N %
% E X X C E P P T I O O NN N %
% EEE X C EEE PPPP T I O O N N N %
% E X X C E P T I O O N NN %
% EEEEE X X CCCC EEEEE P T IIIII OOO N N %
% %
% %
% MagickCore Exception Methods %
% %
% Software Design %
% Cristy %
% July 1993 %
% %
% %
% Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
% obtain a copy of the License at %
% %
% https://imagemagick.org/script/license.php %
% %
% Unless required by applicable law or agreed to in writing, software %
% distributed under the License is distributed on an "AS IS" BASIS, %
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
% See the License for the specific language governing permissions and %
% limitations under the License. %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
%
*/
/*
Include declarations.
*/
#include "MagickCore/studio.h"
#include "MagickCore/client.h"
#include "MagickCore/exception.h"
#include "MagickCore/exception-private.h"
#include "MagickCore/linked-list.h"
#include "MagickCore/locale_.h"
#include "MagickCore/log.h"
#include "MagickCore/magick.h"
#include "MagickCore/memory_.h"
#include "MagickCore/memory-private.h"
#include "MagickCore/string_.h"
#include "MagickCore/utility.h"
#include "MagickCore/utility-private.h"
/*
Define declarations.
*/
#define MaxExceptionList 64
/*
Forward declarations.
*/
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
static void
DefaultErrorHandler(const ExceptionType,const char *,const char *),
DefaultFatalErrorHandler(const ExceptionType,const char *,const char *),
DefaultWarningHandler(const ExceptionType,const char *,const char *);
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
/*
Global declarations.
*/
static ErrorHandler
error_handler = DefaultErrorHandler;
static FatalErrorHandler
fatal_error_handler = DefaultFatalErrorHandler;
static WarningHandler
warning_handler = DefaultWarningHandler;
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% A c q u i r e E x c e p t i o n I n f o %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% AcquireExceptionInfo() allocates the ExceptionInfo structure.
%
% The format of the AcquireExceptionInfo method is:
%
% ExceptionInfo *AcquireExceptionInfo(void)
%
*/
MagickExport ExceptionInfo *AcquireExceptionInfo(void)
{
ExceptionInfo
*exception;
exception=(ExceptionInfo *) AcquireCriticalMemory(sizeof(*exception));
InitializeExceptionInfo(exception);
exception->relinquish=MagickTrue;
return(exception);
}
/*l
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% C l e a r M a g i c k E x c e p t i o n %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ClearMagickException() clears any exception that may not have been caught
% yet.
%
% The format of the ClearMagickException method is:
%
% ClearMagickException(ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o exception: the exception info.
%
*/
static void *DestroyExceptionElement(void *exception)
{
register ExceptionInfo
*p;
p=(ExceptionInfo *) exception;
if (p->reason != (char *) NULL)
p->reason=DestroyString(p->reason);
if (p->description != (char *) NULL)
p->description=DestroyString(p->description);
p=(ExceptionInfo *) RelinquishMagickMemory(p);
return((void *) NULL);
}
MagickExport void ClearMagickException(ExceptionInfo *exception)
{
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickCoreSignature);
if (exception->exceptions == (void *) NULL)
return;
LockSemaphoreInfo(exception->semaphore);
ClearLinkedList((LinkedListInfo *) exception->exceptions,
DestroyExceptionElement);
exception->severity=UndefinedException;
exception->reason=(char *) NULL;
exception->description=(char *) NULL;
UnlockSemaphoreInfo(exception->semaphore);
errno=0;
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% C a t c h E x c e p t i o n %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CatchException() returns if no exceptions is found otherwise it reports
% the exception as a warning, error, or fatal depending on the severity.
%
% The format of the CatchException method is:
%
% CatchException(ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o exception: the exception info.
%
*/
MagickExport void CatchException(ExceptionInfo *exception)
{
LinkedListInfo
*exceptions;
register const ExceptionInfo
*p;
ssize_t
i;
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickCoreSignature);
if (exception->exceptions == (void *) NULL)
return;
LockSemaphoreInfo(exception->semaphore);
exceptions=(LinkedListInfo *) exception->exceptions;
ResetLinkedListIterator(exceptions);
p=(const ExceptionInfo *) GetNextValueInLinkedList(exceptions);
for (i=0; p != (const ExceptionInfo *) NULL; i++)
{
if ((p->severity >= WarningException) && (p->severity < ErrorException))
MagickWarning(p->severity,p->reason,p->description);
if ((p->severity >= ErrorException) && (p->severity < FatalErrorException))
MagickError(p->severity,p->reason,p->description);
if (p->severity >= FatalErrorException)
MagickFatalError(p->severity,p->reason,p->description);
p=(const ExceptionInfo *) GetNextValueInLinkedList(exceptions);
}
UnlockSemaphoreInfo(exception->semaphore);
ClearMagickException(exception);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% C l o n e E x c e p t i o n I n f o %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CloneExceptionInfo() clones the ExceptionInfo structure.
%
% The format of the CloneExceptionInfo method is:
%
% ExceptionInfo *CloneException(ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o exception: the exception info.
%
*/
MagickExport ExceptionInfo *CloneExceptionInfo(ExceptionInfo *exception)
{
ExceptionInfo
*clone_exception;
clone_exception=(ExceptionInfo *) AcquireCriticalMemory(sizeof(*exception));
InitializeExceptionInfo(clone_exception);
InheritException(clone_exception,exception);
clone_exception->relinquish=MagickTrue;
return(clone_exception);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
+ D e f a u l t E r r o r H a n d l e r %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DefaultErrorHandler() displays an error reason.
%
% The format of the DefaultErrorHandler method is:
%
% void MagickError(const ExceptionType severity,const char *reason,
% const char *description)
%
% A description of each parameter follows:
%
% o severity: Specifies the numeric error category.
%
% o reason: Specifies the reason to display before terminating the
% program.
%
% o description: Specifies any description to the reason.
%
*/
static void DefaultErrorHandler(const ExceptionType magick_unused(severity),
const char *reason,const char *description)
{
magick_unreferenced(severity);
if (reason == (char *) NULL)
return;
(void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason);
if (description != (char *) NULL)
(void) FormatLocaleFile(stderr," (%s)",description);
(void) FormatLocaleFile(stderr,".\n");
(void) fflush(stderr);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
+ D e f a u l t F a t a l E r r o r H a n d l e r %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DefaultFatalErrorHandler() displays an error reason and then terminates the
% program.
%
% The format of the DefaultFatalErrorHandler method is:
%
% void MagickFatalError(const ExceptionType severity,const char *reason,
% const char *description)
%
% A description of each parameter follows:
%
% o severity: Specifies the numeric error category.
%
% o reason: Specifies the reason to display before terminating the program.
%
% o description: Specifies any description to the reason.
%
*/
static void DefaultFatalErrorHandler(const ExceptionType severity,
const char *reason,const char *description)
{
if (reason == (char *) NULL)
return;
(void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason);
if (description != (char *) NULL)
(void) FormatLocaleFile(stderr," (%s)",description);
(void) FormatLocaleFile(stderr,".\n");
(void) fflush(stderr);
MagickCoreTerminus();
exit((int) (severity-FatalErrorException)+1);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
+ D e f a u l t W a r n i n g H a n d l e r %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DefaultWarningHandler() displays a warning reason.
%
% The format of the DefaultWarningHandler method is:
%
% void DefaultWarningHandler(const ExceptionType severity,
% const char *reason,const char *description)
%
% A description of each parameter follows:
%
% o severity: Specifies the numeric warning category.
%
% o reason: Specifies the reason to display before terminating the
% program.
%
% o description: Specifies any description to the reason.
%
*/
static void DefaultWarningHandler(const ExceptionType magick_unused(severity),
const char *reason,const char *description)
{
magick_unreferenced(severity);
if (reason == (char *) NULL)
return;
(void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason);
if (description != (char *) NULL)
(void) FormatLocaleFile(stderr," (%s)",description);
(void) FormatLocaleFile(stderr,".\n");
(void) fflush(stderr);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% D e s t r o y E x c e p t i o n I n f o %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DestroyExceptionInfo() deallocates memory associated with an exception.
%
% The format of the DestroyExceptionInfo method is:
%
% ExceptionInfo *DestroyExceptionInfo(ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o exception: the exception info.
%
*/
MagickExport ExceptionInfo *DestroyExceptionInfo(ExceptionInfo *exception)
{
MagickBooleanType
relinquish;
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickCoreSignature);
if (exception->semaphore == (SemaphoreInfo *) NULL)
ActivateSemaphoreInfo(&exception->semaphore);
LockSemaphoreInfo(exception->semaphore);
exception->severity=UndefinedException;
if (exception->relinquish != MagickFalse)
{
exception->signature=(~MagickCoreSignature);
if (exception->exceptions != (void *) NULL)
exception->exceptions=(void *) DestroyLinkedList((LinkedListInfo *)
exception->exceptions,DestroyExceptionElement);
}
else
if (exception->exceptions != (void *) NULL)
ClearLinkedList((LinkedListInfo *) exception->exceptions,
DestroyExceptionElement);
relinquish=exception->relinquish;
UnlockSemaphoreInfo(exception->semaphore);
if (relinquish != MagickFalse)
{
RelinquishSemaphoreInfo(&exception->semaphore);
exception=(ExceptionInfo *) RelinquishMagickMemory(exception);
}
return(exception);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% G e t E x c e p t i o n M e s s a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetExceptionMessage() returns the error message defined by the specified
% error code.
%
% The format of the GetExceptionMessage method is:
%
% char *GetExceptionMessage(const int error)
%
% A description of each parameter follows:
%
% o error: the error code.
%
*/
MagickExport char *GetExceptionMessage(const int error)
{
char
exception[MagickPathExtent];
*exception='\0';
#if defined(MAGICKCORE_HAVE_STRERROR_R)
#if !defined(MAGICKCORE_STRERROR_R_CHAR_P)
(void) strerror_r(error,exception,sizeof(exception));
#else
(void) CopyMagickString(exception,strerror_r(error,exception,
sizeof(exception)),sizeof(exception));
#endif
#else
(void) CopyMagickString(exception,strerror(error),sizeof(exception));
#endif
return(ConstantString(exception));
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% 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 %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetLocaleExceptionMessage() converts a enumerated exception severity and tag
% to a message in the current locale.
%
% The format of the GetLocaleExceptionMessage method is:
%
% const char *GetLocaleExceptionMessage(const ExceptionType severity,
% const char *tag)
%
% A description of each parameter follows:
%
% o severity: the severity of the exception.
%
% o tag: the message tag.
%
*/
static const char *ExceptionSeverityToTag(const ExceptionType severity)
{
switch (severity)
{
case ResourceLimitWarning: return("Resource/Limit/Warning/");
case TypeWarning: return("Type/Warning/");
case OptionWarning: return("Option/Warning/");
case DelegateWarning: return("Delegate/Warning/");
case MissingDelegateWarning: return("Missing/Delegate/Warning/");
case CorruptImageWarning: return("Corrupt/Image/Warning/");
case FileOpenWarning: return("File/Open/Warning/");
case BlobWarning: return("Blob/Warning/");
case StreamWarning: return("Stream/Warning/");
case CacheWarning: return("Cache/Warning/");
case CoderWarning: return("Coder/Warning/");
case FilterWarning: return("Filter/Warning/");
case ModuleWarning: return("Module/Warning/");
case DrawWarning: return("Draw/Warning/");
case ImageWarning: return("Image/Warning/");
case WandWarning: return("Wand/Warning/");
case XServerWarning: return("XServer/Warning/");
case MonitorWarning: return("Monitor/Warning/");
case RegistryWarning: return("Registry/Warning/");
case ConfigureWarning: return("Configure/Warning/");
case PolicyWarning: return("Policy/Warning/");
case ResourceLimitError: return("Resource/Limit/Error/");
case TypeError: return("Type/Error/");
case OptionError: return("Option/Error/");
case DelegateError: return("Delegate/Error/");
case MissingDelegateError: return("Missing/Delegate/Error/");
case CorruptImageError: return("Corrupt/Image/Error/");
case FileOpenError: return("File/Open/Error/");
case BlobError: return("Blob/Error/");
case StreamError: return("Stream/Error/");
case CacheError: return("Cache/Error/");
case CoderError: return("Coder/Error/");
case FilterError: return("Filter/Error/");
case ModuleError: return("Module/Error/");
case DrawError: return("Draw/Error/");
case ImageError: return("Image/Error/");
case WandError: return("Wand/Error/");
case XServerError: return("XServer/Error/");
case MonitorError: return("Monitor/Error/");
case RegistryError: return("Registry/Error/");
case ConfigureError: return("Configure/Error/");
case PolicyError: return("Policy/Error/");
case ResourceLimitFatalError: return("Resource/Limit/FatalError/");
case TypeFatalError: return("Type/FatalError/");
case OptionFatalError: return("Option/FatalError/");
case DelegateFatalError: return("Delegate/FatalError/");
case MissingDelegateFatalError: return("Missing/Delegate/FatalError/");
case CorruptImageFatalError: return("Corrupt/Image/FatalError/");
case FileOpenFatalError: return("File/Open/FatalError/");
case BlobFatalError: return("Blob/FatalError/");
case StreamFatalError: return("Stream/FatalError/");
case CacheFatalError: return("Cache/FatalError/");
case CoderFatalError: return("Coder/FatalError/");
case FilterFatalError: return("Filter/FatalError/");
case ModuleFatalError: return("Module/FatalError/");
case DrawFatalError: return("Draw/FatalError/");
case ImageFatalError: return("Image/FatalError/");
case WandFatalError: return("Wand/FatalError/");
case XServerFatalError: return("XServer/FatalError/");
case MonitorFatalError: return("Monitor/FatalError/");
case RegistryFatalError: return("Registry/FatalError/");
case ConfigureFatalError: return("Configure/FatalError/");
case PolicyFatalError: return("Policy/FatalError/");
default: break;
}
return("");
}
MagickExport const char *GetLocaleExceptionMessage(const ExceptionType severity,
const char *tag)
{
char
message[MagickPathExtent];
const char
*locale_message;
assert(tag != (const char *) NULL);
(void) FormatLocaleString(message,MagickPathExtent,"Exception/%s%s",
ExceptionSeverityToTag(severity),tag);
locale_message=GetLocaleMessage(message);
if (locale_message == (const char *) NULL)
return(tag);
if (locale_message == message)
return(tag);
return(locale_message);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% I n h e r i t E x c e p t i o n %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% InheritException() inherits an exception from a related exception.
%
% The format of the InheritException method is:
%
% InheritException(ExceptionInfo *exception,const ExceptionInfo *relative)
%
% A description of each parameter follows:
%
% o exception: the exception info.
%
% o relative: the related exception info.
%
*/
MagickExport void InheritException(ExceptionInfo *exception,
const ExceptionInfo *relative)
{
register const ExceptionInfo
*p;
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickCoreSignature);
assert(relative != (ExceptionInfo *) NULL);
assert(relative->signature == MagickCoreSignature);
assert(exception != relative);
if (relative->exceptions == (void *) NULL)
return;
LockSemaphoreInfo(relative->semaphore);
ResetLinkedListIterator((LinkedListInfo *) relative->exceptions);
p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
relative->exceptions);
while (p != (const ExceptionInfo *) NULL)
{
(void) ThrowException(exception,p->severity,p->reason,p->description);
p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
relative->exceptions);
}
UnlockSemaphoreInfo(relative->semaphore);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% I n i t i a l i z e t E x c e p t i o n I n f o %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% InitializeExceptionInfo() initializes an exception to default values.
%
% The format of the InitializeExceptionInfo method is:
%
% InitializeExceptionInfo(ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o exception: the exception info.
%
*/
MagickPrivate void InitializeExceptionInfo(ExceptionInfo *exception)
{
assert(exception != (ExceptionInfo *) NULL);
(void) memset(exception,0,sizeof(*exception));
exception->severity=UndefinedException;
exception->exceptions=(void *) NewLinkedList(0);
exception->semaphore=AcquireSemaphoreInfo();
exception->signature=MagickCoreSignature;
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% M a g i c k E r r o r %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MagickError() calls the exception handler methods with an error reason.
%
% The format of the MagickError method is:
%
% void MagickError(const ExceptionType error,const char *reason,
% const char *description)
%
% A description of each parameter follows:
%
% o exception: Specifies the numeric error category.
%
% o reason: Specifies the reason to display before terminating the
% program.
%
% o description: Specifies any description to the reason.
%
*/
MagickExport void MagickError(const ExceptionType error,const char *reason,
const char *description)
{
if (error_handler != (ErrorHandler) NULL)
(*error_handler)(error,reason,description);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% M a g i c k F a t al E r r o r %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MagickFatalError() calls the fatal exception handler methods with an error
% reason.
%
% The format of the MagickError method is:
%
% void MagickFatalError(const ExceptionType error,const char *reason,
% const char *description)
%
% A description of each parameter follows:
%
% o exception: Specifies the numeric error category.
%
% o reason: Specifies the reason to display before terminating the
% program.
%
% o description: Specifies any description to the reason.
%
*/
MagickExport void MagickFatalError(const ExceptionType error,const char *reason,
const char *description)
{
if (fatal_error_handler != (ErrorHandler) NULL)
(*fatal_error_handler)(error,reason,description);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% M a g i c k W a r n i n g %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MagickWarning() calls the warning handler methods with a warning reason.
%
% The format of the MagickWarning method is:
%
% void MagickWarning(const ExceptionType warning,const char *reason,
% const char *description)
%
% A description of each parameter follows:
%
% o warning: the warning severity.
%
% o reason: Define the reason for the warning.
%
% o description: Describe the warning.
%
*/
MagickExport void MagickWarning(const ExceptionType warning,const char *reason,
const char *description)
{
if (warning_handler != (WarningHandler) NULL)
(*warning_handler)(warning,reason,description);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% S e t E r r o r H a n d l e r %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SetErrorHandler() sets the exception handler to the specified method
% and returns the previous exception handler.
%
% The format of the SetErrorHandler method is:
%
% ErrorHandler SetErrorHandler(ErrorHandler handler)
%
% A description of each parameter follows:
%
% o handler: the method to handle errors.
%
*/
MagickExport ErrorHandler SetErrorHandler(ErrorHandler handler)
{
ErrorHandler
previous_handler;
previous_handler=error_handler;
error_handler=handler;
return(previous_handler);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% S e t F a t a l E r r o r H a n d l e r %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SetFatalErrorHandler() sets the fatal exception handler to the specified
% method and returns the previous fatal exception handler.
%
% The format of the SetErrorHandler method is:
%
% ErrorHandler SetErrorHandler(ErrorHandler handler)
%
% A description of each parameter follows:
%
% o handler: the method to handle errors.
%
*/
MagickExport FatalErrorHandler SetFatalErrorHandler(FatalErrorHandler handler)
{
FatalErrorHandler
previous_handler;
previous_handler=fatal_error_handler;
fatal_error_handler=handler;
return(previous_handler);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% S e t W a r n i n g H a n d l e r %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SetWarningHandler() sets the warning handler to the specified method
% and returns the previous warning handler.
%
% The format of the SetWarningHandler method is:
%
% ErrorHandler SetWarningHandler(ErrorHandler handler)
%
% A description of each parameter follows:
%
% o handler: the method to handle warnings.
%
*/
MagickExport WarningHandler SetWarningHandler(WarningHandler handler)
{
WarningHandler
previous_handler;
previous_handler=warning_handler;
warning_handler=handler;
return(previous_handler);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% T h r o w E x c e p t i o n %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ThrowException() throws an exception with the specified severity code,
% reason, and optional description.
%
% The format of the ThrowException method is:
%
% MagickBooleanType ThrowException(ExceptionInfo *exception,
% const ExceptionType severity,const char *reason,
% const char *description)
%
% A description of each parameter follows:
%
% o exception: the exception info.
%
% o severity: the severity of the exception.
%
% o reason: the reason for the exception.
%
% o description: the exception description.
%
*/
MagickExport MagickBooleanType ThrowException(ExceptionInfo *exception,
const ExceptionType severity,const char *reason,const char *description)
{
LinkedListInfo
*exceptions;
register ExceptionInfo
*p;
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickCoreSignature);
LockSemaphoreInfo(exception->semaphore);
exceptions=(LinkedListInfo *) exception->exceptions;
if (GetNumberOfElementsInLinkedList(exceptions) > MaxExceptionList)
{
if (severity < ErrorException)
{
UnlockSemaphoreInfo(exception->semaphore);
return(MagickTrue);
}
p=(ExceptionInfo *) GetLastValueInLinkedList(exceptions);
if (p->severity >= ErrorException)
{
UnlockSemaphoreInfo(exception->semaphore);
return(MagickTrue);
}
}
p=(ExceptionInfo *) GetLastValueInLinkedList(exceptions);
if ((p != (ExceptionInfo *) NULL) && (p->severity == severity) &&
(LocaleCompare(exception->reason,reason) == 0) &&
(LocaleCompare(exception->description,description) == 0))
{
UnlockSemaphoreInfo(exception->semaphore);
return(MagickTrue);
}
p=(ExceptionInfo *) AcquireMagickMemory(sizeof(*p));
if (p == (ExceptionInfo *) NULL)
{
UnlockSemaphoreInfo(exception->semaphore);
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
}
(void) memset(p,0,sizeof(*p));
p->severity=severity;
if (reason != (const char *) NULL)
p->reason=ConstantString(reason);
if (description != (const char *) NULL)
p->description=ConstantString(description);
p->signature=MagickCoreSignature;
(void) AppendValueToLinkedList(exceptions,p);
if (p->severity > exception->severity)
{
exception->severity=p->severity;
exception->reason=p->reason;
exception->description=p->description;
}
UnlockSemaphoreInfo(exception->semaphore);
if (GetNumberOfElementsInLinkedList(exceptions) == MaxExceptionList)
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitWarning,"TooManyExceptions",
"(exception processing is suspended)");
return(MagickTrue);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% T h r o w M a g i c k E x c e p t i o n %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ThrowMagickException logs an exception as determined by the log
% configuration file. If an error occurs, MagickFalse is returned
% otherwise MagickTrue.
%
% The format of the ThrowMagickException method is:
%
% MagickBooleanType ThrowFileException(ExceptionInfo *exception,
% const char *module,const char *function,const size_t line,
% const ExceptionType severity,const char *tag,const char *format,...)
%
% A description of each parameter follows:
%
% o exception: the exception info.
%
% o filename: the source module filename.
%
% o function: the function name.
%
% o line: the line number of the source module.
%
% o severity: Specifies the numeric error category.
%
% o tag: the locale tag.
%
% o format: the output format.
%
*/
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)
{
char
message[MagickPathExtent],
path[MagickPathExtent],
reason[MagickPathExtent];
const char
*locale,
*type;
int
n;
MagickBooleanType
status;
size_t
length;
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickCoreSignature);
locale=GetLocaleExceptionMessage(severity,tag);
(void) CopyMagickString(reason,locale,MagickPathExtent);
(void) ConcatenateMagickString(reason," ",MagickPathExtent);
length=strlen(reason);
#if defined(MAGICKCORE_HAVE_VSNPRINTF)
n=vsnprintf(reason+length,MagickPathExtent-length,format,operands);
#else
n=vsprintf(reason+length,format,operands);
#endif
if (n < 0)
reason[MagickPathExtent-1]='\0';
status=LogMagickEvent(ExceptionEvent,module,function,line,"%s",reason);
GetPathComponent(module,TailPath,path);
type="undefined";
if ((severity >= WarningException) && (severity < ErrorException))
type="warning";
if ((severity >= ErrorException) && (severity < FatalErrorException))
type="error";
if (severity >= FatalErrorException)
type="fatal";
(void) FormatLocaleString(message,MagickPathExtent,"%s @ %s/%s/%s/%.20g",
reason,type,path,function,(double) line);
(void) ThrowException(exception,severity,message,(char *) NULL);
return(status);
}
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception,
const char *module,const char *function,const size_t line,
const ExceptionType severity,const char *tag,const char *format,...)
{
MagickBooleanType
status;
va_list
operands;
va_start(operands,format);
status=ThrowMagickExceptionList(exception,module,function,line,severity,tag,
format,operands);
va_end(operands);
return(status);
}