% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% ThrowMagickException logs an exception as determined by the log configuration
-% file. If an error occurs, MagickFalse is returned otherwise MagickTrue.
+% ThrowMagickException logs an exception as determined by the log
+% configuration file. If an error occurs, MagickFalse is returned
+% otherwise MagickTrue.
%
% The format of the ThrowMagickException method is:
%
%
*/
-static MagickBooleanType ThrowMagickExceptionList(ExceptionInfo *exception,
+MagickExport MagickBooleanType ThrowMagickExceptionList(ExceptionInfo *exception,
const char *module,const char *function,const size_t line,
const ExceptionType severity,const char *tag,const char *format,
va_list operands)
extern MagickExport MagickBooleanType
ThrowException(ExceptionInfo *,const ExceptionType,const char *,
const char *),
+ ThrowMagickExceptionList(ExceptionInfo *,const char *,const char *,const size_t,
+ const ExceptionType,const char *,const char *,va_list),
ThrowMagickException(ExceptionInfo *,const char *,const char *,const size_t,
const ExceptionType,const char *,const char *,...)
magick_attribute((__format__ (__printf__,7,8)));
#include "MagickWand/magick-cli.h"
#include "MagickWand/script-token.h"
#include "MagickCore/utility-private.h"
+#include "MagickCore/exception-private.h"
#include "MagickCore/version.h"
\f
/* verbose debugging,
*/
#define MagickCommandDebug 0
-#define ThrowFileException(exception,severity,tag,context) \
-{ \
- char \
- *message; \
- \
- message=GetExceptionMessage(errno); \
- (void) ThrowMagickException(exception,GetMagickModule(),severity, \
- tag == (const char *) NULL ? "unknown" : tag,"'%s': %s",context,message); \
- message=DestroyString(message); \
-}
#if MagickCommandDebug >= 9
/*
if (value != (const char *) NULL)
(void) FormatLocaleFile(stdout,"%s\n",value);
}
- ResetImageOptionIterator(image_info);
+ ResetImageOptionIterator(image_info);
}
static void OutputArtifacts(Image *image)
/* open file script or stream, and set up tokenizer */
token_info = AcquireScriptTokenInfo(argv[index]);
if (token_info == (ScriptTokenInfo *) NULL) {
- ThrowFileException(cli_wand->wand.exception,OptionFatalError,
- "UnableToOpenScript",argv[index]);
+ CLIWandExceptionFile(OptionFatalError,"UnableToOpenScript",argv[index]);
return;
}
/* define the error location string for use in exceptions
- order of input escapes: option, (arg), filename, line, column */
- cli_wand->location="'%s' in \"%s\" line %u column %u";
- cli_wand->location2="'%s' '%s' in \"%s\" line %u column %u";
+ order of localtion format escapes: filename, line, column */
+ cli_wand->location="in \"%s\" at line %u,column %u";
if ( LocaleCompare("-", argv[index]) == 0 )
cli_wand->filename="stdin";
else
%
*/
WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
- char **argv, int index, ProcessOptionFlags process_flags )
+ char **argv, int index )
{
const char
*option,
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
/* define the error location string for use in exceptions
- order of input escapes: option, (arg), filename, line, column */
- cli_wand->location="'%s' %s arg %u";
- cli_wand->location2="'%s' '%s' %s arg %u";
+ order of localtion format escapes: filename, line, column */
+ cli_wand->location="at %s argument %u";
cli_wand->filename="CLI";
end = argc;
- if ( ( process_flags & ProcessOutputFile ) != 0 )
- end--;
+ if ( (cli_wand->process_flags & ProcessImpliedWrite) != 0 )
+ end--; /* the last arument is an implied write, do not process directly */
for (i=index; i < end; i += count +1) {
/* Finished processing one option? */
- if ( ( process_flags & ProcessOneOptionOnly ) != 0 && i != index )
+ if ( (cli_wand->process_flags & ProcessOneOptionOnly) != 0 && i != index )
return(i);
option=argv[i];
- cli_wand->line=i;
+ cli_wand->line=i; /* note the argument for this option */
{ const OptionInfo *option_info = GetCommandOptionInfo(argv[i]);
count=option_info->type;
(void) FormatLocaleFile(stderr, "CLI %d Non-Option: \"%s\"\n", i, option);
#endif
if ( IfMagickFalse(IsCommandOption(option)) ) {
- if ( (process_flags & ProcessNonOptionImageRead) != 0 )
+ if ( (cli_wand->process_flags & ProcessNonOptionImageRead) != 0 )
/* non-option -- treat as a image read */
CLISpecialOperator(cli_wand,"-read",option);
else
CLIWandException(OptionFatalError,"UnrecognizedOption",option);
goto next_argument;
}
- if ( ((process_flags & ProcessScriptOption) != 0) &&
+ if ( ((cli_wand->process_flags & ProcessScriptOption) != 0) &&
(LocaleCompare(option,"-script") == 0) ) {
/* Call Script from CLI, with a filename as a zeroth argument.
NOTE: -script may need to use 'implict write filename' so it
}
if ( (option_type & SpecialOptionFlag) != 0 ) {
- if ( ( process_flags & ProcessExitOption ) != 0
+ if ( (cli_wand->process_flags & ProcessExitOption) != 0
&& LocaleCompare(option,"-exit") == 0 )
return(i+count);
/* handle any other special operators now */
}
assert(i==end);
- if ( ( process_flags & ProcessOutputFile ) == 0 )
- return(end);
+ if ( (cli_wand->process_flags & ProcessImpliedWrite) == 0 )
+ return(end); /* no implied write -- just return to caller */
- assert(end==argc-1);
+ assert(end==argc-1); /* end should not include last argument */
/*
Implicit Write of images to final CLI argument
however the last argument provides the output filename.
*/
static MagickBooleanType ConcatenateImages(int argc,char **argv,
- ExceptionInfo *exception)
+ ExceptionInfo *exception )
{
FILE
*input,
output=fopen_utf8(argv[argc-1],"wb");
if (output == (FILE *) NULL) {
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- argv[argc-1]);
+ ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[argc-1]);
return(MagickFalse);
}
for (i=2; i < (ssize_t) (argc-1); i++) {
MagickCLI
*cli_wand;
- const char
- *option;
-
size_t
len;
- ProcessOptionFlags
- process_flags = MagickCommandOptionFlags;
-
/* For specific OS command line requirements */
ReadCommandlLine(argc,&argv);
/* "convert" command - give a "depreciation" warning" */
if (len>=7 && LocaleCompare("convert",argv[0]+len-7) == 0) {
- process_flags = ConvertCommandOptionFlags;
+ cli_wand->process_flags = ConvertCommandOptionFlags;
/*(void) FormatLocaleFile(stderr,"WARNING: %s\n",
"The convert is depreciated in IMv7, use \"magick\"\n");*/
}
/* Special Case: Version Information and Abort */
if (argc == 2) {
- option=argv[1];
- if (LocaleCompare("-version",option) == 0) {
+ if (LocaleCompare("-version",argv[1]) == 0) {
CLISpecialOperator(cli_wand, "-version", (char *)NULL);
goto Magick_Command_Exit;
}
- if ((LocaleCompare("-help",option) == 0) || /* GNU standard option */
- (LocaleCompare("--help",option) == 0) ) {
+ if ((LocaleCompare("-help",argv[1]) == 0) || /* GNU standard option */
+ (LocaleCompare("--help",argv[1]) == 0) ) {
MagickUsage(MagickFalse);
goto Magick_Command_Exit;
}
- if (LocaleCompare("-usage",option) == 0) {
+ if (LocaleCompare("-usage",argv[1]) == 0) {
CLISpecialOperator(cli_wand, "-version", (char *)NULL);
MagickUsage(MagickTrue);
goto Magick_Command_Exit;
}
else {
/* Normal Command Line, assumes output file as last option */
- ProcessCommandOptions(cli_wand,argc,argv,1, process_flags);
+ ProcessCommandOptions(cli_wand,argc,argv,1);
}
/* ------------- */
Magick_Command_Cleanup:
- /* recover original image_info and clean up stacks */
+ /* recover original image_info and clean up stacks
+ FUTURE: "-reset stacks" option */
while (cli_wand->image_list_stack != (Stack *)NULL)
CLISpecialOperator(cli_wand,")",(const char *)NULL);
while (cli_wand->image_info_stack != (Stack *)NULL)
extern "C" {
#endif
-typedef enum
-{
- /* What options should be processed */
- /* NonOption Handling */
- ProcessNonOptionImageRead = 0x0001, /* non-option is a image read
- If not set then skip implied read
- without producing an error.
- For use with "mogrify" handling
- */
-
- /* Special Option Handling */
- ProcessExitOption = 0x0100, /* allow '-exit' use */
- ProcessScriptOption = 0x0200, /* allow '-script' use */
- ProcessReadOption = 0x0400, /* allow '-read' use */
-
- /* Option Processing Flags */
- ProcessOneOptionOnly = 0x4000, /* Process One Option Only */
- ProcessOutputFile = 0x8000, /* Process the output file */
-
- /* Flag Groups for specific Situations */
- MagickCommandOptionFlags = 0x8FFF, /* Magick Command Flags */
- ConvertCommandOptionFlags = 0x80FF, /* Convert Command Flags */
- MagickScriptArgsFlags = 0x00FF, /* Script Args Flags */
- MagickScriptReadFlags = 0x01FF /* Script Read Flags - unused */
-
-} ProcessOptionFlags;
-
extern WandExport void
ProcessScriptOptions(MagickCLI *,int,char **,int);
extern WandExport int
- ProcessCommandOptions(MagickCLI *,int,char **,int,ProcessOptionFlags);
+ ProcessCommandOptions(MagickCLI *,int,char **,int);
extern WandExport MagickBooleanType
MagickImageCommand(ImageInfo *,int,char **,char **,ExceptionInfo *);
#if 0
// Other 'special' options this should handle
- // "region"
+ // "region" "reset" "arg"
if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
#endif
CLIWandException(OptionError,"UnrecognizedOption",option);
#endif
#define CLIWandException(severity,tag,option) \
- (void) ThrowMagickException(cli_wand->wand.exception,GetMagickModule(), \
- severity,tag,cli_wand->location,option,cli_wand->filename, \
- cli_wand->line,cli_wand->column)
+ (void) CLIThrowException(cli_wand,GetMagickModule(),severity,tag, \
+ "'%s'",option)
#define CLIWandExceptionArg(severity,tag,option,arg) \
- (void) ThrowMagickException(cli_wand->wand.exception,GetMagickModule(), \
- severity,tag,cli_wand->location2,option,arg,cli_wand->filename, \
- cli_wand->line,cli_wand->column)
+ (void) CLIThrowException(cli_wand,GetMagickModule(),severity,tag, \
+ "'%s' '%s'",option, arg)
+
+#define CLIWandExceptionFile(severity,tag,context) \
+{ char *message=GetExceptionMessage(errno); \
+ (void) CLIThrowException(cli_wand,GetMagickModule(),severity,tag, \
+ "'%s': %s",context,message); \
+ message=DestroyString(message); \
+}
#define CLIWandExceptionBreak(severity,tag,option) \
{ CLIWandException(severity,tag,option); break; }
#define CLIWandExceptionReturn(severity,tag,option) \
- { CLIWandException(severity,tag,option); return; }
+ { CLIWandException(severity,tag,option); return; }
#define CLIWandExceptArgBreak(severity,tag,option,arg) \
- { CLIWandExceptionArg(severity,tag,option,arg); break; }
+ { CLIWandExceptionArg(severity,tag,option,arg); break; }
#define CLIWandExceptArgReturn(severity,tag,option,arg) \
- { CLIWandExceptionArg(severity,tag,option,arg); return; }
+ { CLIWandExceptionArg(severity,tag,option,arg); return; }
+
+
+/* Define how options should be processed */
+typedef enum
+{
+ /* NonOption Handling */
+ ProcessNonOptionImageRead = 0x0001, /* A non-option is a image read
+ If not set then skip implied read
+ without producing an error.
+ For use with "mogrify" handling */
+
+ /* Special Option Handling */
+ ProcessExitOption = 0x0100, /* allow '-exit' use */
+ ProcessScriptOption = 0x0200, /* allow '-script' use */
+ ProcessReadOption = 0x0400, /* allow '-read' use */
+
+ /* Option Processing Flags */
+ ProcessOneOptionOnly = 0x4000, /* Process one option only */
+ ProcessImpliedWrite = 0x8000, /* Last arg is an implied write */
+
+ /* Flag Groups for specific Situations */
+ MagickCommandOptionFlags = 0x8F0F, /* Magick Command Flags */
+ ConvertCommandOptionFlags = 0x800F, /* Convert Command Flags */
+ MagickScriptArgsFlags = 0x000F, /* Script CLI Process Args Flags */
+} ProcessOptionFlags;
/* Define a generic stack linked list, for pushing and popping
*image_list_stack, /* Stacks of Image Lists and Image Info settings */
*image_info_stack;
- const char /* Location string for exception reporting */
- *filename, /* See CLIWandException() macro above */
- *location, /* EG: "'%s' @ \"%s\" line %u column %u"
- option, filename, line, column */
- *location2; /* EG: "'%s' '%s' @ \"%s\" line %u column %u"
- option, arg, filename, line, column */
+ ProcessOptionFlags
+ process_flags; /* when handling CLI, what options do we process? */
+
+ const char /* Location of option being processed for exception */
+ *location, /* location format string for exception reports */
+ *filename; /* "CLI", "unknown", or script filename */
size_t
- line, /* location of current option for error above */
- column;
+ line, /* location of current option from source */
+ column; /* note: line also used for cli argument count */
size_t
signature;
};
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#include "MagickWand/magick-wand-private.h"
#include "MagickWand/wandcli.h"
#include "MagickWand/wandcli-private.h"
+#include "MagickCore/exception.h"
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
cli_wand->image_list_stack=(Stack *)NULL;
cli_wand->image_info_stack=(Stack *)NULL;
- cli_wand->location="'%s'"; /* option location not known by default */
- cli_wand->location2="'%s' '%s'";
- cli_wand->filename=cli_wand->wand.name;
+ cli_wand->process_flags=MagickCommandOptionFlags; /* assume "magick" CLI */
+
+ /* default exception location...
+ EG: sprintf(locaiton, filename, line, column);
+ */
+ cli_wand->location="from \"%s\""; /* location format: */
+ cli_wand->filename="unknown"; /* unknown source */
cli_wand->line=0;
cli_wand->column=0;
- cli_wand->signature=WandSignature;
+ cli_wand->signature=WandSignature;
if (IfMagickTrue(cli_wand->wand.debug))
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
return(cli_wand);
return(status);
}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C L I T h r o w E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CLIThrowException() formats and records an exception condition, 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[MaxTextExtent];
+
+ size_t
+ len;
+
+ MagickBooleanType
+ status;
+
+ va_list
+ operands;
+
+ /* HACK - append location to format string.
+ The better way would be append location formats and add more arguments to
+ operands, but that does not appear to be posible!
+ Note: ThrowMagickExceptionList() was exported specifically for
+ the use of this function.
+ */
+ (void) CopyMagickString(new_format,format,MaxTextExtent);
+ (void) ConcatenateMagickString(new_format," ",MaxTextExtent);
+
+ len=strlen(new_format);
+ (void) FormatLocaleString(new_format+len,MaxTextExtent-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);
+}
*DestroyMagickCLI(MagickCLI *);
extern WandExport MagickBooleanType
- CLICatchException(MagickCLI *,const MagickBooleanType);
+ CLICatchException(MagickCLI *,const MagickBooleanType),
+ CLIThrowException(MagickCLI *,const char *,const char *,const size_t,
+ const ExceptionType,const char *,const char *,...)
+ magick_attribute((__format__ (__printf__,7,8)));
+
#if defined(__cplusplus) || defined(c_plusplus)
}