From: anthony Date: Sun, 8 Apr 2012 12:41:44 +0000 (+0000) Subject: Create wandcli.c module plus other minor changes X-Git-Tag: 7.0.1-0~5870 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=756cd0d228823ea405498ec6b2e9b8843beaca96;p=imagemagick Create wandcli.c module plus other minor changes --- diff --git a/MagickWand/ChangeLog b/MagickWand/ChangeLog index 2dc3b1045..780d18ccd 100644 --- a/MagickWand/ChangeLog +++ b/MagickWand/ChangeLog @@ -1,4 +1,4 @@ -2012-03-15 7.0.0-0 Anthony +2012-03-15 7.0.0-0 Anthony * Fix the MagickWand add/read insertion of new images into wands 2012-02-26 7.0.0-0 Anthony diff --git a/MagickWand/Makefile.am b/MagickWand/Makefile.am index 6d0691240..79181bcb6 100644 --- a/MagickWand/Makefile.am +++ b/MagickWand/Makefile.am @@ -55,7 +55,6 @@ MAGICKWAND_SOURCES = \ MagickWand/montage.h \ MagickWand/operation.c \ MagickWand/operation.h \ - MagickWand/operation-private.h \ MagickWand/pixel-iterator.c \ MagickWand/pixel-iterator.h \ MagickWand/pixel-wand.c \ @@ -68,6 +67,9 @@ MAGICKWAND_SOURCES = \ MagickWand/studio.h \ MagickWand/wand.c \ MagickWand/wand.h \ + MagickWand/wandcli.c \ + MagickWand/wandcli.h \ + MagickWand/wandcli-private.h \ MagickWand/wand-view.c \ MagickWand/wand-view.h @@ -93,16 +95,17 @@ MAGICKWAND_INCLUDE_HDRS = \ MagickWand/pixel-iterator.h \ MagickWand/pixel-wand.h \ MagickWand/stream.h \ + MagickWand/wandcli.h \ MagickWand/wand-view.h MAGICKWAND_NOINST_HDRS = \ MagickWand/mogrify-private.h \ MagickWand/magick-wand-private.h \ - MagickWand/operation-private.h \ MagickWand/pixel-wand-private.h \ MagickWand/script-token.h \ MagickWand/studio.h \ MagickWand/wand.h + MagickWand/wandcli-private.h \ # Headers which are installed MagickWandinc_HEADERS = \ diff --git a/MagickWand/magick-cli.c b/MagickWand/magick-cli.c index 21a3bea5d..a4fa67dea 100644 --- a/MagickWand/magick-cli.c +++ b/MagickWand/magick-cli.c @@ -49,8 +49,9 @@ #include "MagickWand/studio.h" #include "MagickWand/MagickWand.h" #include "MagickWand/magick-wand-private.h" +#include "MagickWand/wandcli.h" +#include "MagickWand/wandcli-private.h" #include "MagickWand/operation.h" -#include "MagickWand/operation-private.h" #include "MagickWand/magick-cli.h" #include "MagickWand/script-token.h" #include "MagickCore/utility-private.h" @@ -247,13 +248,20 @@ WandExport void ProcessScriptOptions(MagickCLI *cli_wand,int argc,char **argv, (void) FormatLocaleFile(stderr, "Script %u,%u Non-Option: \"%s\"\n", cli_wand->line, cli_wand->line, option); #endif - if ( IfMagickFalse(IsCommandOption(option))) + if ( IfMagickFalse(IsCommandOption(option))) { /* non-option -- treat as a image read */ CLISpecialOperator(cli_wand,"-read",option); - else + goto next_token; + } + if ( LocaleCompare(option,"-script") == 0 ) { + option_type=SpecialOptionFlag; + count=1; + /* fall thru - collect one argument */ + } + else { CLIWandExceptionBreak(OptionFatalError,"UnrecognizedOption",option); - count = 0; - goto next_token; + goto next_token; + } } if ( count >= 1 ) { @@ -307,7 +315,8 @@ WandExport void ProcessScriptOptions(MagickCLI *cli_wand,int argc,char **argv, if ( LocaleCompare(option,"-exit") == 0 ) { break; /* forced end of script */ } - if ( LocaleCompare(option,"-script") == 0 ) { + else if ( LocaleCompare(option,"-script") == 0 ) { + /* FUTURE: call new script from this script */ CLIWandExceptionBreak(OptionError,"InvalidUseOfOption",option); goto next_token; } @@ -481,13 +490,24 @@ WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc, #if MagickCommandDebug >= 3 (void) FormatLocaleFile(stderr, "CLI %d Non-Option: \"%s\"\n", i, option); #endif - if ( IfMagickFalse(IsCommandOption(option) ) && - (process_flags & ProcessNonOptionImageRead) != 0 ) - /* non-option -- treat as a image read */ - CLISpecialOperator(cli_wand,"-read",option); - else if ( (process_flags & ProcessUnknownOptionError) != 0 ) - CLIWandException(OptionFatalError,"UnrecognizedOption",option); - count = 0; + if ( IfMagickFalse(IsCommandOption(option)) ) { + if ( (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) && + (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 + must be handled here to prevent 'missing argument' error. + */ + ProcessScriptOptions(cli_wand,argc,argv,i+1); + return(argc); /* Script does not return to CLI -- Yet -- FUTURE */ + } + CLIWandException(OptionFatalError,"UnrecognizedOption",option); goto next_argument; } @@ -526,19 +546,13 @@ WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc, if ( ( process_flags & ProcessExitOption ) != 0 && LocaleCompare(option,"-exit") == 0 ) return(i+count); - if ( ( process_flags & ProcessScriptOption ) != 0 - && LocaleCompare(option,"-script") == 0) { - // Call Script, with a filename as a zeroth argument - ProcessScriptOptions(cli_wand,argc,argv,i+1); - return(argc); /* no more options after script process! */ - } /* handle any other special operators now */ CLISpecialOperator(cli_wand,option,arg1); } if ( (option_type & SettingOptionFlags) != 0 ) { CLISettingOptionInfo(cli_wand, option, arg1); - // FUTURE: Sync Specific Settings into Image Properities (not global) + // FUTURE: Sync individual Settings into images (no SyncImageSettings()) } if ( cli_wand->wand.images != (Image *)NULL ) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images, @@ -596,8 +610,6 @@ next_argument: return(argc); } - (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images, - cli_wand->wand.exception); CLISpecialOperator(cli_wand,"-write",option); return(argc); } diff --git a/MagickWand/magick-cli.h b/MagickWand/magick-cli.h index e50bcb18d..ecf8f5cbb 100644 --- a/MagickWand/magick-cli.h +++ b/MagickWand/magick-cli.h @@ -26,8 +26,11 @@ typedef enum { /* What options should be processed */ /* NonOption Handling */ - ProcessNonOptionImageRead = 0x0001, /* non-option is a image read */ - ProcessUnknownOptionError = 0x0002, /* unknown option produces error */ + 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 */ diff --git a/MagickWand/operation.c b/MagickWand/operation.c index fc4c1fc74..69c73480e 100644 --- a/MagickWand/operation.c +++ b/MagickWand/operation.c @@ -50,9 +50,10 @@ #include "MagickWand/studio.h" #include "MagickWand/MagickWand.h" #include "MagickWand/magick-wand-private.h" -#include "MagickWand/operation.h" -#include "MagickWand/operation-private.h" #include "MagickWand/wand.h" +#include "MagickWand/wandcli.h" +#include "MagickWand/wandcli-private.h" +#include "MagickWand/operation.h" #include "MagickCore/monitor-private.h" #include "MagickCore/thread-private.h" #include "MagickCore/string-private.h" @@ -147,6 +148,27 @@ static inline Image *GetImageCache(const ImageInfo *image_info,const char *path, return(image); } +/* + FloatListOption() converts a string option of space or comma seperated + numbers into a list of floating point numbers, required by some operations. +*/ +static MagickBooleanType FloatListOption(const char *option, + size_t *number_arguments, double **arguments, ExceptionInfo *exception) +{ + char + token[MaxTextExtent]; + + const char + *p; + + MagickBooleanType + error; + + register size_t + x; + +} + /* SparseColorOption() parse the complex -sparse-color argument into an an array of floating point values than call SparseColorImage(). @@ -356,201 +378,6 @@ static Image *SparseColorOption(const Image *image, % % % % % % -+ A c q u i r e W a n d C L I % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% AcquireMagickCLI() creates a new CLI wand (an expanded form of Magick -% Wand). The given image_info and exception is included as is if provided. -% -% Use DestroyMagickCLI() to dispose of the CLI wand when it is no longer -% needed. -% -% The format of the NewMagickWand method is: -% -% MagickCLI *AcquireMagickCLI(ImageInfo *image_info, -% ExceptionInfo *exception) -% -*/ -WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info, - ExceptionInfo *exception) -{ - MagickCLI - *cli_wand; - - /* precaution - as per NewMagickWand() */ - { - size_t depth = MAGICKCORE_QUANTUM_DEPTH; - const char *quantum = GetMagickQuantumDepth(&depth); - if (depth != MAGICKCORE_QUANTUM_DEPTH) - ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum); - } - - /* allocate memory for MgaickCLI */ - cli_wand=(MagickCLI *) AcquireMagickMemory(sizeof(*cli_wand)); - if (cli_wand == (MagickCLI *) NULL) - { - ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", - GetExceptionMessage(errno)); - return((MagickCLI *)NULL); - } - - /* Initialize Wand Part of MagickCLI - FUTURE: this is a repeat of code from NewMagickWand() - However some parts may be given fro man external source! - */ - cli_wand->wand.id=AcquireWandId(); - (void) FormatLocaleString(cli_wand->wand.name,MaxTextExtent, - "%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id); - cli_wand->wand.images=NewImageList(); - if ( image_info == (ImageInfo *)NULL) - cli_wand->wand.image_info=AcquireImageInfo(); - else - cli_wand->wand.image_info=image_info; - if ( exception == (ExceptionInfo *)NULL) - cli_wand->wand.exception=AcquireExceptionInfo(); - else - cli_wand->wand.exception=exception; - cli_wand->wand.debug=IsEventLogging(); - cli_wand->wand.signature=WandSignature; - - /* Initialize CLI Part of MagickCLI */ - cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL); - 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->line=0; - cli_wand->column=0; - cli_wand->signature=WandSignature; - - if (IfMagickTrue(cli_wand->wand.debug)) - (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); - return(cli_wand); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ D e s t r o y W a n d C L I % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% DestroyMagickCLI() destorys everything in a CLI wand, including image_info -% and any exceptions, if still present in the wand. -% -% The format of the NewMagickWand method is: -% -% MagickWand *DestroyMagickCLI() -% Exception *exception) -% -*/ -WandExport MagickCLI *DestroyMagickCLI(MagickCLI *cli_wand) -{ - Stack - *node; - - assert(cli_wand != (MagickCLI *) NULL); - assert(cli_wand->signature == WandSignature); - assert(cli_wand->wand.signature == WandSignature); - if (IfMagickTrue(cli_wand->wand.debug)) - (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); - - /* Destroy CLI part of MagickCLI */ - if (cli_wand->draw_info != (DrawInfo *) NULL ) - cli_wand->draw_info=DestroyDrawInfo(cli_wand->draw_info); - if (cli_wand->quantize_info != (QuantizeInfo *) NULL ) - cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info); - while(cli_wand->image_list_stack != (Stack *)NULL) - { - node=cli_wand->image_list_stack; - cli_wand->image_list_stack=node->next; - (void) DestroyImageList((Image *)node->data); - (void) RelinquishMagickMemory(node); - } - while(cli_wand->image_info_stack != (Stack *)NULL) - { - node=cli_wand->image_info_stack; - cli_wand->image_info_stack=node->next; - (void) DestroyImageInfo((ImageInfo *)node->data); - (void) RelinquishMagickMemory(node); - } - cli_wand->signature=(~WandSignature); - - /* Destroy Wand part MagickCLI */ - cli_wand->wand.images=DestroyImageList(cli_wand->wand.images); - if (cli_wand->wand.image_info != (ImageInfo *) NULL ) - cli_wand->wand.image_info=DestroyImageInfo(cli_wand->wand.image_info); - if (cli_wand->wand.exception != (ExceptionInfo *) NULL ) - cli_wand->wand.exception=DestroyExceptionInfo(cli_wand->wand.exception); - RelinquishWandId(cli_wand->wand.id); - cli_wand->wand.signature=(~WandSignature); - - return((MagickCLI *)NULL); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ C L I C a t c h E x c e p t i o n % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% CLICatchException() will report exceptions, either just non-fatal warnings -% only, or all errors, according to 'all_execeptions' boolean argument. -% -% The function returns true is errors are fatal, in which case the caller -% should abort and re-call with an 'all_exceptions' argument of true before -% quitting. -% -% The cut-off level between fatal and non-fatal may be controlled by options -% (FUTURE), but defaults to 'Error' exceptions. -% -% The format of the CLICatchException method is: -% -% MagickBooleanType CLICatchException(MagickCLI *cli_wand, -% const MagickBooleanType all_exceptions ); -% -*/ -WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand, - const MagickBooleanType all_exceptions ) -{ - MagickBooleanType - status; - assert(cli_wand != (MagickCLI *) NULL); - assert(cli_wand->signature == WandSignature); - assert(cli_wand->wand.signature == WandSignature); - if (IfMagickTrue(cli_wand->wand.debug)) - (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); - - // FUTURE: '-regard_warning' should make this more sensitive. - // Note pipelined options may like more control over this level - - status = IsMagickTrue(cli_wand->wand.exception->severity > ErrorException); - - if ( IfMagickFalse(status) || IfMagickTrue(all_exceptions) ) - CatchException(cli_wand->wand.exception); /* output and clear exceptions */ - - return(status); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % + C L I S e t t i n g O p t i o n I n f o % % % % % @@ -1177,6 +1004,21 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand, (void) SetImageOption(_image_info,option+1,ArgOption(NULL)); break; } + if (LocaleCompare("limit",option+1) == 0) + { + MagickSizeType + limit; + + limit=MagickResourceInfinity; + parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1); + if ( parse < 0 ) + CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType", + option,arg1); + if (LocaleCompare("unlimited",arg2) != 0) + limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0); + (void) SetMagickResourceLimit((ResourceType)parse,limit); + break; + } if (LocaleCompare("log",option+1) == 0) { if (IfSetOption) { @@ -1392,6 +1234,12 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand, _draw_info->render= ArgBooleanNot; break; } + if (LocaleCompare("respect-parenthesis",option+1) == 0) + { + /* link image and setting stacks - option is itself saved on stack! */ + (void) SetImageOption(_image_info,option+1,ArgBooleanString); + break; + } CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option); } case 's': @@ -4213,21 +4061,6 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand, } break; } - if (LocaleCompare("limit",option+1) == 0) - { - MagickSizeType - limit; - - limit=MagickResourceInfinity; - parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1); - if ( parse < 0 ) - CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType", - option,arg1); - if (LocaleCompare("unlimited",arg2) != 0) - limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0); - (void) SetMagickResourceLimit((ResourceType)parse,limit); - break; - } CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option); } case 'm': @@ -4456,11 +4289,12 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand, % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% CLISpecialOption() Applies operations that may involve empty image lists -% and or stacks of image lists or image_info settings. +% CLISpecialOperator() Applies operations that may not actually need images +% in an image list wen it is applied. % -% The classic operators of this type is -read, and image stack operators, -% which can be applied to empty image lists. +% 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. % % Note: unlike other Operators, these may involve other special 'option' % character prefixes, other than simply '-' or '+'. @@ -4518,15 +4352,15 @@ WandExport void CLISpecialOperator(MagickCLI *cli_wand, (void) SyncImagesSettings(cli_wand->wand.image_info,_images,_exception); /* - No-op options + No-op options (ignore these) */ - if (LocaleCompare("noop",option+1) == 0) + if (LocaleCompare("noop",option+1) == 0) /* no argument */ return; - if (LocaleCompare("sans",option+1) == 0) + if (LocaleCompare("sans",option+1) == 0) /* one argument */ return; - if (LocaleCompare("sans0",option+1) == 0) + if (LocaleCompare("sans0",option+1) == 0) /* no argument */ return; - if (LocaleCompare("sans2",option+1) == 0) + if (LocaleCompare("sans2",option+1) == 0) /* two arguments */ return; /* Image Reading @@ -4574,7 +4408,7 @@ WandExport void CLISpecialOperator(MagickCLI *cli_wand, return; } /* - Image Writing + Image Writing (no-images present is valid in specific cases) */ if (LocaleCompare("write",option+1) == 0) { char @@ -4608,12 +4442,6 @@ WandExport void CLISpecialOperator(MagickCLI *cli_wand, /* 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, - IfNormalOp ? "true" : (char *) NULL); - return; - } if (LocaleCompare("(",option) == 0) { /* stack 'push' images */ Stack diff --git a/MagickWand/operation.h b/MagickWand/operation.h index 18b94c467..d0908c115 100644 --- a/MagickWand/operation.h +++ b/MagickWand/operation.h @@ -15,23 +15,13 @@ MagickWand command-line option process. */ -#ifndef _MAGICKWAND_Op_H -#define _MAGICKWAND_Op_H +#ifndef _MAGICKWAND_OPERATION_H +#define _MAGICKWAND_OPERATION_H #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -typedef struct _MagickCLI - MagickCLI; - -extern WandExport MagickCLI - *AcquireMagickCLI(ImageInfo *,ExceptionInfo *), - *DestroyMagickCLI(MagickCLI *); - -extern WandExport MagickBooleanType - CLICatchException(MagickCLI *,const MagickBooleanType); - extern WandExport void CLISettingOptionInfo(MagickCLI *,const char *,const char *), CLISimpleOperatorImages(MagickCLI *,const char *,const char *,const char *), diff --git a/MagickWand/script-token.c b/MagickWand/script-token.c index 8e02ea54f..a9f1ba6ee 100644 --- a/MagickWand/script-token.c +++ b/MagickWand/script-token.c @@ -8,7 +8,7 @@ % S C R R I P T T O O K K E N NN % % SSSS CCC R RR III P T T OOO K K EEEE N N % % % -% Perform "Magick" on Images via the Command Line Interface % +% Tokenize Magick Script into Options % % % % Dragon Computing % % Anthony Thyssen % @@ -31,7 +31,79 @@ % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% Read a stream of characters and return tokens one at a time +% Read a stream of characters and return tokens one at a time. +% +% The input stream is dived into individual 'tokens' (representing 'words' or +% 'options'), in a way that is as close to a UNIX shell, as is feasable. +% Only shell variable, and command substitutions will not be performed. +% Tokens can be any length. +% +% The main function call is GetScriptToken() (see below) whcih returns one +% and only one token at a time. The other functions provide support to this +% function, opening scripts, and seting up the required structures. +% +% More specifically... +% +% Tokens are white space separated, and may be quoted, or even partially +% quoted by either single or double quotes, or the use of backslashes, +% or any mix of the three. +% +% For example: This\ is' a 'single" token" +% +% A token is returned immediatally the end of token is found. That is as soon +% as a unquoted white-space or EOF condition has been found. That is to say +% the file stream is parsed purely character-by-character, regardless any +% buffering constraints set by the system. It is not parsed line-by-line. +% +% The function will return 'MagickTrue' if a valid token was found, while +% the token status will be set accordingally to 'OK' or 'EOF', according to +% the cause of the end of token. The token may be an empty string if the +% input was a quoted empty string. Other error conditions return a value of +% MagickFalse, indicating any token found but was incomplete due to some +% error condition. +% +% Single quotes will preserve all characters including backslashes. Double +% quotes will also preserve backslashes unless escaping a double quote, +% or another backslashes. Other shell meta-characters are not treated as +% special by this tokenizer. +% +% For example Quoting the quote chars: +% \' "'" \" '"' "\"" \\ '\' "\\" +% +% Outside quotes, backslash characters will make spaces, tabs and quotes part +% of a token returned. However a backslash at the end of a line (and outside +% quotes) will cause the newline to be completely ignored (as per the shell +% line continuation). +% +% Comments start with a '#' character at the start of a new token, will be +% completely ignored upto the end of line, regardless of any backslash at the +% 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 +% +% #!/path/to/command/magick -script +% +% or +% +% #!/usr/bin/env magick-script +% +% 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. +% +% #!/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 % */ @@ -158,60 +230,8 @@ WandExport ScriptTokenInfo * DestroyScriptTokenInfo(ScriptTokenInfo *token_info) % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% GetScriptToken() is fairly general, finite state token parser. That will -% divide a input file stream into tokens, in a way that is as close to a -% UNIX shell, as is feasable. Only shell variable, and command -% substitutions will not be performed. Tokens can be any length. -% -% Tokens are white space separated, and may be quoted, or even partially -% quoted by either single or double quotes, or the use of backslashes, -% or any mix of the three. -% -% For example: This\ is' a 'single" token" -% -% A token is returned immediatally the end of token is found. That is as soon -% as a unquoted white-space or EOF condition has been found. That is to say -% the file stream is parsed purely character-by-character, regardless any -% buffering constraints set by the system. It is not parsed line-by-line. -% -% The function will return 'MagickTrue' if a valid token was found, while -% the token status will be set accordingally to 'OK' or 'EOF', according to -% the cause of the end of token. The token may be an empty string if the -% input was a quoted empty string. Other error conditions return a value of -% MagickFalse, indicating any token found but was incomplete due to some -% error condition. -% -% Single quotes will preserve all characters including backslashes. Double -% quotes will also preserve backslashes unless escaping a double quote, -% or another backslashes. Other shell meta-characters are not treated as -% special by this tokenizer. -% -% For example Quoting the quote chars: -% \' "'" \" '"' "\"" \\ '\' "\\" -% -% Outside quotes, backslash characters will make spaces, tabs and quotes part -% of a token returned. However a backslash at the end of a line (and outside -% quotes) will cause the newline to be completely ignored (as per the shell -% line continuation). -% -% Comments start with a '#' character at the start of a new token, will be -% completely ignored upto the end of line, regardless of any backslash at the -% 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 +% GetScriptToken() a fairly general, finite state token parser. That returns +% tokens one at a time, as soon as posible. % % % The format of the GetScriptToken method is: diff --git a/MagickWand/operation-private.h b/MagickWand/wandcli-private.h similarity index 97% rename from MagickWand/operation-private.h rename to MagickWand/wandcli-private.h index 09bfa285a..e0b8a834f 100644 --- a/MagickWand/operation-private.h +++ b/MagickWand/wandcli-private.h @@ -15,8 +15,8 @@ ImageMagick pixel wand API. */ -#ifndef _OPERATION_PRIVATE_H -#define _OPERATION_PRIVATE_H +#ifndef _MAGCIKWAND_WANDCLI_PRIVATE_H +#define _MAGCIKWAND_WANDCLI_PRIVATE_H #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/MagickWand/wandcli.c b/MagickWand/wandcli.c new file mode 100644 index 000000000..9329c33c9 --- /dev/null +++ b/MagickWand/wandcli.c @@ -0,0 +1,243 @@ +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% M M AA GGG III CCC W W AA N N DDD CCC L III % +% MM MM A A G I C W W A A NN N D D C L I % +% M M M AAAA G GG I C W W W AAAA N N N D D C L I % +% M M A A G G I C W W W A A N NN D D C L I % +% M M A A GGG III CCC W W A A N N DDD CCC LLLL III % +% % +% % +% WandCLI Structure Methods % +% % +% Dragon Computing % +% Anthony Thyssen % +% April 2011 % +% % +% % +% Copyright 1999-2012 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 % +% obtain a copy of the License at % +% % +% http://www.imagemagick.org/script/license.php % +% % +% Unless required by applicable law or agreed to in writing, software % +% distributed under the License is distributed on an "AS IS" BASIS, % +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % +% See the License for the specific language governing permissions and % +% limitations under the License. % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% General methds for handling the WandCLI structure used for Command Line. +% +% Anthony Thyssen, April 2011 +*/ + +/* + Include declarations. +*/ +#include "MagickWand/studio.h" +#include "MagickWand/MagickWand.h" +#include "MagickWand/magick-wand-private.h" +#include "MagickWand/wandcli.h" +#include "MagickWand/wandcli-private.h" + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % ++ A c q u i r e W a n d C L I % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% AcquireMagickCLI() creates a new CLI wand (an expanded form of Magick +% Wand). The given image_info and exception is included as is if provided. +% +% Use DestroyMagickCLI() to dispose of the CLI wand when it is no longer +% needed. +% +% The format of the NewMagickWand method is: +% +% MagickCLI *AcquireMagickCLI(ImageInfo *image_info, +% ExceptionInfo *exception) +% +*/ +WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info, + ExceptionInfo *exception) +{ + MagickCLI + *cli_wand; + + /* precaution - as per NewMagickWand() */ + { + size_t depth = MAGICKCORE_QUANTUM_DEPTH; + const char *quantum = GetMagickQuantumDepth(&depth); + if (depth != MAGICKCORE_QUANTUM_DEPTH) + ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum); + } + + /* allocate memory for MgaickCLI */ + cli_wand=(MagickCLI *) AcquireMagickMemory(sizeof(*cli_wand)); + if (cli_wand == (MagickCLI *) NULL) + { + ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", + GetExceptionMessage(errno)); + return((MagickCLI *)NULL); + } + + /* Initialize Wand Part of MagickCLI + FUTURE: this is a repeat of code from NewMagickWand() + However some parts may be given fro man external source! + */ + cli_wand->wand.id=AcquireWandId(); + (void) FormatLocaleString(cli_wand->wand.name,MaxTextExtent, + "%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id); + cli_wand->wand.images=NewImageList(); + if ( image_info == (ImageInfo *)NULL) + cli_wand->wand.image_info=AcquireImageInfo(); + else + cli_wand->wand.image_info=image_info; + if ( exception == (ExceptionInfo *)NULL) + cli_wand->wand.exception=AcquireExceptionInfo(); + else + cli_wand->wand.exception=exception; + cli_wand->wand.debug=IsEventLogging(); + cli_wand->wand.signature=WandSignature; + + /* Initialize CLI Part of MagickCLI */ + cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL); + 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->line=0; + cli_wand->column=0; + cli_wand->signature=WandSignature; + + if (IfMagickTrue(cli_wand->wand.debug)) + (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); + return(cli_wand); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % ++ D e s t r o y W a n d C L I % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DestroyMagickCLI() destorys everything in a CLI wand, including image_info +% and any exceptions, if still present in the wand. +% +% The format of the NewMagickWand method is: +% +% MagickWand *DestroyMagickCLI() +% Exception *exception) +% +*/ +WandExport MagickCLI *DestroyMagickCLI(MagickCLI *cli_wand) +{ + Stack + *node; + + assert(cli_wand != (MagickCLI *) NULL); + assert(cli_wand->signature == WandSignature); + assert(cli_wand->wand.signature == WandSignature); + if (IfMagickTrue(cli_wand->wand.debug)) + (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); + + /* Destroy CLI part of MagickCLI */ + if (cli_wand->draw_info != (DrawInfo *) NULL ) + cli_wand->draw_info=DestroyDrawInfo(cli_wand->draw_info); + if (cli_wand->quantize_info != (QuantizeInfo *) NULL ) + cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info); + while(cli_wand->image_list_stack != (Stack *)NULL) + { + node=cli_wand->image_list_stack; + cli_wand->image_list_stack=node->next; + (void) DestroyImageList((Image *)node->data); + (void) RelinquishMagickMemory(node); + } + while(cli_wand->image_info_stack != (Stack *)NULL) + { + node=cli_wand->image_info_stack; + cli_wand->image_info_stack=node->next; + (void) DestroyImageInfo((ImageInfo *)node->data); + (void) RelinquishMagickMemory(node); + } + cli_wand->signature=(~WandSignature); + + /* Destroy Wand part MagickCLI */ + cli_wand->wand.images=DestroyImageList(cli_wand->wand.images); + if (cli_wand->wand.image_info != (ImageInfo *) NULL ) + cli_wand->wand.image_info=DestroyImageInfo(cli_wand->wand.image_info); + if (cli_wand->wand.exception != (ExceptionInfo *) NULL ) + cli_wand->wand.exception=DestroyExceptionInfo(cli_wand->wand.exception); + RelinquishWandId(cli_wand->wand.id); + cli_wand->wand.signature=(~WandSignature); + + return((MagickCLI *)NULL); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % ++ C L I C a t c h E x c e p t i o n % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% CLICatchException() will report exceptions, either just non-fatal warnings +% only, or all errors, according to 'all_execeptions' boolean argument. +% +% The function returns true is errors are fatal, in which case the caller +% should abort and re-call with an 'all_exceptions' argument of true before +% quitting. +% +% The cut-off level between fatal and non-fatal may be controlled by options +% (FUTURE), but defaults to 'Error' exceptions. +% +% The format of the CLICatchException method is: +% +% MagickBooleanType CLICatchException(MagickCLI *cli_wand, +% const MagickBooleanType all_exceptions ); +% +*/ +WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand, + const MagickBooleanType all_exceptions ) +{ + MagickBooleanType + status; + assert(cli_wand != (MagickCLI *) NULL); + assert(cli_wand->signature == WandSignature); + assert(cli_wand->wand.signature == WandSignature); + if (IfMagickTrue(cli_wand->wand.debug)) + (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); + + // FUTURE: '-regard_warning' should make this more sensitive. + // Note pipelined options may like more control over this level + + status = IsMagickTrue(cli_wand->wand.exception->severity > ErrorException); + + if ( IfMagickFalse(status) || IfMagickTrue(all_exceptions) ) + CatchException(cli_wand->wand.exception); /* output and clear exceptions */ + + return(status); +} diff --git a/MagickWand/wandcli.h b/MagickWand/wandcli.h new file mode 100644 index 000000000..d386395cd --- /dev/null +++ b/MagickWand/wandcli.h @@ -0,0 +1,39 @@ +/* + Copyright 1999-2012 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. + obtain a copy of the License at + + http://www.imagemagick.org/script/license.php + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + MagickWand command-line option process. +*/ +#ifndef _MAGICKWAND_WAND_CLI_H +#define _MAGICKWAND_WAND_CLI_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef struct _MagickCLI + MagickCLI; + +extern WandExport MagickCLI + *AcquireMagickCLI(ImageInfo *,ExceptionInfo *), + *DestroyMagickCLI(MagickCLI *); + +extern WandExport MagickBooleanType + CLICatchException(MagickCLI *,const MagickBooleanType); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif