]> granicus.if.org Git - imagemagick/commitdiff
Finish Syntax Error check of options
authoranthony <anthony@git.imagemagick.org>
Tue, 27 Mar 2012 13:54:47 +0000 (13:54 +0000)
committeranthony <anthony@git.imagemagick.org>
Tue, 27 Mar 2012 13:54:47 +0000 (13:54 +0000)
Adjust "magick-script" command name check

Allow special use of ';' in column one as comment to allow
for shell script to magick script mapping launch code

MagickWand/convert.c
MagickWand/magick-cli.c
MagickWand/operation.c
MagickWand/script-token.c

index 92566377bf4968ec396a89d6437e19455b2d4ccb..8e13e48a59c8d968408abfb14cff88c70f683a31 100644 (file)
@@ -2752,7 +2752,7 @@ WandExport MagickBooleanType ConvertImageCommand(ImageInfo *image_info,
               ThrowConvertException(OptionError,"MissingArgument",option);
             break;
           }
-        if (LocaleCompare("thumbnail",option+1) == 0)
+        if (LocaleCompare("threshold",option+1) == 0)
           {
             if (*option == '+')
               break;
@@ -2763,7 +2763,7 @@ WandExport MagickBooleanType ConvertImageCommand(ImageInfo *image_info,
               ThrowConvertInvalidArgumentException(option,argv[i]);
             break;
           }
-        if (LocaleCompare("threshold",option+1) == 0)
+        if (LocaleCompare("thumbnail",option+1) == 0)
           {
             if (*option == '+')
               break;
index ee5590bb36180c08f60e334770569151197379f2..51b6f338a04b64607ad63f396c81fa9f6d950a39 100644 (file)
@@ -660,56 +660,60 @@ WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,
 
 #if 0
   /* FUTURE: This does not make sense!  Remove it.
-     Only a 'image read' needs to expand file name glob patterns
+     Only "-read" needs to expand file name glob patterns
   */
   status=ExpandFilenames(&argc,&argv);
   if (status == MagickFalse)
     ThrowConvertException(ResourceLimitError,"MemoryAllocationFailed",
       GetExceptionMessage(errno));
 #endif
+  /* Initialize special "CLI Wand" to hold images and settings (empty) */
+  cli_wand=AcquireMagickCLI(image_info,exception);
 
-  /* Handle special single use options */
+  /* Special Case:  If command name ends with "script" then run it as is
+     a "-script" option is implied.  This allows you to name the "magick"
+     command "magick-script", and create scripts of the form...
+           #!/usr/bin/env magick-script
+  */
+  if (LocaleCompare("script",argv[0]+strlen(argv[0])-6) == 0) {
+    cli_wand=AcquireMagickCLI(image_info,exception);
+    GetPathComponent(argv[1],TailPath,cli_wand->wand.name);
+    ProcessScriptOptions(cli_wand,argc,argv,1);
+    goto Magick_Command_Cleanup;
+  }
+
+  /* Special Case: Version Information and Abort */
   if (argc == 2) {
     option=argv[1];
-    if ((LocaleCompare("-version",option+1) == 0) ||
-        (LocaleCompare("--version",option+1) == 0) ) {
-      (void) FormatLocaleFile(stdout,"Version: %s\n",
-        GetMagickVersion((size_t *) NULL));
-      (void) FormatLocaleFile(stdout,"Copyright: %s\n",
-        GetMagickCopyright());
-      (void) FormatLocaleFile(stdout,"Features: %s\n\n",
-        GetMagickFeatures());
-      return(MagickFalse);
+    if ((LocaleCompare("-version",option) == 0) ||
+        (LocaleCompare("--version",option) == 0) ) {
+      CLISpecialOperator(cli_wand, "-version", (char *)NULL);
+      goto Magick_Command_Exit;
     }
   }
 
-  if (argc >= 2) {
-    /* Special "concatenate option (hidden) for delegate usage */
-    if (LocaleCompare("-concatenate",argv[1]) == 0)
-      return(ConcatenateImages(argc,argv,exception));
-
-    /* Special Handling for a "#!/usr/bin/env magick-script" script */
-    if (LocaleCompare("magick-script",argv[0]+strlen(argv[0])-13) == 0) {
-      cli_wand=AcquireMagickCLI(image_info,exception);
-      GetPathComponent(argv[1],TailPath,cli_wand->wand.name);
-      ProcessScriptOptions(cli_wand,argc,argv,1);
-      goto Magick_Command_Cleanup;
-    }
+  /* not enough arguments -- including -help */
+  if (argc < 3) {
+    MagickUsage();
+    goto Magick_Command_Exit;
   }
 
-  if (argc < 3)
-    return(MagickUsage());
-
-  /* Initialize special "CLI Wand" to hold images and settings (empty) */
-  cli_wand=AcquireMagickCLI(image_info,exception);
+  /* Special "concatenate option (hidden) for delegate usage */
+  if (LocaleCompare("-concatenate",argv[1]) == 0) {
+    ConcatenateImages(argc,argv,exception);
+    goto Magick_Command_Exit;
+  }
 
-  if (LocaleCompare("-list",argv[1]) == 0)
-    /* Special option, list information and exit
-       FUTURE: this should be a MagickCore option,
-       especially as no wand is actually needed!
-    */
+  /* List Information and Abort */
+  if (LocaleCompare("-list",argv[1]) == 0) {
     CLISpecialOperator(cli_wand, argv[1], argv[2]);
-  else if (LocaleCompare("-script",argv[1]) == 0) {
+    goto Magick_Command_Exit;
+  }
+
+  /* ------------- */
+  /* The Main Call */
+
+  if (LocaleCompare("-script",argv[1]) == 0) {
     /* Start processing directly from script, no pre-script options
        Replace wand command name with script name
        First argument in the argv array is the script name to read.
@@ -718,12 +722,13 @@ WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,
     ProcessScriptOptions(cli_wand,argc,argv,2);
   }
   else {
-    /* Noraml Command Line, Assumes output file as last option */
+    /* Normal Command Line, assumes output file as last option */
     GetPathComponent(argv[0],TailPath,cli_wand->wand.name);
     ProcessCommandOptions(cli_wand,argc,argv,1,
        (LocaleCompare("magick",argv[0]+strlen(argv[0])-6) == 0)?
            MagickCommandOptionFlags : ConvertCommandOptionFlags);
   }
+  /* ------------- */
 
 Magick_Command_Cleanup:
   /* recover original image_info from bottom of stack */
@@ -755,6 +760,7 @@ Magick_Command_Cleanup:
     }
   }
 
+Magick_Command_Exit:
   /* Destroy the special CLI Wand */
   cli_wand->wand.image_info = (ImageInfo *)NULL; /* not these */
   cli_wand->wand.exception = (ExceptionInfo *)NULL;
index b9fdd63fbd4cacde44995b57995699692035449c..5f6a32c94a66424bb369990ecc91b63fb5b9f3ae 100644 (file)
@@ -689,7 +689,7 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       if (LocaleCompare("bias",option+1) == 0)
         {
-          /* FUTURE: bias OBSOLETED, replaced by "convolve:bias"
+          /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
              as it is actually rarely used except in direct convolve operations
              Usage outside a direct convolve operation is actally non-sensible!
 
@@ -1511,7 +1511,9 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       if (LocaleCompare("texture",option+1) == 0)
         {
-          /* FUTURE: move _image_info string to option splay-tree */
+          /* FUTURE: move _image_info string to option splay-tree
+             Other than "montage" what uses "texture" ????
+          */
           (void) CloneString(&_image_info->texture,ArgOption(NULL));
           break;
         }
@@ -1525,7 +1527,10 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
       if (LocaleCompare("tile-offset",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. ??? */
-          (void) SetImageOption(_image_info,option+1,ArgOption("0"));
+          arg1=ArgOption("0");
+          if (IsGeometry(arg1) == MagickFalse)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
       if (LocaleCompare("transparent-color",option+1) == 0)
@@ -1537,6 +1542,8 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
              Note that +transparent-color, means fall-back to image
              attribute so ImageOption is deleted, not set to a default.
           */
+          if (IfSetOption && IsGeometry(arg1) == MagickFalse)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
               &_image_info->transparent_color,_exception);
@@ -1551,9 +1558,13 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
       if (LocaleCompare("type",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. */
+          parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
+               ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
+                 option,arg1);
+          _image_info->type=(ImageType) parse;
           (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
-          _image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
-                 MagickFalse,ArgOption("undefined"));
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -1573,9 +1584,13 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
              Should this effect _draw_info X and Y resolution?
              FUTURE: this probably should be part of the density setting
           */
+          parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
+               ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
+                 option,arg1);
+          _image_info->units=(ResolutionType) parse;
           (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
-          _image_info->units=(ResolutionType) ParseCommandOption(
-                MagickResolutionOptions,MagickFalse,ArgOption("undefined"));
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -1596,6 +1611,7 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         {
           /* FUTURE: Convert from _image_info to ImageOption
              Only used by coder FPX
+             And it only tests existance, not its content!
           */
           (void) CloneString(&_image_info->view,ArgOption(NULL));
           break;
@@ -1605,6 +1621,11 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
           /* SyncImageSettings() used to set per-image attribute.
              This is VERY deep in the image caching structure.
           */
+          parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
+               ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
+                 option,arg1);
           (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
@@ -1617,8 +1638,7 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
           /* Just what does using a font 'weight' do ???
              There is no "-list weight" output (reference manual says there is)
           */
-          if (!IfSetOption)
-            break;
+          arg1=ArgOption("all");
           _draw_info->weight=StringToUnsignedLong(arg1);
           if (LocaleCompare(arg1,"all") == 0)
             _draw_info->weight=0;
@@ -1639,7 +1659,10 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
           /* Used as a image chromaticity setting
              SyncImageSettings() used to set per-image attribute.
           */
-          (void) SetImageOption(_image_info,option+1,ArgOption("0.0"));
+          arg1=ArgOption("0.0");
+          if (IsGeometry(arg1) == MagickFalse)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -3470,15 +3493,19 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           double
             threshold;
 
-          if (!normal_op)
-            threshold=(double) QuantumRange/2;
-          else
+          threshold=(double) QuantumRange/2;
+          if (normal_op) {
+            if (IsGeometry(arg1) == MagickFalse)
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
             threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
+          }
           (void) BilevelImage(_image,threshold,_exception);
           break;
         }
       if (LocaleCompare("thumbnail",option+1) == 0)
         {
+          if (IsGeometry(arg1) == MagickFalse)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
           new_image=ThumbnailImage(_image,geometry.width,geometry.height,
             _exception);
@@ -3486,14 +3513,15 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("tint",option+1) == 0)
         {
+          if (IsGeometry(arg1) == MagickFalse)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
           break;
         }
       if (LocaleCompare("transform",option+1) == 0)
         {
           /* DEPRECIATED -- should really use Distort AffineProjection */
-          new_image=AffineTransformImage(_image,&_draw_info->affine,
-            _exception);
+          new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
           break;
         }
       if (LocaleCompare("transparent",option+1) == 0)
@@ -3533,10 +3561,11 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("unique",option+1) == 0)
         {
-          /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
-          /* FUTURE: This option is not documented!!!!! */
-          if (!normal_op)
-            {
+          /* FUTURE: move to SyncImageSettings() and AcqireImage()???
+             Option is not documented, bt appears to be for "identify".
+             We may need a identify specific verbose!
+          */
+          if (plus_alt_op) {
               (void) DeleteImageArtifact(_image,"identify:unique-colors");
               break;
             }
@@ -3551,6 +3580,8 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("unsharp",option+1) == 0)
         {
+          if (IsGeometry(arg1) == MagickFalse)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
@@ -3578,6 +3609,8 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("vignette",option+1) == 0)
         {
+          if (IsGeometry(arg1) == MagickFalse)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
@@ -3596,6 +3629,8 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("wave",option+1) == 0)
         {
+          if (IsGeometry(arg1) == MagickFalse)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
@@ -3605,6 +3640,8 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("white-threshold",option+1) == 0)
         {
+          if (IsGeometry(arg1) == MagickFalse)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           (void) WhiteThresholdImage(_image,arg1,_exception);
           break;
         }
@@ -4490,6 +4527,53 @@ WandExport void CLISpecialOperator(MagickCLI *cli_wand,
     (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
          _exception);
 
+  /*
+    No-op options
+  */
+  if (LocaleCompare("noop",option+1) == 0)
+    return;
+  if (LocaleCompare("sans",option+1) == 0)
+    return;
+  if (LocaleCompare("sans0",option+1) == 0)
+    return;
+  if (LocaleCompare("sans2",option+1) == 0)
+    return;
+  /*
+    Image Reading
+  */
+  if ( ( LocaleCompare("read",option+1) == 0 ) ||
+       ( LocaleCompare("--",option) == 0 ) ) {
+/*
+      int argc = 1
+      char **argv = &arg1;
+      MagickBooleanType
+        status=ExpandFilenames(&argc,&argv);
+
+      if (status == MagickFalse)
+        ThrowConvertException(ResourceLimitError,"MemoryAllocationFailed",
+             GetExceptionMessage(errno));
+      ...loop over images to read...
+*/
+#if !USE_WAND_METHODS
+      Image *
+        new_images;
+      if (cli_wand->wand.image_info->ping != MagickFalse)
+        new_images=PingImages(cli_wand->wand.image_info,arg1,_exception);
+      else
+        new_images=ReadImages(cli_wand->wand.image_info,arg1,_exception);
+      AppendImageToList(&cli_wand->wand.images, new_images);
+#else
+      /* read images using MagickWand method - no ping */
+      /* This is not working! - it locks up in a CPU loop! */
+      MagickSetLastIterator(&cli_wand->wand);
+      MagickReadImage(&cli_wand->wand,arg1);
+      MagickSetFirstIterator(&cli_wand->wand);
+#endif
+      return;
+    }
+  /*
+    Parenthesis and Brace operations
+  */
   if (LocaleCompare("respect-parenthesis",option+1) == 0) {
       /* link image and setting stacks - option is itself saved on stack! */
       (void) SetImageOption(cli_wand->wand.image_info,option+1,
@@ -4626,35 +4710,18 @@ WandExport void CLISpecialOperator(MagickCLI *cli_wand,
       AppendImageToList(&cli_wand->wand.images,new_images);
       return;
     }
-  if ( ( LocaleCompare("read",option+1) == 0 ) ||
-       ( LocaleCompare("--",option) == 0 ) ) {
-#if !USE_WAND_METHODS
-      Image *
-        new_images;
-
-      if (cli_wand->wand.image_info->ping != MagickFalse)
-        new_images=PingImages(cli_wand->wand.image_info,arg1,_exception);
-      else
-        new_images=ReadImages(cli_wand->wand.image_info,arg1,_exception);
-      AppendImageToList(&cli_wand->wand.images, new_images);
-#else
-      /* read images using MagickWand method - no ping */
-      /* This is not working! - it locks up in a CPU loop! */
-      MagickSetLastIterator(&cli_wand->wand);
-      MagickReadImage(&cli_wand->wand,arg1);
-      MagickSetFirstIterator(&cli_wand->wand);
-#endif
+  /*
+    Informational Operations
+  */
+  if (LocaleCompare("verbose",option+1) == 0) {
+      (void) FormatLocaleFile(stdout,"Version: %s\n",
+        GetMagickVersion((size_t *) NULL));
+      (void) FormatLocaleFile(stdout,"Copyright: %s\n",
+        GetMagickCopyright());
+      (void) FormatLocaleFile(stdout,"Features: %s\n\n",
+        GetMagickFeatures());
       return;
     }
-  /* No-op options */
-  if (LocaleCompare("noop",option+1) == 0)
-    return;
-  if (LocaleCompare("sans",option+1) == 0)
-    return;
-  if (LocaleCompare("sans0",option+1) == 0)
-    return;
-  if (LocaleCompare("sans2",option+1) == 0)
-    return;
   if (LocaleCompare("list",option+1) == 0) {
       /* FUTURE: This should really be built into the MagickCore
          It does not actually require any wand or images at all!
index 2420e6f7e291e81dafcecdb078de43125ee3c72f..74929de2b1b10b2b4a9903e3174c02d83c366200 100644 (file)
@@ -197,6 +197,21 @@ WandExport ScriptTokenInfo * DestroyScriptTokenInfo(ScriptTokenInfo *token_info)
 %  end of the line.  You can escape a comment '#', using quotes or backlsashes
 %  just as you can in a shell.
 %
+%  As a special case a ':' at the start of a line is also treated as a comment
+%  This allows a magick script to ignore a line that is parsed by the shell
+%  and can be used as a 'launcher' for magick scripts. For example
+%
+%    #!/bin/sh
+%    #
+%    # Shell Launcher for Magick Script
+%    :; echo "This part is run in the shell"
+%    :; exec magick -script "$0" "$@"; exit 10
+%    #
+%    # The rest of the script is magick script
+%    -read label:"This is a Magick Script!"
+%    -write show: -exit
+%
+%
 %  The format of the GetScriptToken method is:
 %
 %     MagickBooleanType GetScriptToken(ScriptTokenInfo *token_info)
@@ -288,8 +303,9 @@ WandExport MagickBooleanType GetScriptToken(ScriptTokenInfo *token_info)
         state=IN_WHITE;
       continue;
     }
-    if (c == '#' && state == IN_WHITE)
-      state=IN_COMMENT;
+    if ( state == IN_WHITE )
+      if (c == '#' || (c == ':' && token_info->curr_column==1))
+        state=IN_COMMENT;
     /* whitespace break character */
     if (strchr(" \n\r\t",c) != (char *)NULL) {
       switch (state) {