Coverage Report

Created: 2026-06-30 07:12

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