]> granicus.if.org Git - imagemagick/commitdiff
Exception handling for CLI Wands.
authoranthony <anthony@git.imagemagick.org>
Tue, 10 Apr 2012 13:02:37 +0000 (13:02 +0000)
committeranthony <anthony@git.imagemagick.org>
Tue, 10 Apr 2012 13:02:37 +0000 (13:02 +0000)
Preparations to disable depreciation meessages in "convert"

MagickCore/exception.c
MagickCore/exception.h
MagickWand/magick-cli.c
MagickWand/magick-cli.h
MagickWand/operation.c
MagickWand/wandcli-private.h
MagickWand/wandcli.c
MagickWand/wandcli.h

index 9971d052b27e8ae9955790b7c861ee3fbd899363..492ef23675d0ff59f3f98b4b85adac03ba709609 100644 (file)
@@ -951,8 +951,9 @@ MagickExport MagickBooleanType ThrowException(ExceptionInfo *exception,
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  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:
 %
@@ -978,7 +979,7 @@ MagickExport MagickBooleanType ThrowException(ExceptionInfo *exception,
 %
 */
 
-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)
index f6558f336474738d09cbe7245ae327d8e628da6b..581c035b115d2eab2f400a0ae27d0a4c7f29a35f 100644 (file)
@@ -153,6 +153,8 @@ extern MagickExport FatalErrorHandler
 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)));
index 4677e3243731954abaef7b8d939fd9d3e753817e..27d3c3a0141344c618eeaf314fe7945a6e7adab6 100644 (file)
@@ -55,6 +55,7 @@
 #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
 /*
@@ -94,7 +85,7 @@ static void OutputOptions(ImageInfo *image_info)
     if (value != (const char *) NULL)
       (void) FormatLocaleFile(stdout,"%s\n",value);
   }
-  ResetImageOptionIterator(image_info); 
+  ResetImageOptionIterator(image_info);
 }
 
 static void OutputArtifacts(Image *image)
@@ -202,15 +193,13 @@ WandExport void ProcessScriptOptions(MagickCLI *cli_wand,int argc,char **argv,
   /* 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
@@ -434,7 +423,7 @@ next_token:
 %
 */
 WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
-     char **argv, int index, ProcessOptionFlags process_flags )
+     char **argv, int index )
 {
   const char
     *option,
@@ -459,22 +448,21 @@ WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
     (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;
@@ -491,14 +479,14 @@ WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
       (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
@@ -543,7 +531,7 @@ WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
     }
 
     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 */
@@ -577,10 +565,10 @@ next_argument:
   }
   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
@@ -723,7 +711,7 @@ static void MagickUsage(MagickBooleanType verbose)
    however the last argument provides the output filename.
 */
 static MagickBooleanType ConcatenateImages(int argc,char **argv,
-  ExceptionInfo *exception)
+     ExceptionInfo *exception )
 {
   FILE
     *input,
@@ -737,8 +725,7 @@ static MagickBooleanType ConcatenateImages(int argc,char **argv,
 
   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++) {
@@ -760,15 +747,9 @@ WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,
   MagickCLI
     *cli_wand;
 
-  const char
-    *option;
-
   size_t
     len;
 
-  ProcessOptionFlags
-    process_flags = MagickCommandOptionFlags;
-
   /* For specific OS command line requirements */
   ReadCommandlLine(argc,&argv);
 
@@ -791,7 +772,7 @@ WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,
 
   /* "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");*/
   }
@@ -807,17 +788,16 @@ WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,
 
   /* 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;
@@ -857,12 +837,13 @@ WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,
   }
   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)
index ecf8f5cbb9f0f5ae571a54af1cda9bf089aafa43..692eabeaa7ce6227bf432c65b4b303d9a3082227 100644 (file)
 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 *);
index 9925816ab0cfa01abd6fcc02fcddb769e462d07a..4f2f2849b3d3856d59e12206ba9e2b43f130d308 100644 (file)
@@ -4663,7 +4663,7 @@ WandExport void CLISpecialOperator(MagickCLI *cli_wand,
 
 #if 0
   // Other 'special' options this should handle
-  //    "region"
+  //    "region"  "reset"  "arg"
   if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
 #endif
     CLIWandException(OptionError,"UnrecognizedOption",option);
index e0b8a834f7e9b7e6314775d151046ff644b704d5..9c17b249b73ff2c727ed54559ed54d64d50a30bb 100644 (file)
@@ -23,26 +23,56 @@ extern "C" {
 #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
@@ -75,22 +105,23 @@ struct _MagickCLI       /* CLI interface version of MagickWand */
     *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
index e6c0259347114ebd03ba1e553fe4c83101b8a44c..8363edf977fe29a634251876ebfe6169024f9cd3 100644 (file)
@@ -47,6 +47,7 @@
 #include "MagickWand/magick-wand-private.h"
 #include "MagickWand/wandcli.h"
 #include "MagickWand/wandcli-private.h"
+#include "MagickCore/exception.h"
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -118,13 +119,17 @@ WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info,
   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);
@@ -242,3 +247,54 @@ WandExport MagickBooleanType CLICatchException(MagickCLI *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);
+}
index d386395cd77201186c5046461c007d4f700a7133..0d07f154a987df527aa81bb10bcfbddf5f649c1f 100644 (file)
@@ -30,7 +30,11 @@ extern WandExport MagickCLI
   *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)
 }