MagickCore  6.7.5
exception.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %        EEEEE  X   X   CCCC  EEEEE  PPPP  TTTTT  IIIII   OOO   N   N         %
00007 %        E       X X   C      E      P   P   T      I    O   O  NN  N         %
00008 %        EEE      X    C      EEE    PPPP    T      I    O   O  N N N         %
00009 %        E       X X   C      E      P       T      I    O   O  N  NN         %
00010 %        EEEEE   X  X   CCCC  EEEEE  P       T    IIIII   OOO   N   N         %
00011 %                                                                             %
00012 %                                                                             %
00013 %                        MagickCore Exception Methods                         %
00014 %                                                                             %
00015 %                             Software Design                                 %
00016 %                               John Cristy                                   %
00017 %                                July 1993                                    %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "MagickCore/studio.h"
00044 #include "MagickCore/client.h"
00045 #include "MagickCore/exception.h"
00046 #include "MagickCore/exception-private.h"
00047 #include "MagickCore/hashmap.h"
00048 #include "MagickCore/locale_.h"
00049 #include "MagickCore/log.h"
00050 #include "MagickCore/magick.h"
00051 #include "MagickCore/memory_.h"
00052 #include "MagickCore/string_.h"
00053 #include "MagickCore/utility.h"
00054 #include "MagickCore/utility-private.h"
00055 
00056 /*
00057   Forward declarations.
00058 */
00059 #if defined(__cplusplus) || defined(c_plusplus)
00060 extern "C" {
00061 #endif
00062 
00063 static void
00064   DefaultErrorHandler(const ExceptionType,const char *,const char *),
00065   DefaultFatalErrorHandler(const ExceptionType,const char *,const char *),
00066   DefaultWarningHandler(const ExceptionType,const char *,const char *);
00067 
00068 #if defined(__cplusplus) || defined(c_plusplus)
00069 }
00070 #endif
00071 
00072 /*
00073   Global declarations.
00074 */
00075 static ErrorHandler
00076   error_handler = DefaultErrorHandler;
00077 
00078 static FatalErrorHandler
00079   fatal_error_handler = DefaultFatalErrorHandler;
00080 
00081 static WarningHandler
00082   warning_handler = DefaultWarningHandler;
00083 
00084 /*
00085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00086 %                                                                             %
00087 %                                                                             %
00088 %                                                                             %
00089 %   A c q u i r e E x c e p t i o n I n f o                                   %
00090 %                                                                             %
00091 %                                                                             %
00092 %                                                                             %
00093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00094 %
00095 %  AcquireExceptionInfo() allocates the ExceptionInfo structure.
00096 %
00097 %  The format of the AcquireExceptionInfo method is:
00098 %
00099 %      ExceptionInfo *AcquireExceptionInfo(void)
00100 %
00101 */
00102 MagickExport ExceptionInfo *AcquireExceptionInfo(void)
00103 {
00104   ExceptionInfo
00105     *exception;
00106 
00107   exception=(ExceptionInfo *) AcquireMagickMemory(sizeof(*exception));
00108   if (exception == (ExceptionInfo *) NULL)
00109     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00110   GetExceptionInfo(exception);
00111   exception->relinquish=MagickTrue;
00112   return(exception);
00113 }
00114 
00115 /*
00116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00117 %                                                                             %
00118 %                                                                             %
00119 %                                                                             %
00120 %   C l e a r M a g i c k E x c e p t i o n                                   %
00121 %                                                                             %
00122 %                                                                             %
00123 %                                                                             %
00124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00125 %
00126 %  ClearMagickException() clears any exception that may not have been caught
00127 %  yet.
00128 %
00129 %  The format of the ClearMagickException method is:
00130 %
00131 %      ClearMagickException(ExceptionInfo *exception)
00132 %
00133 %  A description of each parameter follows:
00134 %
00135 %    o exception: the exception info.
00136 %
00137 */
00138 
00139 static void *DestroyExceptionElement(void *exception)
00140 {
00141   register ExceptionInfo
00142     *p;
00143 
00144   p=(ExceptionInfo *) exception;
00145   if (p->reason != (char *) NULL)
00146     p->reason=DestroyString(p->reason);
00147   if (p->description != (char *) NULL)
00148     p->description=DestroyString(p->description);
00149   p=(ExceptionInfo *) RelinquishMagickMemory(p);
00150   return((void *) NULL);
00151 }
00152 
00153 MagickExport void ClearMagickException(ExceptionInfo *exception)
00154 {
00155   register ExceptionInfo
00156     *p;
00157 
00158   assert(exception != (ExceptionInfo *) NULL);
00159   assert(exception->signature == MagickSignature);
00160   if (exception->exceptions  == (void *) NULL)
00161     return;
00162   LockSemaphoreInfo(exception->semaphore);
00163   p=(ExceptionInfo *) RemoveLastElementFromLinkedList((LinkedListInfo *)
00164     exception->exceptions);
00165   while (p != (ExceptionInfo *) NULL)
00166   {
00167     (void) DestroyExceptionElement(p);
00168     p=(ExceptionInfo *) RemoveLastElementFromLinkedList((LinkedListInfo *)
00169       exception->exceptions);
00170   }
00171   exception->severity=UndefinedException;
00172   exception->reason=(char *) NULL;
00173   exception->description=(char *) NULL;
00174   UnlockSemaphoreInfo(exception->semaphore);
00175   errno=0;
00176 }
00177 
00178 /*
00179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00180 %                                                                             %
00181 %                                                                             %
00182 %                                                                             %
00183 %   C a t c h E x c e p t i o n                                               %
00184 %                                                                             %
00185 %                                                                             %
00186 %                                                                             %
00187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00188 %
00189 %  CatchException() returns if no exceptions is found otherwise it reports
00190 %  the exception as a warning, error, or fatal depending on the severity.
00191 %
00192 %  The format of the CatchException method is:
00193 %
00194 %      CatchException(ExceptionInfo *exception)
00195 %
00196 %  A description of each parameter follows:
00197 %
00198 %    o exception: the exception info.
00199 %
00200 */
00201 MagickExport void CatchException(ExceptionInfo *exception)
00202 {
00203   register const ExceptionInfo
00204     *p;
00205 
00206   assert(exception != (ExceptionInfo *) NULL);
00207   assert(exception->signature == MagickSignature);
00208   if (exception->exceptions  == (void *) NULL)
00209     return;
00210   LockSemaphoreInfo(exception->semaphore);
00211   ResetLinkedListIterator((LinkedListInfo *) exception->exceptions);
00212   p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
00213     exception->exceptions);
00214   while (p != (const ExceptionInfo *) NULL)
00215   {
00216     if ((p->severity >= WarningException) && (p->severity < ErrorException))
00217       MagickWarning(p->severity,p->reason,p->description);
00218     if ((p->severity >= ErrorException) && (p->severity < FatalErrorException))
00219       MagickError(p->severity,p->reason,p->description);
00220     if (p->severity >= FatalErrorException)
00221       MagickFatalError(p->severity,p->reason,p->description);
00222     p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
00223       exception->exceptions);
00224   }
00225   UnlockSemaphoreInfo(exception->semaphore);
00226   ClearMagickException(exception);
00227 }
00228 
00229 /*
00230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00231 %                                                                             %
00232 %                                                                             %
00233 %                                                                             %
00234 %   C l o n e E x c e p t i o n I n f o                                       %
00235 %                                                                             %
00236 %                                                                             %
00237 %                                                                             %
00238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00239 %
00240 %  CloneExceptionInfo() clones the ExceptionInfo structure.
00241 %
00242 %  The format of the CloneExceptionInfo method is:
00243 %
00244 %      ExceptionInfo *CloneException(ExceptionInfo *exception)
00245 %
00246 %  A description of each parameter follows:
00247 %
00248 %    o exception: the exception info.
00249 %
00250 */
00251 MagickExport ExceptionInfo *CloneExceptionInfo(ExceptionInfo *exception)
00252 {
00253   ExceptionInfo
00254     *clone_exception;
00255 
00256   clone_exception=(ExceptionInfo *) AcquireMagickMemory(sizeof(*exception));
00257   if (clone_exception == (ExceptionInfo *) NULL)
00258     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00259   GetExceptionInfo(clone_exception);
00260   InheritException(clone_exception,exception);
00261   exception->relinquish=MagickTrue;
00262   return(exception);
00263 }
00264 
00265 /*
00266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00267 %                                                                             %
00268 %                                                                             %
00269 %                                                                             %
00270 +   D e f a u l t E r r o r H a n d l e r                                     %
00271 %                                                                             %
00272 %                                                                             %
00273 %                                                                             %
00274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00275 %
00276 %  DefaultErrorHandler() displays an error reason.
00277 %
00278 %  The format of the DefaultErrorHandler method is:
00279 %
00280 %      void MagickError(const ExceptionType severity,const char *reason,
00281 %        const char *description)
00282 %
00283 %  A description of each parameter follows:
00284 %
00285 %    o severity: Specifies the numeric error category.
00286 %
00287 %    o reason: Specifies the reason to display before terminating the
00288 %      program.
00289 %
00290 %    o description: Specifies any description to the reason.
00291 %
00292 */
00293 static void DefaultErrorHandler(const ExceptionType magick_unused(severity),
00294   const char *reason,const char *description)
00295 {
00296   if (reason == (char *) NULL)
00297     return;
00298   (void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason);
00299   if (description != (char *) NULL)
00300     (void) FormatLocaleFile(stderr," (%s)",description);
00301   (void) FormatLocaleFile(stderr,".\n");
00302   (void) fflush(stderr);
00303 }
00304 
00305 /*
00306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00307 %                                                                             %
00308 %                                                                             %
00309 %                                                                             %
00310 +   D e f a u l t F a t a l E r r o r H a n d l e r                           %
00311 %                                                                             %
00312 %                                                                             %
00313 %                                                                             %
00314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00315 %
00316 %  DefaultFatalErrorHandler() displays an error reason and then terminates the
00317 %  program.
00318 %
00319 %  The format of the DefaultFatalErrorHandler method is:
00320 %
00321 %      void MagickFatalError(const ExceptionType severity,const char *reason,
00322 %        const char *description)
00323 %
00324 %  A description of each parameter follows:
00325 %
00326 %    o severity: Specifies the numeric error category.
00327 %
00328 %    o reason: Specifies the reason to display before terminating the
00329 %      program.
00330 %
00331 %    o description: Specifies any description to the reason.
00332 %
00333 */
00334 static void DefaultFatalErrorHandler(
00335   const ExceptionType magick_unused(severity),
00336   const char *reason,const char *description)
00337 {
00338   if (reason == (char *) NULL)
00339     return;
00340   (void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason);
00341   if (description != (char *) NULL)
00342     (void) FormatLocaleFile(stderr," (%s)",description);
00343   (void) FormatLocaleFile(stderr,".\n");
00344   (void) fflush(stderr);
00345   MagickCoreTerminus();
00346   exit(1);
00347 }
00348 
00349 /*
00350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00351 %                                                                             %
00352 %                                                                             %
00353 %                                                                             %
00354 +   D e f a u l t W a r n i n g H a n d l e r                                 %
00355 %                                                                             %
00356 %                                                                             %
00357 %                                                                             %
00358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00359 %
00360 %  DefaultWarningHandler() displays a warning reason.
00361 %
00362 %  The format of the DefaultWarningHandler method is:
00363 %
00364 %      void DefaultWarningHandler(const ExceptionType severity,
00365 %        const char *reason,const char *description)
00366 %
00367 %  A description of each parameter follows:
00368 %
00369 %    o severity: Specifies the numeric warning category.
00370 %
00371 %    o reason: Specifies the reason to display before terminating the
00372 %      program.
00373 %
00374 %    o description: Specifies any description to the reason.
00375 %
00376 */
00377 static void DefaultWarningHandler(const ExceptionType magick_unused(severity),
00378   const char *reason,const char *description)
00379 {
00380   if (reason == (char *) NULL)
00381     return;
00382   (void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason);
00383   if (description != (char *) NULL)
00384     (void) FormatLocaleFile(stderr," (%s)",description);
00385   (void) FormatLocaleFile(stderr,".\n");
00386   (void) fflush(stderr);
00387 }
00388 
00389 /*
00390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00391 %                                                                             %
00392 %                                                                             %
00393 %                                                                             %
00394 %   D e s t r o y E x c e p t i o n I n f o                                   %
00395 %                                                                             %
00396 %                                                                             %
00397 %                                                                             %
00398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00399 %
00400 %  DestroyExceptionInfo() deallocates memory associated with an exception.
00401 %
00402 %  The format of the DestroyExceptionInfo method is:
00403 %
00404 %      ExceptionInfo *DestroyExceptionInfo(ExceptionInfo *exception)
00405 %
00406 %  A description of each parameter follows:
00407 %
00408 %    o exception: the exception info.
00409 %
00410 */
00411 MagickExport ExceptionInfo *DestroyExceptionInfo(ExceptionInfo *exception)
00412 {
00413   MagickBooleanType
00414     relinquish;
00415 
00416   assert(exception != (ExceptionInfo *) NULL);
00417   assert(exception->signature == MagickSignature);
00418   if (exception->semaphore == (SemaphoreInfo *) NULL)
00419     AcquireSemaphoreInfo(&exception->semaphore);
00420   LockSemaphoreInfo(exception->semaphore);
00421   exception->severity=UndefinedException;
00422   if (exception->exceptions != (void *) NULL)
00423     exception->exceptions=(void *) DestroyLinkedList((LinkedListInfo *)
00424       exception->exceptions,DestroyExceptionElement);
00425   relinquish=exception->relinquish;
00426   if (exception->relinquish != MagickFalse)
00427     exception->signature=(~MagickSignature);
00428   UnlockSemaphoreInfo(exception->semaphore);
00429   DestroySemaphoreInfo(&exception->semaphore);
00430   if (relinquish != MagickFalse)
00431     exception=(ExceptionInfo *) RelinquishMagickMemory(exception);
00432   return(exception);
00433 }
00434 
00435 /*
00436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00437 %                                                                             %
00438 %                                                                             %
00439 %                                                                             %
00440 %   G e t E x c e p t i o n I n f o                                           %
00441 %                                                                             %
00442 %                                                                             %
00443 %                                                                             %
00444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00445 %
00446 %  GetExceptionInfo() initializes an exception to default values.
00447 %
00448 %  The format of the GetExceptionInfo method is:
00449 %
00450 %      GetExceptionInfo(ExceptionInfo *exception)
00451 %
00452 %  A description of each parameter follows:
00453 %
00454 %    o exception: the exception info.
00455 %
00456 */
00457 MagickExport void GetExceptionInfo(ExceptionInfo *exception)
00458 {
00459   assert(exception != (ExceptionInfo *) NULL);
00460   (void) ResetMagickMemory(exception,0,sizeof(*exception));
00461   exception->severity=UndefinedException;
00462   exception->exceptions=(void *) NewLinkedList(0);
00463   exception->semaphore=AllocateSemaphoreInfo();
00464   exception->signature=MagickSignature;
00465 }
00466 
00467 /*
00468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00469 %                                                                             %
00470 %                                                                             %
00471 %                                                                             %
00472 %   G e t E x c e p t i o n M e s s a g e                                     %
00473 %                                                                             %
00474 %                                                                             %
00475 %                                                                             %
00476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00477 %
00478 %  GetExceptionMessage() returns the error message defined by the specified
00479 %  error code.
00480 %
00481 %  The format of the GetExceptionMessage method is:
00482 %
00483 %      char *GetExceptionMessage(const int error)
00484 %
00485 %  A description of each parameter follows:
00486 %
00487 %    o error: the error code.
00488 %
00489 */
00490 MagickExport char *GetExceptionMessage(const int error)
00491 {
00492   char
00493     exception[MaxTextExtent];
00494 
00495   *exception='\0';
00496 #if defined(MAGICKCORE_HAVE_STRERROR_R)
00497 #if !defined(MAGICKCORE_STRERROR_R_CHAR_P)
00498   (void) strerror_r(error,exception,sizeof(exception));
00499 #else
00500   (void) CopyMagickString(exception,strerror_r(error,exception,
00501     sizeof(exception)),sizeof(exception));
00502 #endif
00503 #else
00504   (void) CopyMagickString(exception,strerror(error),sizeof(exception));
00505 #endif
00506   return(ConstantString(exception));
00507 }
00508 
00509 /*
00510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00511 %                                                                             %
00512 %                                                                             %
00513 %                                                                             %
00514 %   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                         %
00515 %                                                                             %
00516 %                                                                             %
00517 %                                                                             %
00518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00519 %
00520 %  GetLocaleExceptionMessage() converts a enumerated exception severity and tag
00521 %  to a message in the current locale.
00522 %
00523 %  The format of the GetLocaleExceptionMessage method is:
00524 %
00525 %      const char *GetLocaleExceptionMessage(const ExceptionType severity,
00526 %        const char *tag)
00527 %
00528 %  A description of each parameter follows:
00529 %
00530 %    o severity: the severity of the exception.
00531 %
00532 %    o tag: the message tag.
00533 %
00534 */
00535 
00536 static const char *ExceptionSeverityToTag(const ExceptionType severity)
00537 {
00538   switch (severity)
00539   {
00540     case ResourceLimitWarning: return("Resource/Limit/Warning/");
00541     case TypeWarning: return("Type/Warning/");
00542     case OptionWarning: return("Option/Warning/");
00543     case DelegateWarning: return("Delegate/Warning/");
00544     case MissingDelegateWarning: return("Missing/Delegate/Warning/");
00545     case CorruptImageWarning: return("Corrupt/Image/Warning/");
00546     case FileOpenWarning: return("File/Open/Warning/");
00547     case BlobWarning: return("Blob/Warning/");
00548     case StreamWarning: return("Stream/Warning/");
00549     case CacheWarning: return("Cache/Warning/");
00550     case CoderWarning: return("Coder/Warning/");
00551     case FilterWarning: return("Filter/Warning/");
00552     case ModuleWarning: return("Module/Warning/");
00553     case DrawWarning: return("Draw/Warning/");
00554     case ImageWarning: return("Image/Warning/");
00555     case WandWarning: return("Wand/Warning/");
00556     case XServerWarning: return("XServer/Warning/");
00557     case MonitorWarning: return("Monitor/Warning/");
00558     case RegistryWarning: return("Registry/Warning/");
00559     case ConfigureWarning: return("Configure/Warning/");
00560     case PolicyWarning: return("Policy/Warning/");
00561     case ResourceLimitError: return("Resource/Limit/Error/");
00562     case TypeError: return("Type/Error/");
00563     case OptionError: return("Option/Error/");
00564     case DelegateError: return("Delegate/Error/");
00565     case MissingDelegateError: return("Missing/Delegate/Error/");
00566     case CorruptImageError: return("Corrupt/Image/Error/");
00567     case FileOpenError: return("File/Open/Error/");
00568     case BlobError: return("Blob/Error/");
00569     case StreamError: return("Stream/Error/");
00570     case CacheError: return("Cache/Error/");
00571     case CoderError: return("Coder/Error/");
00572     case FilterError: return("Filter/Error/");
00573     case ModuleError: return("Module/Error/");
00574     case DrawError: return("Draw/Error/");
00575     case ImageError: return("Image/Error/");
00576     case WandError: return("Wand/Error/");
00577     case XServerError: return("XServer/Error/");
00578     case MonitorError: return("Monitor/Error/");
00579     case RegistryError: return("Registry/Error/");
00580     case ConfigureError: return("Configure/Error/");
00581     case PolicyError: return("Policy/Error/");
00582     case ResourceLimitFatalError: return("Resource/Limit/FatalError/");
00583     case TypeFatalError: return("Type/FatalError/");
00584     case OptionFatalError: return("Option/FatalError/");
00585     case DelegateFatalError: return("Delegate/FatalError/");
00586     case MissingDelegateFatalError: return("Missing/Delegate/FatalError/");
00587     case CorruptImageFatalError: return("Corrupt/Image/FatalError/");
00588     case FileOpenFatalError: return("File/Open/FatalError/");
00589     case BlobFatalError: return("Blob/FatalError/");
00590     case StreamFatalError: return("Stream/FatalError/");
00591     case CacheFatalError: return("Cache/FatalError/");
00592     case CoderFatalError: return("Coder/FatalError/");
00593     case FilterFatalError: return("Filter/FatalError/");
00594     case ModuleFatalError: return("Module/FatalError/");
00595     case DrawFatalError: return("Draw/FatalError/");
00596     case ImageFatalError: return("Image/FatalError/");
00597     case WandFatalError: return("Wand/FatalError/");
00598     case XServerFatalError: return("XServer/FatalError/");
00599     case MonitorFatalError: return("Monitor/FatalError/");
00600     case RegistryFatalError: return("Registry/FatalError/");
00601     case ConfigureFatalError: return("Configure/FatalError/");
00602     case PolicyFatalError: return("Policy/FatalError/");
00603     default: break;
00604   }
00605   return("");
00606 }
00607 
00608 MagickExport const char *GetLocaleExceptionMessage(const ExceptionType severity,
00609   const char *tag)
00610 {
00611   char
00612     message[MaxTextExtent];
00613 
00614   const char
00615     *locale_message;
00616 
00617   assert(tag != (const char *) NULL);
00618   (void) FormatLocaleString(message,MaxTextExtent,"Exception/%s%s",
00619     ExceptionSeverityToTag(severity),tag);
00620   locale_message=GetLocaleMessage(message);
00621   if (locale_message == (const char *) NULL)
00622     return(tag);
00623   if (locale_message == message)
00624     return(tag);
00625   return(locale_message);
00626 }
00627 
00628 /*
00629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00630 %                                                                             %
00631 %                                                                             %
00632 %                                                                             %
00633 %   I n h e r i t E x c e p t i o n                                           %
00634 %                                                                             %
00635 %                                                                             %
00636 %                                                                             %
00637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00638 %
00639 %  InheritException() inherits an exception from a related exception.
00640 %
00641 %  The format of the InheritException method is:
00642 %
00643 %      InheritException(ExceptionInfo *exception,const ExceptionInfo *relative)
00644 %
00645 %  A description of each parameter follows:
00646 %
00647 %    o exception: the exception info.
00648 %
00649 %    o relative: the related exception info.
00650 %
00651 */
00652 MagickExport void InheritException(ExceptionInfo *exception,
00653   const ExceptionInfo *relative)
00654 {
00655   register const ExceptionInfo
00656     *p;
00657 
00658   assert(exception != (ExceptionInfo *) NULL);
00659   assert(exception->signature == MagickSignature);
00660   assert(relative != (ExceptionInfo *) NULL);
00661   assert(relative->signature == MagickSignature);
00662   if (relative->exceptions == (void *) NULL)
00663     return;
00664   LockSemaphoreInfo(exception->semaphore);
00665   ResetLinkedListIterator((LinkedListInfo *) relative->exceptions);
00666   p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
00667     relative->exceptions);
00668   while (p != (const ExceptionInfo *) NULL)
00669   {
00670     (void) ThrowException(exception,p->severity,p->reason,p->description);
00671     p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *)
00672       relative->exceptions);
00673   }
00674   UnlockSemaphoreInfo(exception->semaphore);
00675 }
00676 
00677 /*
00678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00679 %                                                                             %
00680 %                                                                             %
00681 %                                                                             %
00682 %   M a g i c k E r r o r                                                     %
00683 %                                                                             %
00684 %                                                                             %
00685 %                                                                             %
00686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00687 %
00688 %  MagickError() calls the exception handler methods with an error reason.
00689 %
00690 %  The format of the MagickError method is:
00691 %
00692 %      void MagickError(const ExceptionType error,const char *reason,
00693 %        const char *description)
00694 %
00695 %  A description of each parameter follows:
00696 %
00697 %    o exception: Specifies the numeric error category.
00698 %
00699 %    o reason: Specifies the reason to display before terminating the
00700 %      program.
00701 %
00702 %    o description: Specifies any description to the reason.
00703 %
00704 */
00705 MagickExport void MagickError(const ExceptionType error,const char *reason,
00706   const char *description)
00707 {
00708   if (error_handler != (ErrorHandler) NULL)
00709     (*error_handler)(error,reason,description);
00710 }
00711 
00712 /*
00713 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00714 %                                                                             %
00715 %                                                                             %
00716 %                                                                             %
00717 %   M a g i c k F a t al E r r o r                                            %
00718 %                                                                             %
00719 %                                                                             %
00720 %                                                                             %
00721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00722 %
00723 %  MagickFatalError() calls the fatal exception handler methods with an error
00724 %  reason.
00725 %
00726 %  The format of the MagickError method is:
00727 %
00728 %      void MagickFatalError(const ExceptionType error,const char *reason,
00729 %        const char *description)
00730 %
00731 %  A description of each parameter follows:
00732 %
00733 %    o exception: Specifies the numeric error category.
00734 %
00735 %    o reason: Specifies the reason to display before terminating the
00736 %      program.
00737 %
00738 %    o description: Specifies any description to the reason.
00739 %
00740 */
00741 MagickExport void MagickFatalError(const ExceptionType error,const char *reason,
00742   const char *description)
00743 {
00744   if (fatal_error_handler != (ErrorHandler) NULL)
00745     (*fatal_error_handler)(error,reason,description);
00746 }
00747 
00748 /*
00749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00750 %                                                                             %
00751 %                                                                             %
00752 %                                                                             %
00753 %   M a g i c k W a r n i n g                                                 %
00754 %                                                                             %
00755 %                                                                             %
00756 %                                                                             %
00757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00758 %
00759 %  MagickWarning() calls the warning handler methods with a warning reason.
00760 %
00761 %  The format of the MagickWarning method is:
00762 %
00763 %      void MagickWarning(const ExceptionType warning,const char *reason,
00764 %        const char *description)
00765 %
00766 %  A description of each parameter follows:
00767 %
00768 %    o warning: the warning severity.
00769 %
00770 %    o reason: Define the reason for the warning.
00771 %
00772 %    o description: Describe the warning.
00773 %
00774 */
00775 MagickExport void MagickWarning(const ExceptionType warning,const char *reason,
00776   const char *description)
00777 {
00778   if (warning_handler != (WarningHandler) NULL)
00779     (*warning_handler)(warning,reason,description);
00780 }
00781 
00782 /*
00783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00784 %                                                                             %
00785 %                                                                             %
00786 %                                                                             %
00787 %   S e t E r r o r H a n d l e r                                             %
00788 %                                                                             %
00789 %                                                                             %
00790 %                                                                             %
00791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00792 %
00793 %  SetErrorHandler() sets the exception handler to the specified method
00794 %  and returns the previous exception handler.
00795 %
00796 %  The format of the SetErrorHandler method is:
00797 %
00798 %      ErrorHandler SetErrorHandler(ErrorHandler handler)
00799 %
00800 %  A description of each parameter follows:
00801 %
00802 %    o handler: the method to handle errors.
00803 %
00804 */
00805 MagickExport ErrorHandler SetErrorHandler(ErrorHandler handler)
00806 {
00807   ErrorHandler
00808     previous_handler;
00809 
00810   previous_handler=error_handler;
00811   error_handler=handler;
00812   return(previous_handler);
00813 }
00814 
00815 /*
00816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00817 %                                                                             %
00818 %                                                                             %
00819 %                                                                             %
00820 %   S e t F a t a l E r r o r H a n d l e r                                   %
00821 %                                                                             %
00822 %                                                                             %
00823 %                                                                             %
00824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00825 %
00826 %  SetFatalErrorHandler() sets the fatal exception handler to the specified
00827 %  method and returns the previous fatal exception handler.
00828 %
00829 %  The format of the SetErrorHandler method is:
00830 %
00831 %      ErrorHandler SetErrorHandler(ErrorHandler handler)
00832 %
00833 %  A description of each parameter follows:
00834 %
00835 %    o handler: the method to handle errors.
00836 %
00837 */
00838 MagickExport FatalErrorHandler SetFatalErrorHandler(FatalErrorHandler handler)
00839 {
00840   FatalErrorHandler
00841     previous_handler;
00842 
00843   previous_handler=fatal_error_handler;
00844   fatal_error_handler=handler;
00845   return(previous_handler);
00846 }
00847 
00848 /*
00849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00850 %                                                                             %
00851 %                                                                             %
00852 %                                                                             %
00853 %   S e t W a r n i n g H a n d l e r                                         %
00854 %                                                                             %
00855 %                                                                             %
00856 %                                                                             %
00857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00858 %
00859 %  SetWarningHandler() sets the warning handler to the specified method
00860 %  and returns the previous warning handler.
00861 %
00862 %  The format of the SetWarningHandler method is:
00863 %
00864 %      ErrorHandler SetWarningHandler(ErrorHandler handler)
00865 %
00866 %  A description of each parameter follows:
00867 %
00868 %    o handler: the method to handle warnings.
00869 %
00870 */
00871 MagickExport WarningHandler SetWarningHandler(WarningHandler handler)
00872 {
00873   WarningHandler
00874     previous_handler;
00875 
00876   previous_handler=warning_handler;
00877   warning_handler=handler;
00878   return(previous_handler);
00879 }
00880 
00881 /*
00882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00883 %                                                                             %
00884 %                                                                             %
00885 %                                                                             %
00886 %   T h r o w E x c e p t i o n                                               %
00887 %                                                                             %
00888 %                                                                             %
00889 %                                                                             %
00890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00891 %
00892 %  ThrowException() throws an exception with the specified severity code,
00893 %  reason, and optional description.
00894 %
00895 %  The format of the ThrowException method is:
00896 %
00897 %      MagickBooleanType ThrowException(ExceptionInfo *exception,
00898 %        const ExceptionType severity,const char *reason,
00899 %        const char *description)
00900 %
00901 %  A description of each parameter follows:
00902 %
00903 %    o exception: the exception info.
00904 %
00905 %    o severity: the severity of the exception.
00906 %
00907 %    o reason: the reason for the exception.
00908 %
00909 %    o description: the exception description.
00910 %
00911 */
00912 MagickExport MagickBooleanType ThrowException(ExceptionInfo *exception,
00913   const ExceptionType severity,const char *reason,const char *description)
00914 {
00915   register ExceptionInfo
00916     *p;
00917 
00918   assert(exception != (ExceptionInfo *) NULL);
00919   assert(exception->signature == MagickSignature);
00920   p=(ExceptionInfo *) GetLastValueInLinkedList((LinkedListInfo *)
00921     exception->exceptions);
00922   if ((p != (ExceptionInfo *) NULL) && (p->severity == severity) &&
00923       (LocaleCompare(exception->reason,reason) == 0) &&
00924       (LocaleCompare(exception->description,description) == 0))
00925     return(MagickTrue);
00926   p=(ExceptionInfo *) AcquireMagickMemory(sizeof(*p));
00927   if (p == (ExceptionInfo *) NULL)
00928     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00929   (void) ResetMagickMemory(p,0,sizeof(*p));
00930   p->severity=severity;
00931   if (reason != (const char *) NULL)
00932     p->reason=ConstantString(reason);
00933   if (description != (const char *) NULL)
00934     p->description=ConstantString(description);
00935   p->signature=MagickSignature;
00936   (void) AppendValueToLinkedList((LinkedListInfo *) exception->exceptions,p);
00937   exception->severity=p->severity;
00938   exception->reason=p->reason;
00939   exception->description=p->description;
00940   return(MagickTrue);
00941 }
00942 
00943 /*
00944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00945 %                                                                             %
00946 %                                                                             %
00947 %                                                                             %
00948 %   T h r o w M a g i c k E x c e p t i o n                                   %
00949 %                                                                             %
00950 %                                                                             %
00951 %                                                                             %
00952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00953 %
00954 %  ThrowMagickException logs an exception as determined by the log configuration
00955 %  file.  If an error occurs, MagickFalse is returned otherwise MagickTrue.
00956 %
00957 %  The format of the ThrowMagickException method is:
00958 %
00959 %      MagickBooleanType ThrowFileException(ExceptionInfo *exception,
00960 %        const char *module,const char *function,const size_t line,
00961 %        const ExceptionType severity,const char *tag,const char *format,...)
00962 %
00963 %  A description of each parameter follows:
00964 %
00965 %    o exception: the exception info.
00966 %
00967 %    o filename: the source module filename.
00968 %
00969 %    o function: the function name.
00970 %
00971 %    o line: the line number of the source module.
00972 %
00973 %    o severity: Specifies the numeric error category.
00974 %
00975 %    o tag: the locale tag.
00976 %
00977 %    o format: the output format.
00978 %
00979 */
00980 
00981 static MagickBooleanType ThrowMagickExceptionList(ExceptionInfo *exception,
00982   const char *module,const char *function,const size_t line,
00983   const ExceptionType severity,const char *tag,const char *format,
00984   va_list operands)
00985 {
00986   char
00987     message[MaxTextExtent],
00988     path[MaxTextExtent],
00989     reason[MaxTextExtent];
00990 
00991   const char
00992     *locale,
00993     *type;
00994 
00995   int
00996     n;
00997 
00998   MagickBooleanType
00999     status;
01000 
01001   size_t
01002     length;
01003 
01004   assert(exception != (ExceptionInfo *) NULL);
01005   assert(exception->signature == MagickSignature);
01006   locale=GetLocaleExceptionMessage(severity,tag);
01007   (void) CopyMagickString(reason,locale,MaxTextExtent);
01008   (void) ConcatenateMagickString(reason," ",MaxTextExtent);
01009   length=strlen(reason);
01010 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
01011   n=vsnprintf(reason+length,MaxTextExtent-length,format,operands);
01012 #else
01013   n=vsprintf(reason+length,format,operands);
01014 #endif
01015   if (n < 0)
01016     reason[MaxTextExtent-1]='\0';
01017   status=LogMagickEvent(ExceptionEvent,module,function,line,"%s",reason);
01018   GetPathComponent(module,TailPath,path);
01019   type="undefined";
01020   if ((severity >= WarningException) && (severity < ErrorException))
01021     type="warning";
01022   if ((severity >= ErrorException) && (severity < FatalErrorException))
01023     type="error";
01024   if (severity >= FatalErrorException)
01025     type="fatal";
01026   (void) FormatLocaleString(message,MaxTextExtent,"%s @ %s/%s/%s/%.20g",reason,
01027     type,path,function,(double) line);
01028   (void) ThrowException(exception,severity,message,(char *) NULL);
01029   return(status);
01030 }
01031 
01032 MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception,
01033   const char *module,const char *function,const size_t line,
01034   const ExceptionType severity,const char *tag,const char *format,...)
01035 {
01036   MagickBooleanType
01037     status;
01038 
01039   va_list
01040     operands;
01041 
01042   va_start(operands,format);
01043   status=ThrowMagickExceptionList(exception,module,function,line,severity,tag,
01044     format,operands);
01045   va_end(operands);
01046   return(status);
01047 }