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