]> granicus.if.org Git - imagemagick/blobdiff - MagickWand/script-token.c
(no commit message)
[imagemagick] / MagickWand / script-token.c
index a9f1ba6eefb828fe0245b0718dfbdbb111b39c62..62e7d0b9893a27c2dd76b4e1408cf230fed45c95 100644 (file)
@@ -15,7 +15,7 @@
 %                               January 2012                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
 %  end of the line.  You can escape a comment '#', using quotes or backlsashes
 %  just as you can in a shell.
 %
-%  This allows the normal UNIX 'scripting' to be used to call on the magick
-%  command to parse the tokens from a file
+%  The parser will accept both newlines, returns, or return-newlines to mark
+%  the EOL. Though this is technically breaking (or perhaps adding to) the
+%  'BASH' syntax that is being followed.
+%
+%
+%  UNIX script Launcher...
+%
+%  The use of '#' comments allow normal UNIX 'scripting' to be used to call on
+%  the "magick" command to parse the tokens from a file
 %
 %    #!/path/to/command/magick -script
 %
-%  or
+%
+%  UNIX 'env' command launcher...
+%
+%  If "magick" is renamed "magick-script" you can use a 'env' UNIX launcher
 %
 %    #!/usr/bin/env magick-script
 %
+%
+%  Shell script launcher...
+%
 %  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 can be parsed by the shell
 %  and not by the magick script (tokenizer).  This allows for an alternative
-%  script 'launcher' to be used for magick scripts, and posibly windows DOS
-%  scripts.
+%  script 'launcher' to be used for magick scripts.
 %
 %    #!/bin/sh
+%    :; exec magick -script "$0" "$@"; exit 10
 %    #
-%    # Shell Launcher for Magick Script
-%    : echo "This part is run in the shell"
-%    : exec magick -script "$0" "$@"; exit 10
+%    # The rest of the file is magick script
+%    -read label:"This is a Magick Script!"
+%    -write show: -exit
+%
+% Or with some shell pre/post processing...
+%
+%    #!/bin/sh
+%    :; echo "This part is run in the shell, but ignored by Magick"
+%    :; magick -script "$0" "$@"
+%    :; echo "This is run after the "magick" script is finished!"
+%    :; exit 10
 %    #
-%    # The rest of the script is magick script
+%    # The rest of the file is magick script
+%    -read label:"This is a Magick Script!"
+%    -write show: -exit
+%
+%
+%  DOS script launcher...
+%
+%  Similarly any '@' at the start of the line (outside of quotes) will also be
+%  treated as comment. This allow you to create a DOS script launcher, to
+%  allow a ".bat" DOS scripts to run as "magick" scripts instead.
+%
+%    @echo This line is DOS executed but ignored by Magick
+%    @magick -script %~dpnx0 %*
+%    @echo This line is processed after the Magick script is finished
+%    @GOTO :EOF
+%    #
+%    # The rest of the file is magick script
+%    -read label:"This is a Magick Script!"
+%    -write show: -exit
+%
+% But this can also be used as a shell script launcher as well!
+% Though is more restrictive and less free-form than using ':'.
+%
+%    #!/bin/sh
+%    @() { exec magick -script "$@"; }
+%    @ "$0" "$@"; exit
+%    #
+%    # The rest of the file is magick script
+%    -read label:"This is a Magick Script!"
+%    -write show: -exit
+%
+% Or even like this...
+%
+%    #!/bin/sh
+%    @() { }
+%    @; exec magick -script "$0" "$@"; exit
+%    #
+%    # The rest of the file is magick script
 %    -read label:"This is a Magick Script!"
 %    -write show: -exit
 %
 %    o filename   the filename to open  ("-" means stdin)
 %
 */
-WandExport ScriptTokenInfo *AcquireScriptTokenInfo(char *filename)
+WandExport ScriptTokenInfo *AcquireScriptTokenInfo(const char *filename)
 {
   ScriptTokenInfo
     *token_info;
@@ -255,6 +313,7 @@ WandExport ScriptTokenInfo * DestroyScriptTokenInfo(ScriptTokenInfo *token_info)
    The EOL is defined as either '\r\n', or '\r', or '\n'.
    A '\r' on its own is converted into a '\n' to correctly handle
    raw input, typically due to 'copy-n-paste' of text files.
+   But a '\r\n' sequence is left ASIS for string handling
 */
 #define GetChar(c) \
 { \
@@ -305,16 +364,19 @@ WandExport MagickBooleanType GetScriptToken(ScriptTokenInfo *token_info)
     offset;
 
   /* EOF - no more tokens! */
+  if (token_info == (ScriptTokenInfo *) NULL)
+    return(MagickFalse);
   if (token_info->status != TokenStatusOK)
     {
       token_info->token[0]='\0';
       return(MagickFalse);
     }
-
   state=IN_WHITE;
   quote='\0';
   offset=0;
+DisableMSCWarning(4127)
   while(1)
+RestoreMSCWarning
   {
     /* get character */
     GetChar(c);
@@ -325,10 +387,12 @@ WandExport MagickBooleanType GetScriptToken(ScriptTokenInfo *token_info)
         state=IN_WHITE;
       continue;
     }
+    /* comment lines start with '#' anywhere, or ':' or '@' at start of line */
     if ( state == IN_WHITE )
-      if (c == '#' || (c == ':' && token_info->curr_column==1))
+      if ( ( c == '#' ) ||
+           ( token_info->curr_column==1 && (c == ':' || c == '@' ) ) )
         state=IN_COMMENT;
-    /* whitespace break character */
+    /* whitespace token separator character */
     if (strchr(" \n\r\t",c) != (char *)NULL) {
       switch (state) {
         case IN_TOKEN:
@@ -341,7 +405,7 @@ WandExport MagickBooleanType GetScriptToken(ScriptTokenInfo *token_info)
       continue;
     }
     /* quote character */
-    if (strchr("'\"",c) != (char *)NULL) {
+    if ( c=='\'' || c =='"' ) {
       switch (state) {
         case IN_WHITE:
           token_info->token_line=token_info->curr_line;
@@ -370,13 +434,16 @@ WandExport MagickBooleanType GetScriptToken(ScriptTokenInfo *token_info)
             continue;
           }
         GetChar(c);
-        if (c == '\n' || c == '\r' )
+        if (c == '\n')
           switch (state) {
             case IN_COMMENT:
               state=IN_WHITE;  /* end comment */
+            case IN_QUOTE:
+              if (quote != '"')
+                break;         /* in double quotes only */
             case IN_WHITE:
             case IN_TOKEN:
-              continue;   /* line continuation (outside quotes and comment) */
+              continue;        /* line continuation - remove line feed */
           }
         switch (state) {
           case IN_WHITE: