anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 1 | /* |
| 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 3 | % % |
| 4 | % % |
| 5 | % % |
| 6 | % M M AAA GGGG IIIII CCCC K K % |
| 7 | % MM MM A A G I C K K % |
| 8 | % M M M AAAAA G GGG I C KKK % |
| 9 | % M M A A G G I C K K % |
| 10 | % M M A A GGGG IIIII CCCC K K % |
| 11 | % % |
| 12 | % CCCC L IIIII % |
| 13 | % C L I % |
| 14 | % C L I % |
| 15 | % C L I % |
| 16 | % CCCC LLLLL IIIII % |
| 17 | % % |
| 18 | % Perform "Magick" on Images via the Command Line Interface % |
| 19 | % % |
| 20 | % Dragon Computing % |
| 21 | % Anthony Thyssen % |
| 22 | % January 2012 % |
| 23 | % % |
| 24 | % % |
cristy | fe676ee | 2013-11-18 13:03:38 +0000 | [diff] [blame^] | 25 | % Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization % |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 26 | % dedicated to making software imaging solutions freely available. % |
| 27 | % % |
| 28 | % You may not use this file except in compliance with the License. You may % |
| 29 | % obtain a copy of the License at % |
| 30 | % % |
| 31 | % http://www.imagemagick.org/script/license.php % |
| 32 | % % |
| 33 | % Unless required by applicable law or agreed to in writing, software % |
| 34 | % distributed under the License is distributed on an "AS IS" BASIS, % |
| 35 | % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
| 36 | % See the License for the specific language governing permissions and % |
| 37 | % limitations under the License. % |
| 38 | % % |
| 39 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 40 | % |
| 41 | % Read CLI arguments, script files, and pipelines, to provide options that |
| 42 | % manipulate images from many different formats. |
| 43 | % |
| 44 | */ |
| 45 | |
| 46 | /* |
| 47 | Include declarations. |
| 48 | */ |
| 49 | #include "MagickWand/studio.h" |
| 50 | #include "MagickWand/MagickWand.h" |
| 51 | #include "MagickWand/magick-wand-private.h" |
anthony | 756cd0d | 2012-04-08 12:41:44 +0000 | [diff] [blame] | 52 | #include "MagickWand/wandcli.h" |
| 53 | #include "MagickWand/wandcli-private.h" |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 54 | #include "MagickWand/operation.h" |
anthony | 2052d27 | 2012-02-28 12:48:29 +0000 | [diff] [blame] | 55 | #include "MagickWand/magick-cli.h" |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 56 | #include "MagickWand/script-token.h" |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 57 | #include "MagickCore/utility-private.h" |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 58 | #include "MagickCore/exception-private.h" |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 59 | #include "MagickCore/version.h" |
| 60 | |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 61 | /* verbose debugging, |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 62 | 0 - no debug lines |
| 63 | 3 - show option details (better to use -debug Command now) |
| 64 | 5 - image counts (after option runs) |
anthony | 24aa882 | 2012-03-11 00:56:06 +0000 | [diff] [blame] | 65 | */ |
anthony | 2cfa1a1 | 2012-05-12 05:18:07 +0000 | [diff] [blame] | 66 | #define MagickCommandDebug 0 |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 67 | |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 68 | |
| 69 | /* |
| 70 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 71 | % % |
| 72 | % % |
| 73 | % % |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 74 | + P r o c e s s S c r i p t O p t i o n s % |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 75 | % % |
| 76 | % % |
| 77 | % % |
| 78 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 79 | % |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 80 | % ProcessScriptOptions() reads options and processes options as they are |
| 81 | % found in the given file, or pipeline. The filename to open and read |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 82 | % options is given as the 'index' argument of the argument array given. |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 83 | % |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 84 | % Other arguments following index may be read by special script options |
| 85 | % as settings (strings), images, or as operations to be processed in various |
| 86 | % ways. How they are treated is up to the script being processed. |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 87 | % |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 88 | % Note that a script not 'return' to the command line processing, nor can |
| 89 | % they call (and return from) other scripts. At least not at this time. |
| 90 | % |
| 91 | % There are no 'ProcessOptionFlags' control flags at this time. |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 92 | % |
| 93 | % The format of the ProcessScriptOptions method is: |
| 94 | % |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 95 | % void ProcessScriptOptions(MagickCLI *cli_wand,const char *filename, |
| 96 | % int argc,char **argv,int index) |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 97 | % |
| 98 | % A description of each parameter follows: |
| 99 | % |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 100 | % o cli_wand: the main CLI Wand to use. |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 101 | % |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 102 | % o filename: the filename of script to process |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 103 | % |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 104 | % o argc: the number of elements in the argument vector. (optional) |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 105 | % |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 106 | % o argv: A text array containing the command line arguments. (optional) |
| 107 | % |
| 108 | % o index: offset of next argment in argv (script arguments) (optional) |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 109 | % |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 110 | */ |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 111 | WandExport void ProcessScriptOptions(MagickCLI *cli_wand,const char *filename, |
| 112 | int argc,char **argv,int index) |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 113 | { |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 114 | ScriptTokenInfo |
| 115 | *token_info; |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 116 | |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 117 | CommandOptionFlags |
| 118 | option_type; |
| 119 | |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 120 | int |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 121 | count; |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 122 | |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 123 | char |
| 124 | *option, |
| 125 | *arg1, |
| 126 | *arg2; |
| 127 | |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 128 | assert(filename != (char *)NULL ); /* at least one argument - script name */ |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 129 | assert(cli_wand != (MagickCLI *) NULL); |
| 130 | assert(cli_wand->signature == WandSignature); |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 131 | if (IfMagickTrue(cli_wand->wand.debug)) |
| 132 | (void) LogMagickEvent(CommandEvent,GetMagickModule(), |
| 133 | "Processing script \"%s\"", filename); |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 134 | |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 135 | /* open file script or stream, and set up tokenizer */ |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 136 | token_info = AcquireScriptTokenInfo(filename); |
anthony | 8ac75b5 | 2012-03-18 11:56:44 +0000 | [diff] [blame] | 137 | if (token_info == (ScriptTokenInfo *) NULL) { |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 138 | CLIWandExceptionFile(OptionFatalError,"UnableToOpenScript",filename); |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 139 | return; |
| 140 | } |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 141 | |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 142 | /* define the error location string for use in exceptions |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 143 | order of localtion format escapes: filename, line, column */ |
| 144 | cli_wand->location="in \"%s\" at line %u,column %u"; |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 145 | if ( LocaleCompare("-", filename) == 0 ) |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 146 | cli_wand->filename="stdin"; |
| 147 | else |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 148 | cli_wand->filename=filename; |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 149 | |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 150 | /* Process Options from Script */ |
| 151 | option = arg1 = arg2 = (char*)NULL; |
dirk | 93b02b7 | 2013-11-16 16:03:36 +0000 | [diff] [blame] | 152 | DisableMSCWarning(4127) |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 153 | while (1) { |
dirk | 93b02b7 | 2013-11-16 16:03:36 +0000 | [diff] [blame] | 154 | RestoreMSCWarning |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 155 | |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 156 | { MagickBooleanType status = GetScriptToken(token_info); |
| 157 | cli_wand->line=token_info->token_line; |
| 158 | cli_wand->column=token_info->token_column; |
anthony | 84d4279 | 2012-03-30 14:08:38 +0000 | [diff] [blame] | 159 | if( IfMagickFalse(status) ) |
| 160 | break; /* error or end of options */ |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 161 | } |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 162 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 163 | do { /* use break to loop to exception handler and loop */ |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 164 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 165 | /* save option details */ |
| 166 | CloneString(&option,token_info->token); |
| 167 | |
| 168 | /* get option, its argument count, and option type */ |
| 169 | cli_wand->command = GetCommandOptionInfo(option); |
| 170 | count=cli_wand->command->type; |
| 171 | option_type=(CommandOptionFlags) cli_wand->command->flags; |
anthony | f125a5e | 2012-04-03 13:14:42 +0000 | [diff] [blame] | 172 | #if 0 |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 173 | (void) FormatLocaleFile(stderr, "Script: %u,%u: \"%s\" matched \"%s\"\n", |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 174 | cli_wand->line, cli_wand->line, option, cli_wand->command->mnemonic ); |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 175 | #endif |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 176 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 177 | /* handle a undefined option - image read - always for "magick-script" */ |
| 178 | if ( option_type == UndefinedOptionFlag || |
| 179 | (option_type & NonMagickOptionFlag) != 0 ) { |
anthony | f125a5e | 2012-04-03 13:14:42 +0000 | [diff] [blame] | 180 | #if MagickCommandDebug >= 3 |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 181 | (void) FormatLocaleFile(stderr, "Script %u,%u Non-Option: \"%s\"\n", |
| 182 | cli_wand->line, cli_wand->line, option); |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 183 | #endif |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 184 | if ( IfMagickFalse(IsCommandOption(option))) { |
| 185 | /* non-option -- treat as a image read */ |
| 186 | cli_wand->command=(const OptionInfo *)NULL; |
| 187 | CLIOption(cli_wand,"-read",option); |
| 188 | break; /* next option */ |
| 189 | } |
| 190 | CLIWandException(OptionFatalError,"UnrecognizedOption",option); |
| 191 | break; /* next option */ |
anthony | 756cd0d | 2012-04-08 12:41:44 +0000 | [diff] [blame] | 192 | } |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 193 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 194 | if ( count >= 1 ) { |
| 195 | if( IfMagickFalse(GetScriptToken(token_info)) ) |
| 196 | CLIWandException(OptionFatalError,"MissingArgument",option); |
| 197 | CloneString(&arg1,token_info->token); |
| 198 | } |
| 199 | else |
| 200 | CloneString(&arg1,(char *)NULL); |
anthony | 2052d27 | 2012-02-28 12:48:29 +0000 | [diff] [blame] | 201 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 202 | if ( count >= 2 ) { |
| 203 | if( IfMagickFalse(GetScriptToken(token_info)) ) |
| 204 | CLIWandExceptionBreak(OptionFatalError,"MissingArgument",option); |
| 205 | CloneString(&arg2,token_info->token); |
| 206 | } |
| 207 | else |
| 208 | CloneString(&arg2,(char *)NULL); |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 209 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 210 | /* |
| 211 | Process Options |
| 212 | */ |
anthony | f125a5e | 2012-04-03 13:14:42 +0000 | [diff] [blame] | 213 | #if MagickCommandDebug >= 3 |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 214 | (void) FormatLocaleFile(stderr, |
| 215 | "Script %u,%u Option: \"%s\" Count: %d Flags: %04x Args: \"%s\" \"%s\"\n", |
| 216 | cli_wand->line,cli_wand->line,option,count,option_type,arg1,arg2); |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 217 | #endif |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 218 | /* Hard Depreciated Options, no code to execute - error */ |
| 219 | if ( (option_type & DeprecateOptionFlag) != 0 ) { |
| 220 | CLIWandException(OptionError,"DeprecatedOptionNoCode",option); |
| 221 | break; /* next option */ |
anthony | 8226e72 | 2012-04-05 14:25:46 +0000 | [diff] [blame] | 222 | } |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 223 | |
| 224 | /* MagickCommandGenesis() options have no place in a magick script */ |
| 225 | if ( (option_type & GenesisOptionFlag) != 0 ) { |
| 226 | CLIWandException(OptionError,"InvalidUseOfOption",option); |
| 227 | break; /* next option */ |
anthony | 8226e72 | 2012-04-05 14:25:46 +0000 | [diff] [blame] | 228 | } |
anthony | b1d483a | 2012-04-14 12:53:56 +0000 | [diff] [blame] | 229 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 230 | /* handle any special 'script' options */ |
| 231 | if ( (option_type & SpecialOptionFlag) != 0 ) { |
| 232 | if ( LocaleCompare(option,"-exit") == 0 ) { |
anthony | 4837ac2 | 2012-05-18 23:39:48 +0000 | [diff] [blame] | 233 | goto loop_exit; /* break out of loop - return from script */ |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 234 | } |
| 235 | if ( LocaleCompare(option,"-script") == 0 ) { |
| 236 | /* FUTURE: call new script from this script - error for now */ |
| 237 | CLIWandException(OptionError,"InvalidUseOfOption",option); |
| 238 | break; /* next option */ |
| 239 | } |
| 240 | /* FUTURE: handle special script-argument options here */ |
| 241 | /* handle any other special operators now */ |
| 242 | CLIWandException(OptionError,"InvalidUseOfOption",option); |
| 243 | break; /* next option */ |
| 244 | } |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 245 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 246 | /* Process non-specific Option */ |
| 247 | CLIOption(cli_wand, option, arg1, arg2); |
| 248 | |
dirk | 93b02b7 | 2013-11-16 16:03:36 +0000 | [diff] [blame] | 249 | DisableMSCWarning(4127) |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 250 | } while (0); /* break block to next option */ |
dirk | 93b02b7 | 2013-11-16 16:03:36 +0000 | [diff] [blame] | 251 | RestoreMSCWarning |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 252 | |
anthony | be39e6f | 2012-10-05 06:26:31 +0000 | [diff] [blame] | 253 | #if MagickCommandDebug >= 5 |
| 254 | fprintf(stderr, "Script Image Count = %ld\n", |
| 255 | GetImageListLength(cli_wand->wand.images) ); |
| 256 | #endif |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 257 | if ( IfMagickTrue(CLICatchException(cli_wand, MagickFalse)) ) |
| 258 | break; /* exit loop */ |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 259 | } |
| 260 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 261 | /* |
| 262 | Loop exit - check for some tokenization error |
| 263 | */ |
anthony | 4837ac2 | 2012-05-18 23:39:48 +0000 | [diff] [blame] | 264 | loop_exit: |
anthony | f125a5e | 2012-04-03 13:14:42 +0000 | [diff] [blame] | 265 | #if MagickCommandDebug >= 3 |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 266 | (void) FormatLocaleFile(stderr, "Script End: %d\n", token_info->status); |
| 267 | #endif |
| 268 | switch( token_info->status ) { |
| 269 | case TokenStatusOK: |
| 270 | case TokenStatusEOF: |
anthony | 8226e72 | 2012-04-05 14:25:46 +0000 | [diff] [blame] | 271 | if (cli_wand->image_list_stack != (Stack *)NULL) |
| 272 | CLIWandException(OptionError,"UnbalancedParenthesis", "(eof)"); |
| 273 | else if (cli_wand->image_info_stack != (Stack *)NULL) |
| 274 | CLIWandException(OptionError,"UnbalancedBraces", "(eof)"); |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 275 | break; |
| 276 | case TokenStatusBadQuotes: |
| 277 | /* Ensure last token has a sane length for error report */ |
| 278 | if( strlen(token_info->token) > INITAL_TOKEN_LENGTH-1 ) { |
| 279 | token_info->token[INITAL_TOKEN_LENGTH-4] = '.'; |
| 280 | token_info->token[INITAL_TOKEN_LENGTH-3] = '.'; |
| 281 | token_info->token[INITAL_TOKEN_LENGTH-2] = '.'; |
| 282 | token_info->token[INITAL_TOKEN_LENGTH-1] = '\0'; |
| 283 | } |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 284 | CLIWandException(OptionFatalError,"ScriptUnbalancedQuotes", |
| 285 | token_info->token); |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 286 | break; |
| 287 | case TokenStatusMemoryFailed: |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 288 | CLIWandException(OptionFatalError,"ScriptTokenMemoryFailed",""); |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 289 | break; |
| 290 | case TokenStatusBinary: |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 291 | CLIWandException(OptionFatalError,"ScriptIsBinary",""); |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 292 | break; |
| 293 | } |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 294 | if (IfMagickTrue(cli_wand->wand.debug)) |
| 295 | (void) LogMagickEvent(CommandEvent,GetMagickModule(), |
| 296 | "Script End \"%s\"", filename); |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 297 | |
| 298 | /* Clean up */ |
| 299 | token_info = DestroyScriptTokenInfo(token_info); |
| 300 | |
| 301 | CloneString(&option,(char *)NULL); |
| 302 | CloneString(&arg1,(char *)NULL); |
| 303 | CloneString(&arg2,(char *)NULL); |
| 304 | |
| 305 | return; |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 306 | } |
| 307 | |
| 308 | /* |
| 309 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 310 | % % |
| 311 | % % |
| 312 | % % |
| 313 | + P r o c e s s C o m m a n d O p t i o n s % |
| 314 | % % |
| 315 | % % |
| 316 | % % |
| 317 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 318 | % |
| 319 | % ProcessCommandOptions() reads and processes arguments in the given |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 320 | % command line argument array. The 'index' defines where in the array we |
| 321 | % should begin processing |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 322 | % |
| 323 | % The 'process_flags' can be used to control and limit option processing. |
| 324 | % For example, to only process one option, or how unknown and special options |
| 325 | % are to be handled, and if the last argument in array is to be regarded as a |
| 326 | % final image write argument (filename or special coder). |
| 327 | % |
| 328 | % The format of the ProcessCommandOptions method is: |
| 329 | % |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 330 | % int ProcessCommandOptions(MagickCLI *cli_wand, |
| 331 | % int argc,char **argv,int index) |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 332 | % |
| 333 | % A description of each parameter follows: |
| 334 | % |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 335 | % o cli_wand: the main CLI Wand to use. |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 336 | % |
| 337 | % o argc: the number of elements in the argument vector. |
| 338 | % |
| 339 | % o argv: A text array containing the command line arguments. |
| 340 | % |
anthony | 0ea037a | 2012-04-03 12:14:39 +0000 | [diff] [blame] | 341 | % o process_flags: What type of arguments will be processed, ignored |
| 342 | % or return errors. |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 343 | % |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 344 | % o index: index in the argv array to start processing from |
| 345 | % |
| 346 | % The function returns the index ot the next option to be processed. This |
| 347 | % is really only releven if process_flags contains a ProcessOneOptionOnly |
| 348 | % flag. |
| 349 | % |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 350 | */ |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 351 | WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc, |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 352 | char **argv, int index ) |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 353 | { |
| 354 | const char |
| 355 | *option, |
| 356 | *arg1, |
| 357 | *arg2; |
| 358 | |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 359 | int |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 360 | i, |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 361 | end, |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 362 | count; |
| 363 | |
| 364 | CommandOptionFlags |
anthony | 686b1a3 | 2012-02-15 14:50:53 +0000 | [diff] [blame] | 365 | option_type; |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 366 | |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 367 | assert(argc>=index); /* you may have no arguments left! */ |
| 368 | assert(argv != (char **)NULL); |
| 369 | assert(argv[index] != (char *)NULL); |
| 370 | assert(argv[argc-1] != (char *)NULL); |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 371 | assert(cli_wand != (MagickCLI *) NULL); |
| 372 | assert(cli_wand->signature == WandSignature); |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 373 | |
anthony | 92c93bd | 2012-03-19 14:02:47 +0000 | [diff] [blame] | 374 | /* define the error location string for use in exceptions |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 375 | order of localtion format escapes: filename, line, column */ |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 376 | cli_wand->location="at %s arg %u"; |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 377 | cli_wand->filename="CLI"; |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 378 | cli_wand->line=index; /* note first argument we will process */ |
| 379 | |
| 380 | if (IfMagickTrue(cli_wand->wand.debug)) |
| 381 | (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), |
| 382 | "- Starting (\"%s\")", argv[index]); |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 383 | |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 384 | end = argc; |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 385 | if ( (cli_wand->process_flags & ProcessImplictWrite) != 0 ) |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 386 | end--; /* the last arument is an implied write, do not process directly */ |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 387 | |
| 388 | for (i=index; i < end; i += count +1) { |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 389 | /* Finished processing one option? */ |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 390 | if ( (cli_wand->process_flags & ProcessOneOptionOnly) != 0 && i != index ) |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 391 | return(i); |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 392 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 393 | do { /* use break to loop to exception handler and loop */ |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 394 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 395 | option=argv[i]; |
| 396 | cli_wand->line=i; /* note the argument for this option */ |
| 397 | |
| 398 | /* get option, its argument count, and option type */ |
| 399 | cli_wand->command = GetCommandOptionInfo(argv[i]); |
| 400 | count=cli_wand->command->type; |
| 401 | option_type=(CommandOptionFlags) cli_wand->command->flags; |
anthony | f125a5e | 2012-04-03 13:14:42 +0000 | [diff] [blame] | 402 | #if 0 |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 403 | (void) FormatLocaleFile(stderr, "CLI %d: \"%s\" matched \"%s\"\n", |
| 404 | i, argv[i], cli_wand->command->mnemonic ); |
anthony | 686b1a3 | 2012-02-15 14:50:53 +0000 | [diff] [blame] | 405 | #endif |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 406 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 407 | if ( option_type == UndefinedOptionFlag || |
| 408 | (option_type & NonMagickOptionFlag) != 0 ) { |
anthony | f125a5e | 2012-04-03 13:14:42 +0000 | [diff] [blame] | 409 | #if MagickCommandDebug >= 3 |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 410 | (void) FormatLocaleFile(stderr, "CLI arg %d Non-Option: \"%s\"\n", |
| 411 | i, option); |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 412 | #endif |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 413 | if ( IfMagickFalse(IsCommandOption(option)) ) { |
| 414 | if ( (cli_wand->process_flags & ProcessImplictRead) != 0 ) { |
| 415 | /* non-option -- treat as a image read */ |
| 416 | cli_wand->command=(const OptionInfo *)NULL; |
| 417 | CLIOption(cli_wand,"-read",option); |
| 418 | break; /* next option */ |
| 419 | } |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 420 | } |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 421 | CLIWandException(OptionFatalError,"UnrecognizedOption",option); |
| 422 | break; /* next option */ |
anthony | 756cd0d | 2012-04-08 12:41:44 +0000 | [diff] [blame] | 423 | } |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 424 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 425 | if ( ((option_type & SpecialOptionFlag) != 0 ) && |
| 426 | ((cli_wand->process_flags & ProcessScriptOption) != 0) && |
| 427 | (LocaleCompare(option,"-script") == 0) ) { |
| 428 | /* Call Script from CLI, with a filename as a zeroth argument. |
| 429 | NOTE: -script may need to use the 'implict write filename' argument |
| 430 | so it must be handled specially to prevent a 'missing argument' error. |
| 431 | */ |
| 432 | if ( (i+count) >= argc ) |
| 433 | CLIWandException(OptionFatalError,"MissingArgument",option); |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 434 | ProcessScriptOptions(cli_wand,argv[i+1],argc,argv,i+count); |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 435 | return(argc); /* Script does not return to CLI -- Yet */ |
| 436 | /* FUTURE: when it does, their may be no write arg! */ |
| 437 | } |
| 438 | |
| 439 | if ((i+count) >= end ) { |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 440 | CLIWandException(OptionFatalError,"MissingArgument",option); |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 441 | if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse ) |
| 442 | return(end); |
| 443 | break; /* next option - not that their is any! */ |
| 444 | } |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 445 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 446 | arg1 = ( count >= 1 ) ? argv[i+1] : (char *)NULL; |
| 447 | arg2 = ( count >= 2 ) ? argv[i+2] : (char *)NULL; |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 448 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 449 | /* |
| 450 | Process Known Options |
| 451 | */ |
anthony | f125a5e | 2012-04-03 13:14:42 +0000 | [diff] [blame] | 452 | #if MagickCommandDebug >= 3 |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 453 | (void) FormatLocaleFile(stderr, |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 454 | "CLI arg %u Option: \"%s\" Count: %d Flags: %04x Args: \"%s\" \"%s\"\n", |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 455 | i,option,count,option_type,arg1,arg2); |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 456 | #endif |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 457 | /* ignore 'genesis options' in command line args */ |
| 458 | if ( (option_type & GenesisOptionFlag) != 0 ) |
| 459 | break; /* next option */ |
anthony | 8226e72 | 2012-04-05 14:25:46 +0000 | [diff] [blame] | 460 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 461 | /* Handle any special options for CLI (-script handled above) */ |
| 462 | if ( (option_type & SpecialOptionFlag) != 0 ) { |
| 463 | if ( (cli_wand->process_flags & ProcessExitOption) != 0 |
| 464 | && LocaleCompare(option,"-exit") == 0 ) |
| 465 | return(i+count); |
| 466 | break; /* next option */ |
| 467 | } |
anthony | b1d483a | 2012-04-14 12:53:56 +0000 | [diff] [blame] | 468 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 469 | /* Process standard image option */ |
| 470 | CLIOption(cli_wand, option, arg1, arg2); |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 471 | |
dirk | 93b02b7 | 2013-11-16 16:03:36 +0000 | [diff] [blame] | 472 | DisableMSCWarning(4127) |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 473 | } while (0); /* break block to next option */ |
dirk | 93b02b7 | 2013-11-16 16:03:36 +0000 | [diff] [blame] | 474 | RestoreMSCWarning |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 475 | |
anthony | be39e6f | 2012-10-05 06:26:31 +0000 | [diff] [blame] | 476 | #if MagickCommandDebug >= 5 |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 477 | (void) FormatLocaleFile(stderr, "CLI-post Image Count = %ld\n", |
| 478 | (long) GetImageListLength(cli_wand->wand.images) ); |
anthony | be39e6f | 2012-10-05 06:26:31 +0000 | [diff] [blame] | 479 | #endif |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 480 | if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse ) |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 481 | return(i+count); |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 482 | } |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 483 | assert(i==end); |
anthony | 2052d27 | 2012-02-28 12:48:29 +0000 | [diff] [blame] | 484 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 485 | if ( (cli_wand->process_flags & ProcessImplictWrite) == 0 ) |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 486 | return(end); /* no implied write -- just return to caller */ |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 487 | |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 488 | assert(end==argc-1); /* end should not include last argument */ |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 489 | |
| 490 | /* |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 491 | Implicit Write of images to final CLI argument |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 492 | */ |
| 493 | option=argv[i]; |
anthony | 799889a | 2012-03-11 11:00:32 +0000 | [diff] [blame] | 494 | cli_wand->line=i; |
anthony | 686b1a3 | 2012-02-15 14:50:53 +0000 | [diff] [blame] | 495 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 496 | /* check that stacks are empty - or cause exception */ |
| 497 | if (cli_wand->image_list_stack != (Stack *)NULL) |
| 498 | CLIWandException(OptionError,"UnbalancedParenthesis", "(end of cli)"); |
| 499 | else if (cli_wand->image_info_stack != (Stack *)NULL) |
| 500 | CLIWandException(OptionError,"UnbalancedBraces", "(end of cli)"); |
| 501 | if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse ) |
| 502 | return(argc); |
| 503 | |
anthony | f125a5e | 2012-04-03 13:14:42 +0000 | [diff] [blame] | 504 | #if MagickCommandDebug >= 3 |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 505 | (void) FormatLocaleFile(stderr,"CLI arg %d Write File: \"%s\"\n",i,option); |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 506 | #endif |
| 507 | |
anthony | 964d28e | 2012-05-17 23:39:46 +0000 | [diff] [blame] | 508 | /* Valid 'do no write' replacement option (instead of "null:") */ |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 509 | if (LocaleCompare(option,"-exit") == 0 ) |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 510 | return(argc); /* just exit, no image write */ |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 511 | |
anthony | e5b3965 | 2012-04-21 05:37:29 +0000 | [diff] [blame] | 512 | /* If filename looks like an option, |
| 513 | Or the common 'end of line' error of a single space. |
| 514 | -- produce an error */ |
| 515 | if (IfMagickTrue(IsCommandOption(option)) || |
| 516 | (option[0] == ' ' && option[1] == '\0') ) { |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 517 | CLIWandException(OptionError,"MissingOutputFilename",option); |
| 518 | return(argc); |
| 519 | } |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 520 | |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 521 | cli_wand->command=(const OptionInfo *)NULL; |
| 522 | CLIOption(cli_wand,"-write",option); |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 523 | return(argc); |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 524 | } |
| 525 | |
| 526 | /* |
| 527 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 528 | % % |
| 529 | % % |
| 530 | % % |
| 531 | + M a g i c k I m a g e C o m m a n d % |
| 532 | % % |
| 533 | % % |
| 534 | % % |
| 535 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 536 | % |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 537 | % MagickImageCommand() Handle special use CLI arguments and prepare a |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 538 | % CLI MagickCLI to process the command line or directly specified script. |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 539 | % |
| 540 | % This is essentualy interface function between the MagickCore library |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 541 | % initialization function MagickCommandGenesis(), and the option MagickCLI |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 542 | % processing functions ProcessCommandOptions() or ProcessScriptOptions() |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 543 | % |
| 544 | % The format of the MagickImageCommand method is: |
| 545 | % |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 546 | % MagickBooleanType MagickImageCommand(ImageInfo *image_info,int argc, |
| 547 | % char **argv,char **metadata,ExceptionInfo *exception) |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 548 | % |
| 549 | % A description of each parameter follows: |
| 550 | % |
| 551 | % o image_info: the starting image_info structure |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 552 | % (for compatibilty with MagickCommandGenisis()) |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 553 | % |
| 554 | % o argc: the number of elements in the argument vector. |
| 555 | % |
| 556 | % o argv: A text array containing the command line arguments. |
| 557 | % |
anthony | 0ea037a | 2012-04-03 12:14:39 +0000 | [diff] [blame] | 558 | % o metadata: any metadata (for VBS) is returned here. |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 559 | % (for compatibilty with MagickCommandGenisis()) |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 560 | % |
| 561 | % o exception: return any errors or warnings in this structure. |
| 562 | % |
| 563 | */ |
| 564 | |
anthony | 40b6015 | 2012-04-04 06:13:37 +0000 | [diff] [blame] | 565 | static void MagickUsage(MagickBooleanType verbose) |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 566 | { |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 567 | const char |
| 568 | *name; |
| 569 | |
| 570 | size_t |
| 571 | len; |
| 572 | |
| 573 | name=GetClientName(); |
| 574 | len=strlen(name); |
| 575 | |
anthony | d22bf40 | 2012-04-10 01:32:03 +0000 | [diff] [blame] | 576 | if (len>=7 && LocaleCompare("convert",name+len-7) == 0) { |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 577 | /* convert usage */ |
| 578 | (void) FormatLocaleFile(stdout, |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 579 | "Usage: %s [ {option} | {image} ... ] {output_image}\n",name); |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 580 | (void) FormatLocaleFile(stdout, |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 581 | " %s -help | -version | -usage | -list {option}\n\n",name); |
anthony | d22bf40 | 2012-04-10 01:32:03 +0000 | [diff] [blame] | 582 | return; |
| 583 | } |
| 584 | else if (len>=6 && LocaleCompare("script",name+len-6) == 0) { |
| 585 | /* magick-script usage */ |
| 586 | (void) FormatLocaleFile(stdout, |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 587 | "Usage: %s {filename} [ {script_args} ... ]\n",name); |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 588 | } |
| 589 | else { |
| 590 | /* magick usage */ |
| 591 | (void) FormatLocaleFile(stdout, |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 592 | "Usage: %s [ {option} | {image} ... ] {output_image}\n",name); |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 593 | (void) FormatLocaleFile(stdout, |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 594 | " %s [ {option} | {image} ... ] -script {filename} [ {script_args} ...]\n", |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 595 | name); |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 596 | } |
anthony | d22bf40 | 2012-04-10 01:32:03 +0000 | [diff] [blame] | 597 | (void) FormatLocaleFile(stdout, |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 598 | " %s -help | -version | -usage | -list {option}\n\n",name); |
anthony | 40b6015 | 2012-04-04 06:13:37 +0000 | [diff] [blame] | 599 | |
| 600 | if (IfMagickFalse(verbose)) |
| 601 | return; |
| 602 | |
anthony | d22bf40 | 2012-04-10 01:32:03 +0000 | [diff] [blame] | 603 | (void) FormatLocaleFile(stdout,"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", |
anthony | 40b6015 | 2012-04-04 06:13:37 +0000 | [diff] [blame] | 604 | "All options are performed in a strict 'as you see them' order\n", |
| 605 | "You must read-in images before you can operate on them.\n", |
| 606 | "\n", |
| 607 | "Magick Script files can use any of the following forms...\n", |
| 608 | " #!/path/to/magick -script\n", |
| 609 | "or\n", |
| 610 | " #!/bin/sh\n", |
| 611 | " :; exec magick -script \"$0\" \"$@\"; exit 10\n", |
| 612 | " # Magick script from here...\n", |
| 613 | "or\n", |
| 614 | " #!/usr/bin/env magick-script\n", |
| 615 | "The latter two forms do not require the path to the command hard coded.\n", |
| 616 | "Note: \"magick-script\" needs to be linked to the \"magick\" command.\n", |
| 617 | "\n", |
| 618 | "For more information on usage, options, examples, and techniques\n", |
| 619 | "see the ImageMagick website at ", MagickAuthoritativeURL); |
| 620 | |
| 621 | return; |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 622 | } |
| 623 | |
| 624 | /* |
| 625 | Concatanate given file arguments to the given output argument. |
| 626 | Used for a special -concatenate option used for specific 'delegates'. |
| 627 | The option is not formally documented. |
| 628 | |
| 629 | magick -concatenate files... output |
| 630 | |
| 631 | This is much like the UNIX "cat" command, but for both UNIX and Windows, |
| 632 | however the last argument provides the output filename. |
| 633 | */ |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 634 | static MagickBooleanType ConcatenateImages(int argc,char **argv, |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 635 | ExceptionInfo *exception ) |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 636 | { |
| 637 | FILE |
| 638 | *input, |
| 639 | *output; |
| 640 | |
| 641 | int |
| 642 | c; |
| 643 | |
| 644 | register ssize_t |
| 645 | i; |
| 646 | |
anthony | 451f909 | 2012-05-11 01:56:24 +0000 | [diff] [blame] | 647 | if (IfMagickFalse( ExpandFilenames(&argc,&argv) )) |
anthony | 3b2e607 | 2012-05-03 13:00:39 +0000 | [diff] [blame] | 648 | ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed", |
| 649 | GetExceptionMessage(errno)); |
| 650 | |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 651 | output=fopen_utf8(argv[argc-1],"wb"); |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 652 | if (output == (FILE *) NULL) { |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 653 | ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[argc-1]); |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 654 | return(MagickFalse); |
| 655 | } |
| 656 | for (i=2; i < (ssize_t) (argc-1); i++) { |
anthony | 3b2e607 | 2012-05-03 13:00:39 +0000 | [diff] [blame] | 657 | #if 0 |
| 658 | fprintf(stderr, "DEBUG: Concatenate Image: \"%s\"\n", argv[i]); |
| 659 | #endif |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 660 | input=fopen_utf8(argv[i],"rb"); |
anthony | 3b2e607 | 2012-05-03 13:00:39 +0000 | [diff] [blame] | 661 | if (input == (FILE *) NULL) { |
cristy | 6a0d361 | 2012-05-02 15:39:55 +0000 | [diff] [blame] | 662 | ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[i]); |
| 663 | continue; |
| 664 | } |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 665 | for (c=fgetc(input); c != EOF; c=fgetc(input)) |
| 666 | (void) fputc((char) c,output); |
| 667 | (void) fclose(input); |
| 668 | (void) remove_utf8(argv[i]); |
| 669 | } |
| 670 | (void) fclose(output); |
| 671 | return(MagickTrue); |
| 672 | } |
| 673 | |
| 674 | WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info, |
| 675 | int argc,char **argv,char **metadata,ExceptionInfo *exception) |
| 676 | { |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 677 | MagickCLI |
| 678 | *cli_wand; |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 679 | |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 680 | size_t |
| 681 | len; |
| 682 | |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 683 | assert(image_info != (ImageInfo *)NULL); |
| 684 | |
anthony | 4cb3726 | 2012-03-18 11:18:45 +0000 | [diff] [blame] | 685 | /* For specific OS command line requirements */ |
| 686 | ReadCommandlLine(argc,&argv); |
| 687 | |
anthony | 668f43a | 2012-02-20 14:55:32 +0000 | [diff] [blame] | 688 | /* Initialize special "CLI Wand" to hold images and settings (empty) */ |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 689 | cli_wand=AcquireMagickCLI(image_info,exception); |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 690 | cli_wand->location="Initializing"; |
| 691 | cli_wand->filename=argv[0]; |
anthony | 8226e72 | 2012-04-05 14:25:46 +0000 | [diff] [blame] | 692 | cli_wand->line=1; |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 693 | |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 694 | if (IfMagickTrue(cli_wand->wand.debug)) |
| 695 | (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), |
| 696 | "\"%s\"",argv[0]); |
| 697 | |
| 698 | |
anthony | eff71f5 | 2012-03-29 12:59:09 +0000 | [diff] [blame] | 699 | GetPathComponent(argv[0],TailPath,cli_wand->wand.name); |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 700 | SetClientName(cli_wand->wand.name); |
anthony | eff71f5 | 2012-03-29 12:59:09 +0000 | [diff] [blame] | 701 | ConcatenateMagickString(cli_wand->wand.name,"-CLI",MaxTextExtent); |
| 702 | |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 703 | len=strlen(argv[0]); /* precaution */ |
| 704 | |
anthony | eff71f5 | 2012-03-29 12:59:09 +0000 | [diff] [blame] | 705 | /* "convert" command - give a "depreciation" warning" */ |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 706 | if (len>=7 && LocaleCompare("convert",argv[0]+len-7) == 0) { |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 707 | cli_wand->process_flags = ConvertCommandOptionFlags; |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 708 | (void) FormatLocaleFile(stderr,"WARNING: %s\n", |
| 709 | "The convert is depreciated in IMv7, use \"magick\"\n"); |
anthony | eff71f5 | 2012-03-29 12:59:09 +0000 | [diff] [blame] | 710 | } |
anthony | eff71f5 | 2012-03-29 12:59:09 +0000 | [diff] [blame] | 711 | |
anthony | 8226e72 | 2012-04-05 14:25:46 +0000 | [diff] [blame] | 712 | /* Special Case: If command name ends with "script" implied "-script" */ |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 713 | if (len>=6 && LocaleCompare("script",argv[0]+len-6) == 0) { |
anthony | d22bf40 | 2012-04-10 01:32:03 +0000 | [diff] [blame] | 714 | if (argc >= 2 && ( (*(argv[1]) != '-') || (strlen(argv[1]) == 1) )) { |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 715 | GetPathComponent(argv[1],TailPath,cli_wand->wand.name); |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 716 | ProcessScriptOptions(cli_wand,argv[1],argc,argv,2); |
anthony | e5fcd36 | 2012-04-09 04:02:09 +0000 | [diff] [blame] | 717 | goto Magick_Command_Cleanup; |
| 718 | } |
anthony | 52bef75 | 2012-03-27 13:54:47 +0000 | [diff] [blame] | 719 | } |
| 720 | |
| 721 | /* Special Case: Version Information and Abort */ |
| 722 | if (argc == 2) { |
cristy | e4ef295 | 2013-08-16 14:24:00 +0000 | [diff] [blame] | 723 | if ((LocaleCompare("-version",argv[1]) == 0) || /* GNU standard option */ |
| 724 | (LocaleCompare("--version",argv[1]) == 0) ) { /* just version */ |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 725 | CLIOption(cli_wand, "-version"); |
anthony | 52bef75 | 2012-03-27 13:54:47 +0000 | [diff] [blame] | 726 | goto Magick_Command_Exit; |
| 727 | } |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 728 | if ((LocaleCompare("-help",argv[1]) == 0) || /* GNU standard option */ |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 729 | (LocaleCompare("--help",argv[1]) == 0) ) { /* just a brief summary */ |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 730 | if (IfMagickTrue(cli_wand->wand.debug)) |
| 731 | (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), |
| 732 | "- Special Option \"%s\"", argv[1]); |
anthony | 40b6015 | 2012-04-04 06:13:37 +0000 | [diff] [blame] | 733 | MagickUsage(MagickFalse); |
| 734 | goto Magick_Command_Exit; |
| 735 | } |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 736 | if (LocaleCompare("-usage",argv[1]) == 0) { /* both version & usage */ |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 737 | if (IfMagickTrue(cli_wand->wand.debug)) |
| 738 | (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), |
| 739 | "- Special Option \"%s\"", argv[1]); |
anthony | ca48768 | 2012-04-27 07:59:27 +0000 | [diff] [blame] | 740 | CLIOption(cli_wand, "-version" ); |
anthony | 40b6015 | 2012-04-04 06:13:37 +0000 | [diff] [blame] | 741 | MagickUsage(MagickTrue); |
| 742 | goto Magick_Command_Exit; |
| 743 | } |
anthony | 52bef75 | 2012-03-27 13:54:47 +0000 | [diff] [blame] | 744 | } |
| 745 | |
| 746 | /* not enough arguments -- including -help */ |
| 747 | if (argc < 3) { |
anthony | 40b6015 | 2012-04-04 06:13:37 +0000 | [diff] [blame] | 748 | (void) FormatLocaleFile(stderr, |
| 749 | "Error: Invalid argument or not enough arguments\n\n"); |
| 750 | MagickUsage(MagickFalse); |
anthony | 52bef75 | 2012-03-27 13:54:47 +0000 | [diff] [blame] | 751 | goto Magick_Command_Exit; |
| 752 | } |
| 753 | |
anthony | 0ea037a | 2012-04-03 12:14:39 +0000 | [diff] [blame] | 754 | /* Special "concatenate option (hidden) for delegate usage */ |
| 755 | if (LocaleCompare("-concatenate",argv[1]) == 0) { |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 756 | if (IfMagickTrue(cli_wand->wand.debug)) |
| 757 | (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), |
| 758 | "- Special Option \"%s\"", argv[1]); |
anthony | 0ea037a | 2012-04-03 12:14:39 +0000 | [diff] [blame] | 759 | ConcatenateImages(argc,argv,exception); |
| 760 | goto Magick_Command_Exit; |
| 761 | } |
| 762 | |
anthony | 0676223 | 2012-04-29 11:45:40 +0000 | [diff] [blame] | 763 | /* List Information and Abort */ |
| 764 | if (argc == 3 && LocaleCompare("-list",argv[1]) == 0) { |
| 765 | CLIOption(cli_wand, argv[1], argv[2]); |
| 766 | goto Magick_Command_Exit; |
| 767 | } |
| 768 | |
anthony | 52bef75 | 2012-03-27 13:54:47 +0000 | [diff] [blame] | 769 | /* ------------- */ |
| 770 | /* The Main Call */ |
| 771 | |
| 772 | if (LocaleCompare("-script",argv[1]) == 0) { |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 773 | /* Start processing directly from script, no pre-script options |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 774 | Replace wand command name with script name |
| 775 | First argument in the argv array is the script name to read. |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 776 | */ |
| 777 | GetPathComponent(argv[2],TailPath,cli_wand->wand.name); |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 778 | ProcessScriptOptions(cli_wand,argv[2],argc,argv,3); |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 779 | } |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 780 | else { |
anthony | 52bef75 | 2012-03-27 13:54:47 +0000 | [diff] [blame] | 781 | /* Normal Command Line, assumes output file as last option */ |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 782 | ProcessCommandOptions(cli_wand,argc,argv,1); |
anthony | 0b46ebe | 2012-03-06 04:15:35 +0000 | [diff] [blame] | 783 | } |
anthony | 52bef75 | 2012-03-27 13:54:47 +0000 | [diff] [blame] | 784 | /* ------------- */ |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 785 | |
anthony | 4cb3726 | 2012-03-18 11:18:45 +0000 | [diff] [blame] | 786 | Magick_Command_Cleanup: |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 787 | cli_wand->location="Cleanup"; |
| 788 | cli_wand->filename=argv[0]; |
| 789 | if (IfMagickTrue(cli_wand->wand.debug)) |
| 790 | (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), |
| 791 | "\"%s\"",argv[0]); |
| 792 | |
anthony | 5216f82 | 2012-04-10 13:02:37 +0000 | [diff] [blame] | 793 | /* recover original image_info and clean up stacks |
| 794 | FUTURE: "-reset stacks" option */ |
anthony | 8226e72 | 2012-04-05 14:25:46 +0000 | [diff] [blame] | 795 | while (cli_wand->image_list_stack != (Stack *)NULL) |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 796 | CLIOption(cli_wand,")"); |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 797 | while (cli_wand->image_info_stack != (Stack *)NULL) |
anthony | 464f1c4 | 2012-04-22 08:51:01 +0000 | [diff] [blame] | 798 | CLIOption(cli_wand,"}"); |
anthony | 2052d27 | 2012-02-28 12:48:29 +0000 | [diff] [blame] | 799 | |
anthony | 1cdc5b7 | 2012-03-03 02:31:18 +0000 | [diff] [blame] | 800 | /* assert we have recovered the original structures */ |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 801 | assert(cli_wand->wand.image_info == image_info); |
| 802 | assert(cli_wand->wand.exception == exception); |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 803 | |
| 804 | /* Handle metadata for ImageMagickObject COM object for Windows VBS */ |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 805 | if (metadata != (char **) NULL) { |
| 806 | const char |
| 807 | *format; |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 808 | |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 809 | char |
| 810 | *text; |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 811 | |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 812 | format="%w,%h,%m"; // Get this from image_info Option splaytree |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 813 | |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 814 | text=InterpretImageProperties(image_info,cli_wand->wand.images,format, |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 815 | exception); |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 816 | if (text == (char *) NULL) |
| 817 | ThrowMagickException(exception,GetMagickModule(),ResourceLimitError, |
cristy | 3ec9e8d | 2013-01-30 16:29:51 +0000 | [diff] [blame] | 818 | "MemoryAllocationFailed","`%s'", GetExceptionMessage(errno)); |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 819 | else { |
| 820 | (void) ConcatenateString(&(*metadata),text); |
| 821 | text=DestroyString(text); |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 822 | } |
anthony | afa3dfc | 2012-03-03 11:31:30 +0000 | [diff] [blame] | 823 | } |
anthony | 4cb3726 | 2012-03-18 11:18:45 +0000 | [diff] [blame] | 824 | |
anthony | 52bef75 | 2012-03-27 13:54:47 +0000 | [diff] [blame] | 825 | Magick_Command_Exit: |
anthony | a322a83 | 2013-04-27 06:28:03 +0000 | [diff] [blame] | 826 | cli_wand->location="Exiting"; |
| 827 | cli_wand->filename=argv[0]; |
| 828 | if (IfMagickTrue(cli_wand->wand.debug)) |
| 829 | (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), |
| 830 | "\"%s\"",argv[0]); |
| 831 | |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 832 | /* Destroy the special CLI Wand */ |
anthony | 43f425d | 2012-02-26 12:58:58 +0000 | [diff] [blame] | 833 | cli_wand->wand.image_info = (ImageInfo *)NULL; /* not these */ |
| 834 | cli_wand->wand.exception = (ExceptionInfo *)NULL; |
| 835 | cli_wand=DestroyMagickCLI(cli_wand); |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 836 | |
anthony | c2b913e | 2012-03-31 00:22:33 +0000 | [diff] [blame] | 837 | return(IsMagickTrue(exception->severity > ErrorException)); |
anthony | fa1e43d | 2012-02-12 12:55:45 +0000 | [diff] [blame] | 838 | } |