|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% W W AA N N DDD CCC L III % |
|
|
% W W A A NN N D D C L I % |
|
|
% W W W AAAA N N N D D C L I % |
|
|
% W W W A A N NN D D C L I % |
|
|
% W W A A N N DDD CCC LLLL III % |
|
|
% % |
|
|
% WandCLI Structure Methods % |
|
|
% % |
|
|
% Dragon Computing % |
|
|
% Anthony Thyssen % |
|
|
% April 2011 % |
|
|
% % |
|
|
% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % |
|
|
% dedicated to making software imaging solutions freely available. % |
|
|
% % |
|
|
% You may not use this file except in compliance with the License. You may % |
|
|
% obtain a copy of the License at % |
|
|
% % |
|
|
% http://www.imagemagick.org/script/license.php % |
|
|
% % |
|
|
% Unless required by applicable law or agreed to in writing, software % |
|
|
% distributed under the License is distributed on an "AS IS" BASIS, % |
|
|
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
|
|
% See the License for the specific language governing permissions and % |
|
|
% limitations under the License. % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% General methds for handling the WandCLI structure used for Command Line. |
|
|
% |
|
|
% Anthony Thyssen, April 2011 |
|
|
*/ |
|
|
|
|
|
/* |
|
|
Include declarations. |
|
|
*/ |
|
|
#include "MagickWand/studio.h" |
|
|
#include "MagickWand/MagickWand.h" |
|
|
#include "MagickWand/wand.h" |
|
|
#include "MagickWand/magick-wand-private.h" |
|
|
#include "MagickWand/wandcli.h" |
|
|
#include "MagickWand/wandcli-private.h" |
|
|
#include "MagickCore/exception.h" |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ A c q u i r e W a n d C L I % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% AcquireMagickCLI() creates a new CLI wand (an expanded form of Magick |
|
|
% Wand). The given image_info and exception is included as is if provided. |
|
|
% |
|
|
% Use DestroyMagickCLI() to dispose of the CLI wand when it is no longer |
|
|
% needed. |
|
|
% |
|
|
% The format of the NewMagickWand method is: |
|
|
% |
|
|
% MagickCLI *AcquireMagickCLI(ImageInfo *image_info, |
|
|
% ExceptionInfo *exception) |
|
|
% |
|
|
*/ |
|
|
WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info, |
|
|
ExceptionInfo *exception) |
|
|
{ |
|
|
MagickCLI |
|
|
*cli_wand; |
|
|
|
|
|
/* precaution - as per NewMagickWand() */ |
|
|
{ |
|
|
size_t depth = MAGICKCORE_QUANTUM_DEPTH; |
|
|
const char *quantum = GetMagickQuantumDepth(&depth); |
|
|
if (depth != MAGICKCORE_QUANTUM_DEPTH) |
|
|
ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum); |
|
|
} |
|
|
|
|
|
/* allocate memory for MgaickCLI */ |
|
|
cli_wand=(MagickCLI *) AcquireMagickMemory(sizeof(*cli_wand)); |
|
|
if (cli_wand == (MagickCLI *) NULL) |
|
|
ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", |
|
|
GetExceptionMessage(errno)); |
|
|
|
|
|
/* Initialize Wand Part of MagickCLI |
|
|
FUTURE: this is a repeat of code from NewMagickWand() |
|
|
However some parts may be given fro man external source! |
|
|
*/ |
|
|
cli_wand->wand.id=AcquireWandId(); |
|
|
(void) FormatLocaleString(cli_wand->wand.name,MagickPathExtent, |
|
|
"%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id); |
|
|
cli_wand->wand.images=NewImageList(); |
|
|
if ( image_info == (ImageInfo *) NULL) |
|
|
cli_wand->wand.image_info=AcquireImageInfo(); |
|
|
else |
|
|
cli_wand->wand.image_info=image_info; |
|
|
if ( exception == (ExceptionInfo *) NULL) |
|
|
cli_wand->wand.exception=AcquireExceptionInfo(); |
|
|
else |
|
|
cli_wand->wand.exception=exception; |
|
|
cli_wand->wand.debug=IsEventLogging(); |
|
|
cli_wand->wand.signature=MagickWandSignature; |
|
|
|
|
|
/* Initialize CLI Part of MagickCLI */ |
|
|
cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL); |
|
|
cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info); |
|
|
cli_wand->process_flags=MagickCommandOptionFlags; /* assume "magick" CLI */ |
|
|
cli_wand->command=(const OptionInfo *) NULL; /* no option at this time */ |
|
|
cli_wand->image_list_stack=(Stack *) NULL; |
|
|
cli_wand->image_info_stack=(Stack *) NULL; |
|
|
|
|
|
/* default exception location... |
|
|
EG: sprintf(locaiton, filename, line, column); |
|
|
*/ |
|
|
cli_wand->location="from \"%s\""; /* location format using arguments: */ |
|
|
/* filename, line, column */ |
|
|
cli_wand->filename="unknown"; /* script filename, unknown source */ |
|
|
cli_wand->line=0; /* line from script OR CLI argument */ |
|
|
cli_wand->column=0; /* column from script */ |
|
|
|
|
|
cli_wand->signature=MagickWandSignature; |
|
|
if (cli_wand->wand.debug != MagickFalse) |
|
|
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); |
|
|
return(cli_wand); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ D e s t r o y W a n d C L I % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% DestroyMagickCLI() destorys everything in a CLI wand, including image_info |
|
|
% and any exceptions, if still present in the wand. |
|
|
% |
|
|
% The format of the NewMagickWand method is: |
|
|
% |
|
|
% MagickWand *DestroyMagickCLI() |
|
|
% Exception *exception) |
|
|
% |
|
|
*/ |
|
|
WandExport MagickCLI *DestroyMagickCLI(MagickCLI *cli_wand) |
|
|
{ |
|
|
Stack |
|
|
*node; |
|
|
|
|
|
assert(cli_wand != (MagickCLI *) NULL); |
|
|
assert(cli_wand->signature == MagickWandSignature); |
|
|
assert(cli_wand->wand.signature == MagickWandSignature); |
|
|
if (cli_wand->wand.debug != MagickFalse) |
|
|
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); |
|
|
|
|
|
/* Destroy CLI part of MagickCLI */ |
|
|
if (cli_wand->draw_info != (DrawInfo *) NULL ) |
|
|
cli_wand->draw_info=DestroyDrawInfo(cli_wand->draw_info); |
|
|
if (cli_wand->quantize_info != (QuantizeInfo *) NULL ) |
|
|
cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info); |
|
|
while(cli_wand->image_list_stack != (Stack *) NULL) |
|
|
{ |
|
|
node=cli_wand->image_list_stack; |
|
|
cli_wand->image_list_stack=node->next; |
|
|
(void) DestroyImageList((Image *)node->data); |
|
|
(void) RelinquishMagickMemory(node); |
|
|
} |
|
|
while(cli_wand->image_info_stack != (Stack *) NULL) |
|
|
{ |
|
|
node=cli_wand->image_info_stack; |
|
|
cli_wand->image_info_stack=node->next; |
|
|
(void) DestroyImageInfo((ImageInfo *)node->data); |
|
|
(void) RelinquishMagickMemory(node); |
|
|
} |
|
|
cli_wand->signature=(~MagickWandSignature); |
|
|
|
|
|
/* Destroy Wand part MagickCLI */ |
|
|
cli_wand->wand.images=DestroyImageList(cli_wand->wand.images); |
|
|
if (cli_wand->wand.image_info != (ImageInfo *) NULL ) |
|
|
cli_wand->wand.image_info=DestroyImageInfo(cli_wand->wand.image_info); |
|
|
if (cli_wand->wand.exception != (ExceptionInfo *) NULL ) |
|
|
cli_wand->wand.exception=DestroyExceptionInfo(cli_wand->wand.exception); |
|
|
RelinquishWandId(cli_wand->wand.id); |
|
|
cli_wand->wand.signature=(~MagickWandSignature); |
|
|
cli_wand=(MagickCLI *) RelinquishMagickMemory(cli_wand); |
|
|
return((MagickCLI *) NULL); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ C L I C a t c h E x c e p t i o n % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% CLICatchException() will report exceptions, either just non-fatal warnings |
|
|
% only, or all errors, according to 'all_execeptions' boolean argument. |
|
|
% |
|
|
% The function returns true if errors are fatal, in which case the caller |
|
|
% should abort and re-call with an 'all_exceptions' argument of true before |
|
|
% quitting. |
|
|
% |
|
|
% The cut-off level between fatal and non-fatal may be controlled by options |
|
|
% (FUTURE), but defaults to 'Error' exceptions. |
|
|
% |
|
|
% The format of the CLICatchException method is: |
|
|
% |
|
|
% MagickBooleanType CLICatchException(MagickCLI *cli_wand, |
|
|
% const MagickBooleanType all_exceptions ); |
|
|
% |
|
|
% Arguments are |
|
|
% |
|
|
% o cli_wand: The Wand CLI that holds the exception Information |
|
|
% |
|
|
% o all_exceptions: Report all exceptions, including the fatal one |
|
|
% |
|
|
*/ |
|
|
WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand, |
|
|
const MagickBooleanType all_exceptions) |
|
|
{ |
|
|
MagickBooleanType |
|
|
status; |
|
|
|
|
|
assert(cli_wand != (MagickCLI *) NULL); |
|
|
assert(cli_wand->signature == MagickWandSignature); |
|
|
assert(cli_wand->wand.signature == MagickWandSignature); |
|
|
if (cli_wand->wand.debug != MagickFalse) |
|
|
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); |
|
|
|
|
|
// FUTURE: '-regard_warning' should make this more sensitive. |
|
|
// Note pipelined options may like more control over this level |
|
|
|
|
|
status=cli_wand->wand.exception->severity > ErrorException ? MagickTrue : |
|
|
MagickFalse; |
|
|
|
|
|
if ((status == MagickFalse) || (all_exceptions != MagickFalse)) |
|
|
CatchException(cli_wand->wand.exception); /* output and clear exceptions */ |
|
|
|
|
|
return(status); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ C L I L o g E v e n t % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% CLILogEvent() is a wrapper around LogMagickEvent(), adding to it the |
|
|
% location of the option that is (about) to be executed. |
|
|
% |
|
|
*/ |
|
|
WandExport MagickBooleanType CLILogEvent(MagickCLI *cli_wand, |
|
|
const LogEventType type,const char *module,const char *function, |
|
|
const size_t line,const char *format,...) |
|
|
{ |
|
|
char |
|
|
new_format[MagickPathExtent]; |
|
|
|
|
|
MagickBooleanType |
|
|
status; |
|
|
|
|
|
va_list |
|
|
operands; |
|
|
|
|
|
/* HACK - prepend the CLI location to format string. |
|
|
The better way would be add more arguments to to the 'va' oparands |
|
|
list, but that does not appear to be possible! So we do some |
|
|
pre-formating of the location info here. |
|
|
*/ |
|
|
(void) FormatLocaleString(new_format,MagickPathExtent,cli_wand->location, |
|
|
cli_wand->filename, cli_wand->line, cli_wand->column); |
|
|
(void) ConcatenateMagickString(new_format," ",MagickPathExtent); |
|
|
(void) ConcatenateMagickString(new_format,format,MagickPathExtent); |
|
|
|
|
|
va_start(operands,format); |
|
|
status=LogMagickEventList(type,module,function,line,new_format,operands); |
|
|
va_end(operands); |
|
|
|
|
|
return(status); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ C L I T h r o w E x c e p t i o n % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% CLIThrowException() is a wrapper around ThrowMagickException(), adding to |
|
|
% it the location of the option that caused the exception to occur. |
|
|
*/ |
|
|
WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand, |
|
|
const char *module,const char *function,const size_t line, |
|
|
const ExceptionType severity,const char *tag,const char *format,...) |
|
|
{ |
|
|
char |
|
|
new_format[MagickPathExtent]; |
|
|
|
|
|
size_t |
|
|
len; |
|
|
|
|
|
MagickBooleanType |
|
|
status; |
|
|
|
|
|
va_list |
|
|
operands; |
|
|
|
|
|
/* HACK - append location to format string. |
|
|
The better way would be add more arguments to to the 'va' oparands |
|
|
list, but that does not appear to be possible! So we do some |
|
|
pre-formating of the location info here. |
|
|
*/ |
|
|
(void) CopyMagickString(new_format,format,MagickPathExtent); |
|
|
(void) ConcatenateMagickString(new_format," ",MagickPathExtent); |
|
|
|
|
|
len=strlen(new_format); |
|
|
(void) FormatLocaleString(new_format+len,MagickPathExtent-len, |
|
|
cli_wand->location,cli_wand->filename,cli_wand->line,cli_wand->column); |
|
|
|
|
|
va_start(operands,format); |
|
|
status=ThrowMagickExceptionList(cli_wand->wand.exception,module,function, |
|
|
line,severity,tag,new_format,operands); |
|
|
va_end(operands); |
|
|
return(status); |
|
|
}
|
|
|
|