]> granicus.if.org Git - imagemagick/commitdiff
Interpret all Option arguments (apart from a select few)
authoranthony <anthony@git.imagemagick.org>
Thu, 17 May 2012 23:39:46 +0000 (23:39 +0000)
committeranthony <anthony@git.imagemagick.org>
Thu, 17 May 2012 23:39:46 +0000 (23:39 +0000)
MagickCore/option.c
MagickCore/option.h
MagickCore/property.c
MagickWand/magick-cli.c
MagickWand/operation.c
MagickWand/tests/README [new file with mode: 0644]
MagickWand/wandcli-private.h
config/english.xml
config/francais.xml

index b9cd40fb86371f59d1c7ad2f80f4e0b76dfe1500..8faa7536c61d687bc579811ade6ee346c7bb3f31 100644 (file)
@@ -199,7 +199,7 @@ static const OptionInfo
     { "+alpha", 1L, DeprecateOptionFlag, MagickTrue },
     { "-alpha", 1L, SimpleOperatorFlag, MagickFalse },
     { "+annotate", 0L, DeprecateOptionFlag, MagickTrue },
-    { "-annotate", 2L, SimpleOperatorFlag, MagickFalse },
+    { "-annotate", 2L, SimpleOperatorFlag | AlwaysInterpretArgsFlag, MagickFalse },
     { "+antialias", 0L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse },
     { "-antialias", 0L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse },
     { "+append", 0L, ListOperatorFlag | FireOptionFlag, MagickFalse },
@@ -339,8 +339,8 @@ static const OptionInfo
     { "-dissolve", 1L, NonMagickOptionFlag, MagickFalse },
     { "+dissimilarity-threshold", 0L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
     { "-dissimilarity-threshold", 1L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
-    { "+distort", 2L, SimpleOperatorFlag, MagickFalse },
-    { "-distort", 2L, SimpleOperatorFlag, MagickFalse },
+    { "+distort", 2L, SimpleOperatorFlag | AlwaysInterpretArgsFlag, MagickFalse },
+    { "-distort", 2L, SimpleOperatorFlag | AlwaysInterpretArgsFlag, MagickFalse },
     { "+dither", 0L, ImageInfoOptionFlag | QuantizeInfoOptionFlag, MagickFalse },
     { "-dither", 1L, ImageInfoOptionFlag | QuantizeInfoOptionFlag, MagickFalse },
     { "+draw", 0L, DeprecateOptionFlag, MagickTrue },
@@ -399,7 +399,7 @@ static const OptionInfo
     { "+frame", 1L, DeprecateOptionFlag, MagickTrue },
     { "-frame", 1L, SimpleOperatorFlag, MagickFalse },
     { "+function", 2L, DeprecateOptionFlag, MagickTrue },
-    { "-function", 2L,SimpleOperatorFlag, MagickFalse },
+    { "-function", 2L,SimpleOperatorFlag | AlwaysInterpretArgsFlag, MagickFalse },
     { "+fuzz", 0L, ImageInfoOptionFlag, MagickFalse },
     { "-fuzz", 1L, ImageInfoOptionFlag, MagickFalse },
     { "+fx", 1L, DeprecateOptionFlag | FireOptionFlag, MagickTrue },
@@ -542,7 +542,7 @@ static const OptionInfo
     { "+preview", 0L, DeprecateOptionFlag, MagickTrue },
     { "-preview", 1L, GlobalOptionFlag, MagickFalse },
     { "+print", 1L, DeprecateOptionFlag | FireOptionFlag, MagickTrue },
-    { "-print", 1L, ListOperatorFlag | FireOptionFlag, MagickFalse },
+    { "-print", 1L, ListOperatorFlag | AlwaysInterpretArgsFlag | FireOptionFlag, MagickFalse },
     { "+process", 1L, DeprecateOptionFlag | FireOptionFlag, MagickTrue },
     { "-process", 1L, ListOperatorFlag | FireOptionFlag, MagickFalse },
     { "+profile", 1L, SimpleOperatorFlag, MagickFalse },
@@ -617,8 +617,8 @@ static const OptionInfo
     { "-separate", 0L, SimpleOperatorFlag | FireOptionFlag, MagickFalse },
     { "+sepia-tone", 1L, DeprecateOptionFlag, MagickTrue },
     { "-sepia-tone", 1L, SimpleOperatorFlag, MagickFalse },
-    { "+set", 1L, SimpleOperatorFlag, MagickFalse },
-    { "-set", 2L, SimpleOperatorFlag, MagickFalse },
+    { "+set", 1L, SimpleOperatorFlag | NeverInterpretArgsFlag, MagickFalse },
+    { "-set", 2L, SimpleOperatorFlag | NeverInterpretArgsFlag, MagickFalse },
     { "+shade", 0L, DeprecateOptionFlag, MagickTrue },
     { "-shade", 1L, SimpleOperatorFlag, MagickFalse },
     { "+shadow", 1L, DeprecateOptionFlag, MagickTrue },
@@ -646,7 +646,7 @@ static const OptionInfo
     { "+solarize", 1L, DeprecateOptionFlag, MagickTrue },
     { "-solarize", 1L, SimpleOperatorFlag, MagickFalse },
     { "+sparse-color", 1L, DeprecateOptionFlag, MagickTrue },
-    { "-sparse-color", 2L, SimpleOperatorFlag, MagickFalse },
+    { "-sparse-color", 2L, SimpleOperatorFlag | AlwaysInterpretArgsFlag, MagickFalse },
     { "+splice", 1L, DeprecateOptionFlag, MagickTrue },
     { "-splice", 1L, SimpleOperatorFlag, MagickFalse },
     { "+spread", 1L, DeprecateOptionFlag, MagickTrue },
index 3a045e5e2fbdcce07f97aaeb6abfc3c15dae0997..ad32b0ec93d6e809e273376464f003863e6a8fb7 100644 (file)
@@ -125,7 +125,7 @@ typedef enum
   DrawInfoOptionFlag        = 0x0002,  /* Setting stored in DrawInfo */
   QuantizeInfoOptionFlag    = 0x0004,  /* Setting stored in QuantizeInfo */
   GlobalOptionFlag          = 0x0008,  /* Global Setting or Control */
-  SettingOptionFlags        = 0x000F,  /* mask for all setting options */
+  SettingOptionFlags        = 0x000F,  /* mask any setting option */
 
   NoImageOperatorFlag       = 0x0010,  /* Images not required operator */
   SimpleOperatorFlag        = 0x0020,  /* Simple Image processing operator */
@@ -135,6 +135,9 @@ typedef enum
   SpecialOptionFlag         = 0x0100,  /* Operator with Special Requirements */
                                        /* EG: for specific CLI commands */
 
+  AlwaysInterpretArgsFlag   = 0x0400,  /* Always Interpret escapes in Args */
+  NeverInterpretArgsFlag    = 0x0800,  /* Never Interpret escapes in Args */
+
   NonMagickOptionFlag       = 0x1000,  /* Option not used by Magick Command */
   FireOptionFlag            = 0x2000,  /* Convert operation seq firing point */
   DeprecateOptionFlag       = 0x4000,  /* Deprecate option (no code) */
index 56ebaaf056c7721c89f781635f431bfbcc1cd630..14df007506c8d6f53ea9ffb53e658a1bd5e8d6e2 100644 (file)
@@ -2955,10 +2955,13 @@ MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
   if( IfMagickTrue(image->debug) )
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
 
-  if ((embed_text == (const char *) NULL) || (*embed_text == '\0'))
+  if ((embed_text == (const char *) NULL))
     return((char *) NULL);
   p=embed_text;
 
+  if (*p == '\0')
+    return(ConstantString(""));
+
   /* handle a '@' replace string from file */
   if (*p == '@') {
      p++;
index 74a383d27c5255d9d3a5fe94cc58bc1a1c557f18..b4d9cd18eccacc0c898cc70e1004d259198cbc2a 100644 (file)
@@ -64,7 +64,6 @@
 */
 #define MagickCommandDebug 0
 
-
 #if MagickCommandDebug >= 9
 /*
   Temporary Debugging Information
@@ -77,13 +76,13 @@ static void OutputOptions(ImageInfo *image_info)
     *option,
     *value;
 
-  (void) FormatLocaleFile(stdout,"  Global Options:\n");
+  (void) FormatLocaleFile(stderr,"  Global Options:\n");
   ResetImageOptionIterator(image_info);
   while ((option=GetNextImageOption(image_info)) != (const char *) NULL ) {
-    (void) FormatLocaleFile(stdout,"    %s: ",option);
+    (void) FormatLocaleFile(stderr,"    %s: ",option);
     value=GetImageOption(image_info,option);
     if (value != (const char *) NULL)
-      (void) FormatLocaleFile(stdout,"%s\n",value);
+      (void) FormatLocaleFile(stderr,"%s\n",value);
   }
   ResetImageOptionIterator(image_info);
 }
@@ -94,13 +93,13 @@ static void OutputArtifacts(Image *image)
     *artifact,
     *value;
 
-  (void) FormatLocaleFile(stdout,"  Image Artifacts:\n");
+  (void) FormatLocaleFile(stderr,"  Image Artifacts:\n");
   ResetImageArtifactIterator(image);
   while ((artifact=GetNextImageArtifact(image)) != (const char *) NULL ) {
-    (void) FormatLocaleFile(stdout,"    %s: ",artifact);
+    (void) FormatLocaleFile(stderr,"    %s: ",artifact);
     value=GetImageArtifact(image,artifact);
     if (value != (const char *) NULL)
-      (void) FormatLocaleFile(stdout,"%s\n",value);
+      (void) FormatLocaleFile(stderr,"%s\n",value);
   }
   ResetImageArtifactIterator(image);
 }
@@ -111,13 +110,13 @@ static void OutputProperties(Image *image,ExceptionInfo *exception)
     *property,
     *value;
 
-  (void) FormatLocaleFile(stdout,"  Image Properity:\n");
+  (void) FormatLocaleFile(stderr,"  Image Properity:\n");
   ResetImagePropertyIterator(image);
   while ((property=GetNextImageProperty(image)) != (const char *) NULL ) {
-    (void) FormatLocaleFile(stdout,"    %s: ",property);
+    (void) FormatLocaleFile(stderr,"    %s: ",property);
     value=GetImageProperty(image,property,exception);
     if (value != (const char *) NULL)
-      (void) FormatLocaleFile(stdout,"%s\n",value);
+      (void) FormatLocaleFile(stderr,"%s\n",value);
   }
   ResetImagePropertyIterator(image);
 }
@@ -216,93 +215,94 @@ WandExport void ProcessScriptOptions(MagickCLI *cli_wand,int argc,char **argv,
         break; /* error or end of options */
     }
 
-    /* save option details */
-    CloneString(&option,token_info->token);
+    do { /* use break to loop to exception handler and loop */
+
+      /* save option details */
+      CloneString(&option,token_info->token);
 
-    /* get option, its argument count, and option type */
-    cli_wand->command = GetCommandOptionInfo(option);
-    count=cli_wand->command->type;
-    option_type=(CommandOptionFlags) cli_wand->command->flags;
+      /* get option, its argument count, and option type */
+      cli_wand->command = GetCommandOptionInfo(option);
+      count=cli_wand->command->type;
+      option_type=(CommandOptionFlags) cli_wand->command->flags;
 #if 0
-    (void) FormatLocaleFile(stderr, "Script: %u,%u: \"%s\" matched \"%s\"\n",
+      (void) FormatLocaleFile(stderr, "Script: %u,%u: \"%s\" matched \"%s\"\n",
           cli_wand->line, cli_wand->line, option, cli_wand->command->mnemonic );
 #endif
 
-    /* handle a undefined option - image read? */
-    if ( option_type == UndefinedOptionFlag ||
-         (option_type & NonMagickOptionFlag) != 0 ) {
+      /* handle a undefined option - image read - always for "magick-script" */
+      if ( option_type == UndefinedOptionFlag ||
+           (option_type & NonMagickOptionFlag) != 0 ) {
 #if MagickCommandDebug >= 3
-      (void) FormatLocaleFile(stderr, "Script %u,%u Non-Option: \"%s\"\n",
-                  cli_wand->line, cli_wand->line, option);
+        (void) FormatLocaleFile(stderr, "Script %u,%u Non-Option: \"%s\"\n",
+                    cli_wand->line, cli_wand->line, option);
 #endif
-      if ( IfMagickFalse(IsCommandOption(option))) {
-        /* non-option -- treat as a image read */
-        cli_wand->command=(const OptionInfo *)NULL;
-        CLIOption(cli_wand,"-read",option);
-        goto next_token;
+        if ( IfMagickFalse(IsCommandOption(option))) {
+          /* non-option -- treat as a image read */
+          cli_wand->command=(const OptionInfo *)NULL;
+          CLIOption(cli_wand,"-read",option);
+          break; /* next option */
+        }
+        CLIWandException(OptionFatalError,"UnrecognizedOption",option);
+        break; /* next option */
       }
-      CLIWandExceptionBreak(OptionFatalError,"UnrecognizedOption",option);
-      goto next_token;
-    }
 
-    if ( count >= 1 ) {
-      if( IfMagickFalse(GetScriptToken(token_info)) )
-        CLIWandException(OptionFatalError,"MissingArgument",option);
-      CloneString(&arg1,token_info->token);
-    }
-    else
-      CloneString(&arg1,(char *)NULL);
-
-    if ( count >= 2 ) {
-      if( IfMagickFalse(GetScriptToken(token_info)) )
-        CLIWandExceptionBreak(OptionFatalError,"MissingArgument",option);
-      CloneString(&arg2,token_info->token);
-    }
-    else
-      CloneString(&arg2,(char *)NULL);
+      if ( count >= 1 ) {
+        if( IfMagickFalse(GetScriptToken(token_info)) )
+          CLIWandException(OptionFatalError,"MissingArgument",option);
+        CloneString(&arg1,token_info->token);
+      }
+      else
+        CloneString(&arg1,(char *)NULL);
 
+      if ( count >= 2 ) {
+        if( IfMagickFalse(GetScriptToken(token_info)) )
+          CLIWandExceptionBreak(OptionFatalError,"MissingArgument",option);
+        CloneString(&arg2,token_info->token);
+      }
+      else
+        CloneString(&arg2,(char *)NULL);
 
-    /*
-      Process Options
-    */
+      /*
+        Process Options
+      */
 #if MagickCommandDebug >= 3
-    (void) FormatLocaleFile(stderr,
-      "Script %u,%u Option: \"%s\"  Count: %d  Flags: %04x  Args: \"%s\" \"%s\"\n",
-          cli_wand->line,cli_wand->line,option,count,option_type,arg1,arg2);
+      (void) FormatLocaleFile(stderr,
+        "Script %u,%u Option: \"%s\"  Count: %d  Flags: %04x  Args: \"%s\" \"%s\"\n",
+            cli_wand->line,cli_wand->line,option,count,option_type,arg1,arg2);
 #endif
-    /* Hard Depreciated Options, no code to execute - error */
-    if ( (option_type & DeprecateOptionFlag) != 0 ) {
-      CLIWandException(OptionError,"DeprecatedOptionNoCode",option);
-      if ( IfMagickTrue(CLICatchException(cli_wand, MagickFalse)) )
-        break;
-      goto next_token;
-    }
-
-    /* MagickCommandGenesis() options have no place in a magick script */
-    if ( (option_type & GenesisOptionFlag) != 0 ) {
-      CLIWandExceptionBreak(OptionError,"InvalidUseOfOption",option);
-      goto next_token;
-    }
+      /* Hard Depreciated Options, no code to execute - error */
+      if ( (option_type & DeprecateOptionFlag) != 0 ) {
+        CLIWandException(OptionError,"DeprecatedOptionNoCode",option);
+        break; /* next option */
+      }
 
-    if ( (option_type & SpecialOptionFlag) != 0 ) {
-      if ( LocaleCompare(option,"-exit") == 0 ) {
-        break; /* forced end of script */
+      /* MagickCommandGenesis() options have no place in a magick script */
+      if ( (option_type & GenesisOptionFlag) != 0 ) {
+        CLIWandException(OptionError,"InvalidUseOfOption",option);
+        break; /* next option */
       }
-      if ( LocaleCompare(option,"-script") == 0 ) {
-        /* FUTURE: call new script from this script */
-        CLIWandExceptionBreak(OptionError,"InvalidUseOfOption",option);
-        goto next_token;
+
+      /* handle any special 'script' options */
+      if ( (option_type & SpecialOptionFlag) != 0 ) {
+        if ( LocaleCompare(option,"-exit") == 0 ) {
+          break; /* forced end of script */
+        }
+        if ( LocaleCompare(option,"-script") == 0 ) {
+          /* FUTURE: call new script from this script - error for now */
+          CLIWandException(OptionError,"InvalidUseOfOption",option);
+          break; /* next option */
+        }
+        /* FUTURE: handle special script-argument options here */
+        /* handle any other special operators now */
+        CLIWandException(OptionError,"InvalidUseOfOption",option);
+        break; /* next option */
       }
-      /* FUTURE: handle special script-argument options here */
-      /* handle any other special operators now */
-      CLIWandExceptionBreak(OptionError,"InvalidUseOfOption",option);
-      goto next_token;
-    }
 
-    /* Process non-specific Option */
-    CLIOption(cli_wand, option, arg1, arg2);
+      /* Process non-specific Option */
+      CLIOption(cli_wand, option, arg1, arg2);
+
+    } while (0); /* break block to next option */
 
-next_token:
 #if MagickCommandDebug >= 9
     OutputOptions(cli_wand->wand.image_info);
     if ( cli_wand->wand.images != (Image *)NULL ) {
@@ -310,10 +310,13 @@ next_token:
       OutputProperties(cli_wand->wand.images,cli_wand->wand.exception);
     }
 #endif
-    if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
-      break;
+    if ( IfMagickTrue(CLICatchException(cli_wand, MagickFalse)) )
+      break;  /* exit loop */
   }
 
+  /*
+     Loop exit - check for some tokenization error
+  */
 #if MagickCommandDebug >= 3
   (void) FormatLocaleFile(stderr, "Script End: %d\n", token_info->status);
 #endif
@@ -428,7 +431,7 @@ WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
   cli_wand->filename="CLI";
 
   end = argc;
-  if ( (cli_wand->process_flags & ProcessImpliedWrite) != 0 )
+  if ( (cli_wand->process_flags & ProcessImplictWrite) != 0 )
     end--; /* the last arument is an implied write, do not process directly */
 
   for (i=index; i < end; i += count +1) {
@@ -436,82 +439,87 @@ WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
     if ( (cli_wand->process_flags & ProcessOneOptionOnly) != 0 && i != index )
       return(i);
 
-    option=argv[i];
-    cli_wand->line=i;  /* note the argument for this option */
+    do { /* use break to loop to exception handler and loop */
+
+      option=argv[i];
+      cli_wand->line=i;  /* note the argument for this option */
 
-    /* get option, its argument count, and option type */
-    cli_wand->command = GetCommandOptionInfo(argv[i]);
-    count=cli_wand->command->type;
-    option_type=(CommandOptionFlags) cli_wand->command->flags;
+      /* get option, its argument count, and option type */
+      cli_wand->command = GetCommandOptionInfo(argv[i]);
+      count=cli_wand->command->type;
+      option_type=(CommandOptionFlags) cli_wand->command->flags;
 #if 0
-    (void) FormatLocaleFile(stderr, "CLI %d: \"%s\" matched \"%s\"\n",
-          i, argv[i], cli_wand->command->mnemonic );
+      (void) FormatLocaleFile(stderr, "CLI %d: \"%s\" matched \"%s\"\n",
+            i, argv[i], cli_wand->command->mnemonic );
 #endif
 
-    if ( option_type == UndefinedOptionFlag ||
-         (option_type & NonMagickOptionFlag) != 0 ) {
+      if ( option_type == UndefinedOptionFlag ||
+           (option_type & NonMagickOptionFlag) != 0 ) {
 #if MagickCommandDebug >= 3
-      (void) FormatLocaleFile(stderr, "CLI %d Non-Option: \"%s\"\n", i, option);
+        (void) FormatLocaleFile(stderr, "CLI %d Non-Option: \"%s\"\n", i, option);
 #endif
-      if ( IfMagickFalse(IsCommandOption(option)) ) {
-        if ( (cli_wand->process_flags & ProcessNonOptionImageRead) != 0 ) {
-          /* non-option -- treat as a image read */
-          cli_wand->command=(const OptionInfo *)NULL;
-          CLIOption(cli_wand,"-read",option);
-          goto next_argument;
+        if ( IfMagickFalse(IsCommandOption(option)) ) {
+          if ( (cli_wand->process_flags & ProcessImplictRead) != 0 ) {
+            /* non-option -- treat as a image read */
+            cli_wand->command=(const OptionInfo *)NULL;
+            CLIOption(cli_wand,"-read",option);
+            break; /* next option */
+          }
         }
+        CLIWandException(OptionFatalError,"UnrecognizedOption",option);
+        break; /* next option */
       }
-      CLIWandException(OptionFatalError,"UnrecognizedOption",option);
-      goto next_argument;
-    }
 
-    if ( ((option_type & SpecialOptionFlag) != 0 ) &&
-         ((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 the 'implict write filename' argument
-         so it must be handled specially to prevent a 'missing argument' error.
-      */
-      if ( (i+count) >= argc )
-        CLIWandException(OptionFatalError,"MissingArgument",option);
-      ProcessScriptOptions(cli_wand,argc,argv,i+1);
-      return(argc);  /* Script does not return to CLI -- Yet */
-                     /* FUTURE: when it does, their may be no write arg! */
-    }
+      if ( ((option_type & SpecialOptionFlag) != 0 ) &&
+           ((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 the 'implict write filename' argument
+           so it must be handled specially to prevent a 'missing argument' error.
+        */
+        if ( (i+count) >= argc )
+          CLIWandException(OptionFatalError,"MissingArgument",option);
+        ProcessScriptOptions(cli_wand,argc,argv,i+1);
+        return(argc);  /* Script does not return to CLI -- Yet */
+                       /* FUTURE: when it does, their may be no write arg! */
+      }
 
-    if ((i+count) >= end ) {
-      CLIWandException(OptionFatalError,"MissingArgument",option);
-      if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
-        return(end);
-      goto next_argument; /* no more arguments unable to proceed */
-    }
+      if ((i+count) >= end ) {
+        CLIWandException(OptionFatalError,"MissingArgument",option);
+        if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
+          return(end);
+        break; /* next option - not that their is any! */
+      }
 
-    arg1 = ( count >= 1 ) ? argv[i+1] : (char *)NULL;
-    arg2 = ( count >= 2 ) ? argv[i+2] : (char *)NULL;
+      arg1 = ( count >= 1 ) ? argv[i+1] : (char *)NULL;
+      arg2 = ( count >= 2 ) ? argv[i+2] : (char *)NULL;
 
-    /*
-      Process Known Options
-    */
+      /*
+        Process Known Options
+      */
 #if MagickCommandDebug >= 3
-    (void) FormatLocaleFile(stderr,
-      "CLI %u Option: \"%s\"  Count: %d  Flags: %04x  Args: \"%s\" \"%s\"\n",
-          i,option,count,option_type,arg1,arg2);
+      (void) FormatLocaleFile(stderr,
+        "CLI %u Option: \"%s\"  Count: %d  Flags: %04x  Args: \"%s\" \"%s\"\n",
+            i,option,count,option_type,arg1,arg2);
 #endif
 
-    if ( (option_type & GenesisOptionFlag) != 0 )
-      goto next_argument; /* ignored this from command line args */
+      /* ignore 'genesis options' in command line args */
+      if ( (option_type & GenesisOptionFlag) != 0 )
+        break; /* next option */
 
-    if ( (option_type & SpecialOptionFlag) != 0 ) {
-      if ( (cli_wand->process_flags & ProcessExitOption) != 0
-           && LocaleCompare(option,"-exit") == 0 )
-        return(i+count);
-      goto next_argument;
-    }
+      /* Handle any special options for CLI (-script handled above) */
+      if ( (option_type & SpecialOptionFlag) != 0 ) {
+        if ( (cli_wand->process_flags & ProcessExitOption) != 0
+             && LocaleCompare(option,"-exit") == 0 )
+          return(i+count);
+        break; /* next option */
+      }
 
-    /* Process a Normal Option */
-    CLIOption(cli_wand, option, arg1, arg2);
+      /* Process standard image option */
+      CLIOption(cli_wand, option, arg1, arg2);
+
+    } while (0); /* break block to next option */
 
-next_argument:
 #if MagickCommandDebug >= 9
     OutputOptions(cli_wand->wand.image_info);
     if ( cli_wand->wand.images != (Image *)NULL ) {
@@ -524,7 +532,7 @@ next_argument:
   }
   assert(i==end);
 
-  if ( (cli_wand->process_flags & ProcessImpliedWrite) == 0 )
+  if ( (cli_wand->process_flags & ProcessImplictWrite) == 0 )
     return(end); /* no implied write -- just return to caller */
 
   assert(end==argc-1); /* end should not include last argument */
@@ -535,19 +543,19 @@ next_argument:
   option=argv[i];
   cli_wand->line=i;
 
-#if MagickCommandDebug >= 3
-  (void) FormatLocaleFile(stderr, "CLI %d Write File: \"%s\"\n", i, option );
-#endif
-
-  /* check that stacks are empty */
+  /* check that stacks are empty - or cause exception */
   if (cli_wand->image_list_stack != (Stack *)NULL)
-    CLIWandException(OptionError,"UnbalancedParenthesis", "(eof)");
+    CLIWandException(OptionError,"UnbalancedParenthesis", "(end of cli)");
   else if (cli_wand->image_info_stack != (Stack *)NULL)
-    CLIWandException(OptionError,"UnbalancedBraces", "(eof)");
+    CLIWandException(OptionError,"UnbalancedBraces", "(end of cli)");
   if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
     return(argc);
 
-  /* This is a valid 'do no write' option - no images needed */
+#if MagickCommandDebug >= 3
+  (void) FormatLocaleFile(stderr, "CLI %d Write File: \"%s\"\n", i, option );
+#endif
+
+  /* Valid 'do no write' replacement option (instead of "null:") */
   if (LocaleCompare(option,"-exit") == 0 )
     return(argc);  /* just exit, no image write */
 
index 8c5cc49fbc77db47e72e478534ce1abec098e4eb..9f531542cba0d8ad8cd83688487adcc933e3835b 100644 (file)
@@ -1600,7 +1600,7 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
   return the Image pointer to the first image in list.
 */
 static void CLISimpleOperatorImage(MagickCLI *cli_wand,
-  const char *option, const char *arg1, const char *arg2)
+  const char *option, const char *arg1n, const char *arg2n)
 {
   Image *
     new_image;
@@ -1617,11 +1617,17 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
   ssize_t
     parse;
 
+  const char    /* For percent escape interpretImageProperties() */
+    *arg1,
+    *arg2;
+
 #define _image_info     (cli_wand->wand.image_info)
 #define _image          (cli_wand->wand.images)
 #define _exception      (cli_wand->wand.exception)
 #define _draw_info      (cli_wand->draw_info)
 #define _quantize_info  (cli_wand->quantize_info)
+#define _process_flags  (cli_wand->process_flags)
+#define _option_type    ((CommandOptionFlags) cli_wand->command->flags)
 #define IfNormalOp      (*option=='-')
 #define IfPlusOp        (*option!='-')
 #define normal_op       IsMagickTrue(IfNormalOp)
@@ -1634,13 +1640,38 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
 
-  SetGeometryInfo(&geometry_info);
+  /* Interpret Percent Escapes in Arguments - using first image */
+  arg1 = arg1n,
+  arg2 = arg2n;
+  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+    /* Interpret Percent escapes in argument 1 */
+    if (arg1n != (char *) NULL) {
+      arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
+      if (arg1 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg1=arg1n;  /* use the given argument as is */
+      }
+    }
+    if (arg2n != (char *) NULL) {
+      arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
+      if (arg2 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg2=arg2n;  /* use the given argument as is */
+      }
+    }
+  }
+#undef _option_type
+
+#if 0
+  (void) FormatLocaleFile(stderr,
+    "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
+#endif
 
   new_image = (Image *)NULL; /* the replacement image, if not null at end */
+  SetGeometryInfo(&geometry_info);
 
-  /* FUTURE: We may need somthing a little more optimized than this!
-     Perhaps, do the 'sync' if 'settings tainted' before next operator.
-  */
   switch (*(option+1))
   {
     case 'a':
@@ -1690,7 +1721,6 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
       if (LocaleCompare("annotate",option+1) == 0)
         {
           char
-            *text,
             geometry[MaxTextExtent];
 
           SetGeometryInfo(&geometry_info);
@@ -1699,12 +1729,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
-          text=InterpretImageProperties(_image_info,_image,arg2,
-            _exception);
-          if (text == (char *) NULL)
-            break;
-          (void) CloneString(&_draw_info->text,text);
-          text=DestroyString(text);
+          (void) CloneString(&_draw_info->text,arg2);
           (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
             geometry_info.xi,geometry_info.psi);
           (void) CloneString(&_draw_info->geometry,geometry);
@@ -2133,9 +2158,6 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("distort",option+1) == 0)
         {
-          char
-            *arg;
-
           double
             *args;
 
@@ -2164,13 +2186,8 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
                     (size_t)2,resize_args,MagickTrue,_exception);
                break;
             }
-          /* allow percent escapes in argument string */
-          arg=InterpretImageProperties(_image_info,_image,arg2,_exception);
-          if (arg == (char *) NULL)
-            break;
           /* convert argument string into an array of doubles */
-          args = StringToArrayOfDoubles(arg,&count,_exception);
-          arg=DestroyString(arg);
+          args = StringToArrayOfDoubles(arg2,&count,_exception);
           if (args == (double *)NULL )
             CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
 
@@ -2337,9 +2354,6 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("function",option+1) == 0)
         {
-          char
-            *arg;
-
           double
             *args;
 
@@ -2350,13 +2364,8 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           if ( parse < 0 )
             CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
                  option,arg1);
-          /* allow percent escapes in argument string */
-          arg=InterpretImageProperties(_image_info,_image,arg2,_exception);
-          if (arg == (char *) NULL)
-            break;
           /* convert argument string into an array of doubles */
-          args = StringToArrayOfDoubles(arg,&count,_exception);
-          arg=DestroyString(arg);
+          args = StringToArrayOfDoubles(arg2,&count,_exception);
           if (args == (double *)NULL )
             CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
 
@@ -2431,15 +2440,14 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             *text;
 
           format=GetImageOption(_image_info,"format");
-          if (format == (char *) NULL)
-            {
-              (void) IdentifyImage(_image,stdout,_image_info->verbose,
-                _exception);
-              break;
-            }
+          if (format == (char *) NULL) {
+            (void) IdentifyImage(_image,stdout,_image_info->verbose,_exception);
+            break;
+          }
           text=InterpretImageProperties(_image_info,_image,format,_exception);
           if (text == (char *) NULL)
-            break;
+            CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
+                 option);
           (void) fputs(text,stdout);
           (void) fputc('\n',stdout);
           text=DestroyString((char *)text);
@@ -3070,7 +3078,8 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             }
           value=InterpretImageProperties(_image_info,_image,arg2,_exception);
           if (value == (char *) NULL)
-            break;
+            CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
+                  option);
           if (LocaleNCompare(arg1,"registry:",9) == 0)
             (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
           else
@@ -3176,19 +3185,12 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("sparse-color",option+1) == 0)
         {
-          char
-            *arguments;
-
           parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
           if ( parse < 0 )
             CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
                 option,arg1);
-          arguments=InterpretImageProperties(_image_info,_image,arg2,_exception);
-          if (arguments == (char *) NULL)
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
-          new_image=SparseColorOption(_image,(SparseColorMethod)parse,
-               arguments,_exception);
-          arguments=DestroyString(arguments);
+          new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
+               _exception);
           break;
         }
       if (LocaleCompare("splice",option+1) == 0)
@@ -3404,10 +3406,14 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     default:
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
   }
-  /*
-     Replace current image with any image that was generated
-     and set image point to last image (so image->next is correct)
-  */
+  /* clean up percent escape interpreted strings */
+  if (arg1 != arg1n )
+    arg1=DestroyString((char *)arg1);
+  if (arg2 != arg2n )
+    arg2=DestroyString((char *)arg2);
+
+  /* Replace current image with any image that was generated
+     and set image point to last image (so image->next is correct) */
   if (new_image != (Image *) NULL)
     ReplaceImageInListReturnLast(&_image,new_image);
 
@@ -3491,7 +3497,7 @@ WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
 %
 */
 WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
-     const char *option,const char *arg1, const char *magick_unused(arg2))
+     const char *option,const char *arg1n, const char *arg2n)
 {
   ssize_t
     parse;
@@ -3499,11 +3505,17 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
   Image
     *new_images;
 
+  const char    /* For percent escape interpretImageProperties() */
+    *arg1,
+    *arg2;
+
 #define _image_info     (cli_wand->wand.image_info)
 #define _images         (cli_wand->wand.images)
 #define _exception      (cli_wand->wand.exception)
 #define _draw_info      (cli_wand->draw_info)
 #define _quantize_info  (cli_wand->quantize_info)
+#define _process_flags  (cli_wand->process_flags)
+#define _option_type    ((CommandOptionFlags) cli_wand->command->flags)
 #define IfNormalOp      (*option=='-')
 #define IfPlusOp        (*option!='-')
 #define normal_op       IsMagickTrue(IfNormalOp)
@@ -3515,6 +3527,36 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
 
+  /* Interpret Percent Escapes in Arguments - using first image */
+  arg1 = arg1n;
+  arg2 = arg2n;
+  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+    /* Interpret Percent escapes in argument 1 */
+    if (arg1n != (char *) NULL) {
+      arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
+      if (arg1 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg1=arg1n;  /* use the given argument as is */
+      }
+    }
+    if (arg2n != (char *) NULL) {
+      arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
+      if (arg2 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg2=arg2n;  /* use the given argument as is */
+      }
+    }
+  }
+#undef _option_type
+
+#if 0
+  (void) FormatLocaleFile(stderr,
+    "CLIListOperatorImages: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
+#endif
+
+
   new_images=NewImageList();
 
   switch (*(option+1))
@@ -3981,14 +4023,7 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
     {
       if (LocaleCompare("print",option+1) == 0)
         {
-          char
-            *string;
-
-          string=InterpretImageProperties(_image_info,_images,arg1,_exception);
-          if (string == (char *) NULL)
-            break;
-          (void) FormatLocaleFile(stdout,"%s",string);
-          string=DestroyString(string);
+          (void) FormatLocaleFile(stdout,"%s",arg1);
           break;
         }
       if (LocaleCompare("process",option+1) == 0)
@@ -4192,11 +4227,17 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
     default:
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
   }
+
+  /* clean up percent escape interpreted strings */
+  if (arg1 != arg1n )
+    arg1=DestroyString((char *)arg1);
+  if (arg2 != arg2n )
+    arg2=DestroyString((char *)arg2);
+
+  /* if new image list generated, replace existing image list */
   if (new_images == (Image *) NULL)
     return;
-
-  if (_images != (Image *) NULL)
-    _images=DestroyImageList(_images);
+  _images=DestroyImageList(_images);
   _images=GetFirstImageInList(new_images);
   return;
 
@@ -4215,21 +4256,21 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   C L I S p e c i a l O p e r a t i o n s                                   %
++   C L I N o I m a g e O p e r a t i o n s                                   %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  CLINoImageOperator() Applies operations that may not actually need images
-%  in an image list wen it is applied.
+%  in an image list.
 %
 %  The classic operators of this type is -read, which actually creates images
 %  even when no images are present.  Or image stack operators, which can be
-%  applied to empty image lists.
+%  applied (push or pop) to an empty image list.
 %
 %  Note: unlike other Operators, these may involve other special 'option'
-%  character prefixes, other than simply '-' or '+'.
+%  characters other than '-' or '+', namely parenthesis and braces.
 %
 %  The format of the CLINoImageOption method is:
 %
@@ -4330,7 +4371,7 @@ WandExport void CLINoImageOperator(MagickCLI *cli_wand,
       Image *
         new_images;
 #if 0
-fprintf(stderr, "DEBUG: Reading image: \"%s\"\n", argv[i]);
+      fprintf(stderr, "DEBUG: Reading image: \"%s\"\n", argv[i]);
 #endif
       if (IfMagickTrue(_image_info->ping))
         new_images=PingImages(_image_info,argv[i],_exception);
@@ -4613,19 +4654,25 @@ fprintf(stderr, "DEBUG: Reading image: \"%s\"\n", argv[i]);
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   C L I O p t i o n O p e r a t i o n s                                     %
++   C L I O p t i o n                                                         %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  CLIOption() Processes the given option using the given CLI Magick Wand.
+%  The option arguments can be variable in number, though at this time no more
+%  that two is actually used by any option (this may change). Excess options
+%  are simply ignored.
 %
 %  If the cli_wand->command pointer is non-null, then it is assumed that the
 %  option has already been search for up from the CommandOptions[] table in
-%  "MagickCore/options.c" using  GetCommandOptionInfo(), so that any command
-%  specific options (such as "magick" scripting options, or "display" settings)
-%  can be handled separatally.
+%  "MagickCore/options.c" using  GetCommandOptionInfo().  If not set this
+%  routine will do the lookup instead. The pointer is reset afterward.
+%
+%  This action allows the caller to lookup and pre-handle any 'special'
+%  options, (such as implicit reads) before calling this general option
+%  handler to deal with 'standard' command line options.
 %
 %  The format of the CLIOption method is:
 %
@@ -4637,7 +4684,7 @@ fprintf(stderr, "DEBUG: Reading image: \"%s\"\n", argv[i]);
 %
 %     o option: The special option (with any switch char) to process
 %
-%     o args: any required arguments for an option
+%     o args: any required arguments for an option (variable number)
 %
 %  Example Usage...
 %
@@ -4662,88 +4709,91 @@ WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
 
-  if ( cli_wand->command == (const OptionInfo *) NULL )
-    cli_wand->command = GetCommandOptionInfo(option);
+  do { /* Break Code Block for error handling */
+
+    /* get information about option */
+    if ( cli_wand->command == (const OptionInfo *) NULL )
+      cli_wand->command = GetCommandOptionInfo(option);
 #if 0
-    (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
-          option, cli_wand->command->mnemonic );
+      (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
+            option, cli_wand->command->mnemonic );
 #endif
+    option_type=(CommandOptionFlags) cli_wand->command->flags;
 
-  option_type=(CommandOptionFlags) cli_wand->command->flags;
+    if ( option_type == UndefinedOptionFlag )
+      CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
 
-  if ( option_type == UndefinedOptionFlag )
-    CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
+    assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
 
-  assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
+    /* depreciated options */
+    if ( (option_type & DeprecateOptionFlag) != 0 )
+      CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
 
-  if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
-    CLIWandExceptionReturn(OptionFatalError,"InvalidUseOfOption",option);
+    /* options that this module does not handle */
+    if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
+      CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
 
-  if ( (option_type & DeprecateOptionFlag) != 0 )
-    CLIWandExceptionReturn(OptionError,"DeprecatedOptionNoCode",option);
+    /* Get argument strings from VarArgs
+      How can you determine arguments is enough was supplied? */
+    { size_t
+        count = cli_wand->command->type;
 
-  if ( IfMagickTrue(CLICatchException(cli_wand, MagickFalse)) )
-    return;
+      va_list
+        operands;
 
+      va_start(operands,option);
 
-  { size_t
-      count = cli_wand->command->type;
+      arg1=arg2=NULL;
+      if ( count >= 1 )
+        arg1=(const char *) va_arg(operands, const char *);
+      if ( count >= 2 )
+        arg2=(const char *) va_arg(operands, const char *);
 
-    va_list
-      operands;
-
-    va_start(operands,option);
-
-    arg1=arg2=NULL;
-    if ( count >= 1 )
-      arg1=(const char *) va_arg(operands, const char *);
-    if ( count >= 2 )
-      arg2=(const char *) va_arg(operands, const char *);
-
-    va_end(operands);
+      va_end(operands);
 
 #if 0
-    (void) FormatLocaleFile(stderr,
-      "CLIOption: \"%s\"  Count: %ld  Flags: %04x  Args: \"%s\" \"%s\"\n",
-          option,(long) count,option_type,arg1,arg2);
+      (void) FormatLocaleFile(stderr,
+        "CLIOption: \"%s\"  Count: %ld  Flags: %04x  Args: \"%s\" \"%s\"\n",
+            option,(long) count,option_type,arg1,arg2);
 #endif
-  }
+    }
 
-  cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */
+    /*
+      Call the appropriate option handler
+    */
 
+    /* FUTURE: this is temporary - get 'settings' to handle distribution of
+      settings to images attributes,proprieties,artifacts */
+    if ( cli_wand->wand.images != (Image *)NULL )
+      SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
+          cli_wand->wand.exception);
 
-  /*
-     Call the appropriate option handler
-  */
+    if ( (option_type & SettingOptionFlags) != 0 ) {
+      CLISettingOptionInfo(cli_wand, option, arg1, arg2);
+      // FUTURE: Sync Specific Settings into Image Properities (not global)
+    }
 
-  /* FUTURE: this is temporary - get 'settings' to handle
-     distribution of settings to images attributes,proprieties,artifacts */
-  if ( cli_wand->wand.images != (Image *)NULL )
-    SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
-        cli_wand->wand.exception);
+    /* Operators that do not need images - read, write, stack, clone */
+    if ( (option_type & NoImageOperatorFlag) != 0)
+      CLINoImageOperator(cli_wand, option, arg1, arg2);
 
-  if ( (option_type & SettingOptionFlags) != 0 ) {
-    CLISettingOptionInfo(cli_wand, option, arg1, arg2);
-    // FUTURE: Sync Specific Settings into Image Properities (not global)
-  }
+    /* FUTURE: The not a setting part below is a temporary hack due to
+    * some options being both a Setting and a Simple operator.
+    * Specifically -monitor, -depth, and  -colorspace */
+    if ( cli_wand->wand.images == (Image *)NULL )
+      if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
+          ((option_type & SettingOptionFlags) == 0 ))  /* temp hack */
+        CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
 
-  if ( (option_type & NoImageOperatorFlag) != 0)
-    CLINoImageOperator(cli_wand, option, arg1, arg2);
-
-  /* FUTURE: The not a setting part below is a temporary hack due to
-   * some options being both a Setting and a Simple operator.
-   * Specifically -monitor, -depth, and  -colorspace */
-  if ( cli_wand->wand.images == (Image *)NULL ) {
-    if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
-         ((option_type & SettingOptionFlags) == 0 ))  /* temp hack */
-      CLIWandException(OptionError,"NoImagesFound",option);
-    return; /* on its own this is not an error */
-  }
+    /* Operators work on single images, and needs a loop over the images */
+    if ( (option_type & SimpleOperatorFlag) != 0)
+      CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
 
-  if ( (option_type & SimpleOperatorFlag) != 0)
-    CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
+    /* Operators that work on the image list as a whole */
+    if ( (option_type & ListOperatorFlag) != 0 )
+      CLIListOperatorImages(cli_wand, option, arg1, arg2);
 
-  if ( (option_type & ListOperatorFlag) != 0 )
-    CLIListOperatorImages(cli_wand, option, arg1, arg2);
+  } while (0);  /* end Break code block */
 
+  cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */
 }
diff --git a/MagickWand/tests/README b/MagickWand/tests/README
new file mode 100644 (file)
index 0000000..88475d8
--- /dev/null
@@ -0,0 +1,19 @@
+
+These file provide simple examples and testing of aspects of the
+MagickWand API.
+
+Specifically
+  + MagickAddImage() (also use by MagickReadImage() ) in various situations
+    with a single images, or a list of images.  Study of the examples
+    details exactly what the API does.
+
+  + GetScriptToken ()  doing low level testing of the tokenization (argument
+    separation) the "magick" command applies when reading command options
+    from a script, or pipeline. The Tokenization is designed specifically to
+    emulate the BASH shell. In this way you would write scripts in exactly the
+    same way you would write BASH shell command line arguments.
+
+    Tests include quoting, mixed quoting, backslash escapes, line
+    continuation, extremely long tokens, and various error conditions.
+
+
index d0b0b6d42a82f5388982d9d37712f96c001eb918..4e84a6d1576233ccb39fa1fab0907da90af89159 100644 (file)
@@ -59,11 +59,12 @@ extern "C" {
 /* Define how options should be processed */
 typedef enum
 {
-  /* NonOption Handling */
-  ProcessNonOptionImageRead   = 0x0001,  /* A non-option is a image read
+  /* General Option Handling */
+  ProcessImplictRead          = 0x0001,  /* Non-options are image reads.
                                             If not set then skip implied read
                                             without producing an error.
                                             For use with "mogrify" handling */
+  ProcessInterpretProperities = 0x0010,  /* allow general escapes in args */
 
   /* Special Option Handling */
   ProcessExitOption           = 0x0100,  /* allow '-exit' use */
@@ -73,10 +74,10 @@ typedef enum
 
   /* Option Processing Flags */
   ProcessOneOptionOnly        = 0x4000,  /* Process one option only */
-  ProcessImpliedWrite         = 0x8000,  /* Last arg is an implied write */
+  ProcessImplictWrite         = 0x8000,  /* Last arg is an implict write */
 
   /* Flag Groups for specific Situations */
-  MagickCommandOptionFlags    = 0x8F0F,  /* Magick Command Flags */
+  MagickCommandOptionFlags    = 0x8FFF,  /* Magick Command Flags */
   ConvertCommandOptionFlags   = 0x800F,  /* Convert Command Flags */
   MagickScriptArgsFlags       = 0x000F,  /* Script CLI Process Args Flags */
 } ProcessOptionFlags;
index e4b333c13a2ea2c83ab77999edf1ffe08944d23e..2a4f42e521f9c68e926c4039eef7083829f9eb37 100644 (file)
         <message name="GeometryDoesNotContainImage">
           geometry does not contain image
         </message>
+        <message name="InterpretPropertyFailure">
+          failure in interpret image property escapes
+        </message>
         <message name="InvalidArgument">
           invalid argument for option
         </message>
         <message name="GeometryDoesNotContainImage">
           geometry does not contain image
         </message>
+        <message name="InterpretPropertyFailure">
+          failure in interpret image property escapes
+        </message>
         <message name="InvalidSetting">
           invalid setting
         </message>
index 616ea39b2d7ad8e3e8b8d907717fa6d1d82736e6..0c5c87dbb2c0a5d660bccc01c9b7187afb2fde88 100644 (file)
         <message name="GeometryDoesNotContainImage">
           image non incluse dans la géométrie
         </message>
+        <message name="InterpretPropertyFailure">
+          *** failure in interpret image property escapes ***
+        </message>
         <message name="InvalidArgument">
           argument invalide pour l'option
         </message>
         <message name="GeometryDoesNotContainImage">
           image non incluse dans la géométrie
         </message>
+        <message name="InterpretPropertyFailure">
+          *** failure in interpret image property escapes ***
+        </message>
         <message name="InvalidSetting">
           invalide de réglage
         </message>