This source file includes following definitions.
- AcquireExceptionInfo
- DestroyExceptionElement
- ClearMagickException
- CatchException
- CloneExceptionInfo
- DefaultErrorHandler
- DefaultFatalErrorHandler
- DefaultWarningHandler
- ClearExceptionInfo
- DestroyExceptionInfo
- GetExceptionMessage
- ExceptionSeverityToTag
- GetLocaleExceptionMessage
- InheritException
- InitializeExceptionInfo
- MagickError
- MagickFatalError
- MagickWarning
- SetErrorHandler
- SetFatalErrorHandler
- SetWarningHandler
- ThrowException
- ThrowMagickExceptionList
- ThrowMagickException
#include "magick/studio.h"
#include "magick/client.h"
#include "magick/exception.h"
#include "magick/exception-private.h"
#include "magick/hashmap.h"
#include "magick/locale_.h"
#include "magick/log.h"
#include "magick/magick.h"
#include "magick/memory_.h"
#include "magick/string_.h"
#include "magick/utility.h"
#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
static ErrorHandler
error_handler = DefaultErrorHandler;
static FatalErrorHandler
fatal_error_handler = DefaultFatalErrorHandler;
static WarningHandler
warning_handler = DefaultWarningHandler;
MagickExport ExceptionInfo *AcquireExceptionInfo(void)
{
ExceptionInfo
*exception;
exception=(ExceptionInfo *) AcquireMagickMemory(sizeof(*exception));
if (exception == (ExceptionInfo *) NULL)
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
InitializeExceptionInfo(exception);
exception->relinquish=MagickTrue;
return(exception);
}
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 == MagickSignature);
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;
}
MagickExport void CatchException(ExceptionInfo *exception)
{
register const ExceptionInfo
*p;
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
if (exception->exceptions == (void *) NULL)
return;
LockSemaphoreInfo(exception->semaphore);
ResetLinkedListIterator((LinkedListInfo *) exception->exceptions);
p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
exception->exceptions);
while (p != (const ExceptionInfo *) NULL)
{
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((LinkedListInfo *)
exception->exceptions);
}
UnlockSemaphoreInfo(exception->semaphore);
ClearMagickException(exception);
}
MagickExport ExceptionInfo *CloneExceptionInfo(ExceptionInfo *exception)
{
ExceptionInfo
*clone_exception;
clone_exception=(ExceptionInfo *) AcquireMagickMemory(sizeof(*exception));
if (clone_exception == (ExceptionInfo *) NULL)
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
InitializeExceptionInfo(clone_exception);
InheritException(clone_exception,exception);
clone_exception->relinquish=MagickTrue;
return(clone_exception);
}
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);
}
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);
}
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);
}
MagickPrivate MagickBooleanType ClearExceptionInfo(ExceptionInfo *exception,
MagickBooleanType relinquish)
{
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
if (exception->semaphore == (SemaphoreInfo *) NULL)
ActivateSemaphoreInfo(&exception->semaphore);
LockSemaphoreInfo(exception->semaphore);
if (relinquish == MagickFalse)
relinquish=exception->relinquish;
exception->severity=UndefinedException;
if (relinquish != MagickFalse)
{
exception->signature=(~MagickSignature);
if (exception->exceptions != (void *) NULL)
exception->exceptions=(void *) DestroyLinkedList((LinkedListInfo *)
exception->exceptions,DestroyExceptionElement);
}
else if (exception->exceptions != (void *) NULL)
ClearLinkedList((LinkedListInfo *) exception->exceptions,
DestroyExceptionElement);
UnlockSemaphoreInfo(exception->semaphore);
if (relinquish != MagickFalse)
DestroySemaphoreInfo(&exception->semaphore);
return(relinquish);
}
MagickExport ExceptionInfo *DestroyExceptionInfo(ExceptionInfo *exception)
{
if (ClearExceptionInfo(exception,MagickFalse) != MagickFalse)
exception=(ExceptionInfo *) RelinquishMagickMemory(exception);
return(exception);
}
MagickExport char *GetExceptionMessage(const int error)
{
char
exception[MaxTextExtent];
*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));
}
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[MaxTextExtent];
const char
*locale_message;
assert(tag != (const char *) NULL);
(void) FormatLocaleString(message,MaxTextExtent,"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);
}
MagickExport void InheritException(ExceptionInfo *exception,
const ExceptionInfo *relative)
{
register const ExceptionInfo
*p;
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
assert(relative != (ExceptionInfo *) NULL);
assert(relative->signature == MagickSignature);
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);
}
MagickPrivate void InitializeExceptionInfo(ExceptionInfo *exception)
{
assert(exception != (ExceptionInfo *) NULL);
(void) ResetMagickMemory(exception,0,sizeof(*exception));
exception->severity=UndefinedException;
exception->exceptions=(void *) NewLinkedList(0);
exception->semaphore=AllocateSemaphoreInfo();
exception->signature=MagickSignature;
}
MagickExport void MagickError(const ExceptionType error,const char *reason,
const char *description)
{
if (error_handler != (ErrorHandler) NULL)
(*error_handler)(error,reason,description);
}
MagickExport void MagickFatalError(const ExceptionType error,const char *reason,
const char *description)
{
if (fatal_error_handler != (ErrorHandler) NULL)
(*fatal_error_handler)(error,reason,description);
}
MagickExport void MagickWarning(const ExceptionType warning,const char *reason,
const char *description)
{
if (warning_handler != (WarningHandler) NULL)
(*warning_handler)(warning,reason,description);
}
MagickExport ErrorHandler SetErrorHandler(ErrorHandler handler)
{
ErrorHandler
previous_handler;
previous_handler=error_handler;
error_handler=handler;
return(previous_handler);
}
MagickExport FatalErrorHandler SetFatalErrorHandler(FatalErrorHandler handler)
{
FatalErrorHandler
previous_handler;
previous_handler=fatal_error_handler;
fatal_error_handler=handler;
return(previous_handler);
}
MagickExport WarningHandler SetWarningHandler(WarningHandler handler)
{
WarningHandler
previous_handler;
previous_handler=warning_handler;
warning_handler=handler;
return(previous_handler);
}
MagickExport MagickBooleanType ThrowException(ExceptionInfo *exception,
const ExceptionType severity,const char *reason,const char *description)
{
register ExceptionInfo
*p;
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
LockSemaphoreInfo(exception->semaphore);
p=(ExceptionInfo *) GetLastValueInLinkedList((LinkedListInfo *)
exception->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) ResetMagickMemory(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=MagickSignature;
(void) AppendValueToLinkedList((LinkedListInfo *) exception->exceptions,p);
if (p->severity >= exception->severity)
{
exception->severity=p->severity;
exception->reason=p->reason;
exception->description=p->description;
}
UnlockSemaphoreInfo(exception->semaphore);
return(MagickTrue);
}
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[MaxTextExtent],
path[MaxTextExtent],
reason[MaxTextExtent];
const char
*locale,
*type;
int
n;
MagickBooleanType
status;
size_t
length;
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
locale=GetLocaleExceptionMessage(severity,tag);
(void) CopyMagickString(reason,locale,MaxTextExtent);
(void) ConcatenateMagickString(reason," ",MaxTextExtent);
length=strlen(reason);
#if defined(MAGICKCORE_HAVE_VSNPRINTF)
n=vsnprintf(reason+length,MaxTextExtent-length,format,operands);
#else
n=vsprintf(reason+length,format,operands);
#endif
if (n < 0)
reason[MaxTextExtent-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,MaxTextExtent,"%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);
}