% January 2012 %
% %
% %
-% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2013 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 %
#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"
+#include "MagickCore/exception-private.h"
#include "MagickCore/version.h"
\f
/* verbose debugging,
- 3 - option type details
- 9 - output options/artifacts/propertys
+ 0 - no debug lines
+ 3 - show option details (better to use -debug Command now)
+ 5 - image counts (after option runs)
*/
#define MagickCommandDebug 0
-#define ThrowFileException(exception,severity,tag,context) \
-{ \
- char \
- *message; \
- \
- message=GetExceptionMessage(errno); \
- (void) ThrowMagickException(exception,GetMagickModule(),severity, \
- tag == (const char *) NULL ? "unknown" : tag,"'%s': %s",context,message); \
- message=DestroyString(message); \
-}
-
-#if MagickCommandDebug >= 9
-/*
- Temporary Debugging Information
- FUTURE: these should be able to be printed out using 'percent escapes'
- Actually 'Properities' can already be output with "%[*]"
-*/
-static void OutputOptions(ImageInfo *image_info)
-{
- const char
- *option,
- *value;
-
- (void) FormatLocaleFile(stdout," Global Options:\n");
- ResetImageOptionIterator(image_info);
- while ((option=GetNextImageOption(image_info)) != (const char *) NULL ) {
- (void) FormatLocaleFile(stdout," %s: ",option);
- value=GetImageOption(image_info,option);
- if (value != (const char *) NULL)
- (void) FormatLocaleFile(stdout,"%s\n",value);
- }
- ResetImageOptionIterator(image_info);
-}
-
-static void OutputArtifacts(Image *image)
-{
- const char
- *artifact,
- *value;
-
- (void) FormatLocaleFile(stdout," Image Artifacts:\n");
- ResetImageArtifactIterator(image);
- while ((artifact=GetNextImageArtifact(image)) != (const char *) NULL ) {
- (void) FormatLocaleFile(stdout," %s: ",artifact);
- value=GetImageArtifact(image,artifact);
- if (value != (const char *) NULL)
- (void) FormatLocaleFile(stdout,"%s\n",value);
- }
- ResetImageArtifactIterator(image);
-}
-
-static void OutputProperties(Image *image,ExceptionInfo *exception)
-{
- const char
- *property,
- *value;
-
- (void) FormatLocaleFile(stdout," Image Properity:\n");
- ResetImagePropertyIterator(image);
- while ((property=GetNextImageProperty(image)) != (const char *) NULL ) {
- (void) FormatLocaleFile(stdout," %s: ",property);
- value=GetImageProperty(image,property,exception);
- if (value != (const char *) NULL)
- (void) FormatLocaleFile(stdout,"%s\n",value);
- }
- ResetImagePropertyIterator(image);
-}
-#endif
-
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The format of the ProcessScriptOptions method is:
%
-% void ProcessScriptOptions(MagickCLI *cli_wand,int argc,char **argv,
-% int index)
+% void ProcessScriptOptions(MagickCLI *cli_wand,const char *filename,
+% int argc,char **argv,int index)
%
% A description of each parameter follows:
%
% o cli_wand: the main CLI Wand to use.
%
-% o argc: the number of elements in the argument vector.
+% o filename: the filename of script to process
%
-% o argv: A text array containing the command line arguments.
+% o argc: the number of elements in the argument vector. (optional)
+%
+% o argv: A text array containing the command line arguments. (optional)
%
-% o index: offset for argc to CLI argumnet count
+% o index: offset of next argment in argv (script arguments) (optional)
%
*/
-WandExport void ProcessScriptOptions(MagickCLI *cli_wand,int argc,char **argv,
- int index)
+WandExport void ProcessScriptOptions(MagickCLI *cli_wand,const char *filename,
+ int argc,char **argv,int index)
{
ScriptTokenInfo
*token_info;
*arg1,
*arg2;
- assert(argc>index); /* at least one argument - script name */
- assert(argv != (char **)NULL);
- assert(argv[index] != (char *)NULL);
- assert(argv[argc-1] != (char *)NULL);
+ assert(filename != (char *)NULL ); /* at least one argument - script name */
assert(cli_wand != (MagickCLI *) NULL);
assert(cli_wand->signature == WandSignature);
- if (cli_wand->wand.debug != MagickFalse)
- (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) LogMagickEvent(CommandEvent,GetMagickModule(),
+ "Processing script \"%s\"", filename);
/* open file script or stream, and set up tokenizer */
- token_info = AcquireScriptTokenInfo(argv[index]);
+ token_info = AcquireScriptTokenInfo(filename);
if (token_info == (ScriptTokenInfo *) NULL) {
- ThrowFileException(cli_wand->wand.exception,OptionFatalError,
- "UnableToOpenScript",argv[index]);
+ CLIWandExceptionFile(OptionFatalError,"UnableToOpenScript",filename);
return;
}
/* define the error location string for use in exceptions
- order of input escapes: option, (arg), filename, line, column */
- cli_wand->location="'%s' in \"%s\" line %u column %u";
- cli_wand->location2="'%s' '%s' in \"%s\" line %u column %u";
- if ( LocaleCompare("-", argv[index]) == 0 )
+ order of localtion format escapes: filename, line, column */
+ cli_wand->location="in \"%s\" at line %u,column %u";
+ if ( LocaleCompare("-", filename) == 0 )
cli_wand->filename="stdin";
else
- cli_wand->filename=argv[index];
+ cli_wand->filename=filename;
/* Process Options from Script */
option = arg1 = arg2 = (char*)NULL;
while (1) {
- /* Get a option */
{ MagickBooleanType status = GetScriptToken(token_info);
cli_wand->line=token_info->token_line;
cli_wand->column=token_info->token_column;
break; /* error or end of options */
}
- /* save option details */
- CloneString(&option,token_info->token);
+ do { /* use break to loop to exception handler and loop */
+
+ /* save option details */
+ CloneString(&option,token_info->token);
- { /* get option type and argument count */
- const OptionInfo *option_info = GetCommandOptionInfo(option);
- count=option_info->type;
- option_type=(CommandOptionFlags) option_info->flags;
+ /* get option, its argument count, and option type */
+ cli_wand->command = GetCommandOptionInfo(option);
+ count=cli_wand->command->type;
+ option_type=(CommandOptionFlags) cli_wand->command->flags;
#if 0
(void) FormatLocaleFile(stderr, "Script: %u,%u: \"%s\" matched \"%s\"\n",
- cli_wand->line, cli_wand->line, option, option_info->mnemonic );
+ cli_wand->line, cli_wand->line, option, cli_wand->command->mnemonic );
#endif
- }
- /* handle a undefined option - image read? */
- if ( option_type == UndefinedOptionFlag ||
- (option_type & NonMagickOptionFlag) != 0 ) {
+ /* handle a undefined option - image read - always for "magick-script" */
+ if ( option_type == UndefinedOptionFlag ||
+ (option_type & NonMagickOptionFlag) != 0 ) {
#if MagickCommandDebug >= 3
- (void) FormatLocaleFile(stderr, "Script %u,%u Non-Option: \"%s\"\n",
- cli_wand->line, cli_wand->line, option);
+ (void) FormatLocaleFile(stderr, "Script %u,%u Non-Option: \"%s\"\n",
+ cli_wand->line, cli_wand->line, option);
#endif
- if ( IfMagickFalse(IsCommandOption(option)))
- /* non-option -- treat as a image read */
- CLISpecialOperator(cli_wand,"-read",option);
- else
- CLIWandExceptionBreak(OptionFatalError,"UnrecognizedOption",option);
- count = 0;
- goto next_token;
- }
+ if ( IfMagickFalse(IsCommandOption(option))) {
+ /* non-option -- treat as a image read */
+ cli_wand->command=(const OptionInfo *)NULL;
+ CLIOption(cli_wand,"-read",option);
+ break; /* next option */
+ }
+ CLIWandException(OptionFatalError,"UnrecognizedOption",option);
+ break; /* next option */
+ }
- if ( count >= 1 ) {
- if( IfMagickFalse(GetScriptToken(token_info)) )
- CLIWandException(OptionFatalError,"MissingArgument",option);
- CloneString(&arg1,token_info->token);
- }
- else
- CloneString(&arg1,(char *)NULL);
+ if ( count >= 1 ) {
+ if( IfMagickFalse(GetScriptToken(token_info)) )
+ CLIWandException(OptionFatalError,"MissingArgument",option);
+ CloneString(&arg1,token_info->token);
+ }
+ else
+ CloneString(&arg1,(char *)NULL);
- if ( count >= 2 ) {
- if( IfMagickFalse(GetScriptToken(token_info)) )
- CLIWandExceptionBreak(OptionFatalError,"MissingArgument",option);
- CloneString(&arg2,token_info->token);
- }
- else
- CloneString(&arg2,(char *)NULL);
+ if ( count >= 2 ) {
+ if( IfMagickFalse(GetScriptToken(token_info)) )
+ CLIWandExceptionBreak(OptionFatalError,"MissingArgument",option);
+ CloneString(&arg2,token_info->token);
+ }
+ else
+ CloneString(&arg2,(char *)NULL);
+ /*
+ Process Options
+ */
#if MagickCommandDebug >= 3
- (void) FormatLocaleFile(stderr,
- "Script %u,%u Option: \"%s\" Count: %d Flags: %04x Args: \"%s\" \"%s\"\n",
- cli_wand->line,cli_wand->line,option,count,option_type,arg1,arg2);
+ (void) FormatLocaleFile(stderr,
+ "Script %u,%u Option: \"%s\" Count: %d Flags: %04x Args: \"%s\" \"%s\"\n",
+ cli_wand->line,cli_wand->line,option,count,option_type,arg1,arg2);
#endif
+ /* Hard Depreciated Options, no code to execute - error */
+ if ( (option_type & DeprecateOptionFlag) != 0 ) {
+ CLIWandException(OptionError,"DeprecatedOptionNoCode",option);
+ break; /* next option */
+ }
- if ( (option_type & GenesisOptionFlag) != 0 ) {
- /* Genesis Options have no place in a magick script */
- CLIWandExceptionBreak(OptionError,"InvalidUseOfOption",option);
- goto next_token;
- }
- if ( (option_type & DeprecateOptionFlag) != 0 ) {
- CLIWandException(OptionWarning,"DeprecatedOption",option);
- if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
- break;
- /* fall through - do the depreciated option */
- }
- if (((option_type & ImageRequiredFlags) != 0 ) &&
- ( cli_wand->wand.images != (Image *)NULL ) ) {
- CLIWandException(OptionError,"NoImagesFound",option);
- goto next_token;
- }
-
- /* handle special script-argument options here */
- //either continue processing command line
- // or making use of the command line options.
- //CLICommandOptions(cli_wand,count+1,argv, MagickScriptArgsFlags);
-
- /*
- Process Option from file
- */
- if ( (option_type & SpecialOptionFlag) != 0 ) {
- if ( LocaleCompare(option,"-exit") == 0 ) {
- break; /* forced end of script */
+ /* MagickCommandGenesis() options have no place in a magick script */
+ if ( (option_type & GenesisOptionFlag) != 0 ) {
+ CLIWandException(OptionError,"InvalidUseOfOption",option);
+ break; /* next option */
}
- if ( LocaleCompare(option,"-script") == 0 ) {
- CLIWandExceptionBreak(OptionError,"InvalidUseOfOption",option);
- goto next_token;
+
+ /* handle any special 'script' options */
+ if ( (option_type & SpecialOptionFlag) != 0 ) {
+ if ( LocaleCompare(option,"-exit") == 0 ) {
+ goto loop_exit; /* break out of loop - return from script */
+ }
+ if ( LocaleCompare(option,"-script") == 0 ) {
+ /* FUTURE: call new script from this script - error for now */
+ CLIWandException(OptionError,"InvalidUseOfOption",option);
+ break; /* next option */
+ }
+ /* FUTURE: handle special script-argument options here */
+ /* handle any other special operators now */
+ CLIWandException(OptionError,"InvalidUseOfOption",option);
+ break; /* next option */
}
- /* 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)
- }
- if ( cli_wand->wand.images != (Image *)NULL )
- SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
- cli_wand->wand.exception);
-
- if ( (option_type & SimpleOperatorOptionFlag) != 0)
- CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
-
- if ( (option_type & ListOperatorOptionFlag) != 0 )
- CLIListOperatorImages(cli_wand, option, arg1, arg2);
-
-next_token:
-#if MagickCommandDebug >= 9
- OutputOptions(cli_wand->wand.image_info);
- if ( cli_wand->wand.images != (Image *)NULL ) {
- OutputArtifacts(cli_wand->wand.images);
- OutputProperties(cli_wand->wand.images,cli_wand->wand.exception);
- }
+ /* Process non-specific Option */
+ CLIOption(cli_wand, option, arg1, arg2);
+
+ } while (0); /* break block to next option */
+
+#if MagickCommandDebug >= 5
+ fprintf(stderr, "Script Image Count = %ld\n",
+ GetImageListLength(cli_wand->wand.images) );
#endif
- if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
- break;
+ if ( IfMagickTrue(CLICatchException(cli_wand, MagickFalse)) )
+ break; /* exit loop */
}
+ /*
+ Loop exit - check for some tokenization error
+ */
+loop_exit:
#if MagickCommandDebug >= 3
(void) FormatLocaleFile(stderr, "Script End: %d\n", token_info->status);
#endif
CLIWandException(OptionFatalError,"ScriptIsBinary","");
break;
}
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) LogMagickEvent(CommandEvent,GetMagickModule(),
+ "Script End \"%s\"", filename);
/* Clean up */
token_info = DestroyScriptTokenInfo(token_info);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ProcessCommandOptions() reads and processes arguments in the given
-% command line argument array. The array does not contain the command
-% being processed, only the options.
+% command line argument array. The 'index' defines where in the array we
+% should begin processing
%
% The 'process_flags' can be used to control and limit option processing.
% For example, to only process one option, or how unknown and special options
%
% The format of the ProcessCommandOptions method is:
%
-% int ProcessCommandOptions(MagickCLI *cli_wand,int argc,char **argv,
-% int index, ProcessOptionFlags process_flags )
+% int ProcessCommandOptions(MagickCLI *cli_wand,
+% int argc,char **argv,int index)
%
% A description of each parameter follows:
%
%
*/
WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
- char **argv, int index, ProcessOptionFlags process_flags )
+ char **argv, int index )
{
const char
*option,
assert(argv[argc-1] != (char *)NULL);
assert(cli_wand != (MagickCLI *) NULL);
assert(cli_wand->signature == WandSignature);
- if (cli_wand->wand.debug != MagickFalse)
- (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
/* define the error location string for use in exceptions
- order of input escapes: option, (arg), filename, line, column */
- cli_wand->location="'%s' %s arg %u";
- cli_wand->location2="'%s' '%s' %s arg %u";
+ order of localtion format escapes: filename, line, column */
+ cli_wand->location="at %s arg %u";
cli_wand->filename="CLI";
+ cli_wand->line=index; /* note first argument we will process */
+
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "- Starting (\"%s\")", argv[index]);
end = argc;
- if ( ( process_flags & ProcessOutputFile ) != 0 )
- end--;
+ if ( (cli_wand->process_flags & ProcessImplictWrite) != 0 )
+ end--; /* the last arument is an implied write, do not process directly */
for (i=index; i < end; i += count +1) {
/* Finished processing one option? */
- if ( ( process_flags & ProcessOneOptionOnly ) != 0 && i != index )
+ if ( (cli_wand->process_flags & ProcessOneOptionOnly) != 0 && i != index )
return(i);
- option=argv[i];
- cli_wand->line=i;
+ do { /* use break to loop to exception handler and loop */
+
+ option=argv[i];
+ cli_wand->line=i; /* note the argument for this option */
- { const OptionInfo *option_info = GetCommandOptionInfo(argv[i]);
- count=option_info->type;
- option_type=(CommandOptionFlags) option_info->flags;
+ /* get option, its argument count, and option type */
+ cli_wand->command = GetCommandOptionInfo(argv[i]);
+ count=cli_wand->command->type;
+ option_type=(CommandOptionFlags) cli_wand->command->flags;
#if 0
(void) FormatLocaleFile(stderr, "CLI %d: \"%s\" matched \"%s\"\n",
- i, argv[i], option_info->mnemonic );
+ i, argv[i], cli_wand->command->mnemonic );
#endif
- }
- if ( option_type == UndefinedOptionFlag ||
- (option_type & NonMagickOptionFlag) != 0 ) {
+ if ( option_type == UndefinedOptionFlag ||
+ (option_type & NonMagickOptionFlag) != 0 ) {
#if MagickCommandDebug >= 3
- (void) FormatLocaleFile(stderr, "CLI %d Non-Option: \"%s\"\n", i, option);
+ (void) FormatLocaleFile(stderr, "CLI arg %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 )
+ if ( IfMagickFalse(IsCommandOption(option)) ) {
+ if ( (cli_wand->process_flags & ProcessImplictRead) != 0 ) {
+ /* non-option -- treat as a image read */
+ cli_wand->command=(const OptionInfo *)NULL;
+ CLIOption(cli_wand,"-read",option);
+ break; /* next option */
+ }
+ }
CLIWandException(OptionFatalError,"UnrecognizedOption",option);
- count = 0;
- goto next_argument;
- }
+ break; /* next option */
+ }
- if ((i+count) >= end ) {
- CLIWandException(OptionFatalError,"MissingArgument",option);
- if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
- return(end);
- goto next_argument; /* no more arguments unable to proceed */
- }
+ if ( ((option_type & SpecialOptionFlag) != 0 ) &&
+ ((cli_wand->process_flags & ProcessScriptOption) != 0) &&
+ (LocaleCompare(option,"-script") == 0) ) {
+ /* Call Script from CLI, with a filename as a zeroth argument.
+ NOTE: -script may need to use the 'implict write filename' argument
+ so it must be handled specially to prevent a 'missing argument' error.
+ */
+ if ( (i+count) >= argc )
+ CLIWandException(OptionFatalError,"MissingArgument",option);
+ ProcessScriptOptions(cli_wand,argv[i+1],argc,argv,i+count);
+ return(argc); /* Script does not return to CLI -- Yet */
+ /* FUTURE: when it does, their may be no write arg! */
+ }
- arg1 = ( count >= 1 ) ? argv[i+1] : (char *)NULL;
- arg2 = ( count >= 2 ) ? argv[i+2] : (char *)NULL;
+ if ((i+count) >= end ) {
+ CLIWandException(OptionFatalError,"MissingArgument",option);
+ if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
+ return(end);
+ break; /* next option - not that their is any! */
+ }
+
+ arg1 = ( count >= 1 ) ? argv[i+1] : (char *)NULL;
+ arg2 = ( count >= 2 ) ? argv[i+2] : (char *)NULL;
+ /*
+ Process Known Options
+ */
#if MagickCommandDebug >= 3
- (void) FormatLocaleFile(stderr,
- "CLI %u Option: \"%s\" Count: %d Flags: %04x Args: \"%s\" \"%s\"\n",
- i,option,count,option_type,arg1,arg2);
+ (void) FormatLocaleFile(stderr,
+ "CLI arg %u Option: \"%s\" Count: %d Flags: %04x Args: \"%s\" \"%s\"\n",
+ i,option,count,option_type,arg1,arg2);
#endif
+ /* ignore 'genesis options' in command line args */
+ if ( (option_type & GenesisOptionFlag) != 0 )
+ break; /* next option */
+
+ /* Handle any special options for CLI (-script handled above) */
+ if ( (option_type & SpecialOptionFlag) != 0 ) {
+ if ( (cli_wand->process_flags & ProcessExitOption) != 0
+ && LocaleCompare(option,"-exit") == 0 )
+ return(i+count);
+ break; /* next option */
+ }
- if ( (option_type & DeprecateOptionFlag) != 0 ) {
- CLIWandException(OptionWarning,"DeprecatedOption",option);
- if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
- return(end);
- /* fall through - do the depreciated option */
- }
- if ( (option_type & GenesisOptionFlag) != 0 ) {
- goto next_argument; /* ignore genesis options */
- }
- if (((option_type & ImageRequiredFlags) != 0 ) &&
- ( cli_wand->wand.images == (Image *)NULL ) ) {
- CLIWandException(OptionError,"NoImagesFound",option);
- goto next_argument;
- }
+ /* Process standard image option */
+ CLIOption(cli_wand, option, arg1, arg2);
- if ( (option_type & SpecialOptionFlag) != 0 ) {
- 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);
- }
+ } while (0); /* break block to next option */
- if ( (option_type & SettingOptionFlags) != 0 ) {
- CLISettingOptionInfo(cli_wand, option, arg1);
- // FUTURE: Sync Specific Settings into Image Properities (not global)
- }
- if ( cli_wand->wand.images != (Image *)NULL )
- SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
- cli_wand->wand.exception);
-
- if ( (option_type & SimpleOperatorOptionFlag) != 0)
- CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
-
- if ( (option_type & ListOperatorOptionFlag) != 0 )
- CLIListOperatorImages(cli_wand, option, arg1, arg2);
-
-next_argument:
-#if MagickCommandDebug >= 9
- OutputOptions(cli_wand->wand.image_info);
- if ( cli_wand->wand.images != (Image *)NULL ) {
- OutputArtifacts(cli_wand->wand.images);
- OutputProperties(cli_wand->wand.images,cli_wand->wand.exception);
- }
+#if MagickCommandDebug >= 5
+ (void) FormatLocaleFile(stderr, "CLI-post Image Count = %ld\n",
+ (long) GetImageListLength(cli_wand->wand.images) );
#endif
if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
return(i+count);
}
assert(i==end);
- if ( ( process_flags & ProcessOutputFile ) == 0 )
- return(end);
+ if ( (cli_wand->process_flags & ProcessImplictWrite) == 0 )
+ return(end); /* no implied write -- just return to caller */
- assert(end==argc-1);
+ assert(end==argc-1); /* end should not include last argument */
/*
Implicit Write of images to final CLI argument
option=argv[i];
cli_wand->line=i;
-#if MagickCommandDebug >= 3
- (void) FormatLocaleFile(stderr, "CLI %d Write File: \"%s\"\n", i, option );
-#endif
-
- /* check that stacks are empty */
+ /* check that stacks are empty - or cause exception */
if (cli_wand->image_list_stack != (Stack *)NULL)
- CLIWandException(OptionError,"UnbalancedParenthesis", "(eof)");
+ CLIWandException(OptionError,"UnbalancedParenthesis", "(end of cli)");
else if (cli_wand->image_info_stack != (Stack *)NULL)
- CLIWandException(OptionError,"UnbalancedBraces", "(eof)");
+ CLIWandException(OptionError,"UnbalancedBraces", "(end of cli)");
if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
return(argc);
- /* This is a valid 'do no write' option - no images needed */
+#if MagickCommandDebug >= 3
+ (void) FormatLocaleFile(stderr,"CLI arg %d Write File: \"%s\"\n",i,option);
+#endif
+
+ /* Valid 'do no write' replacement option (instead of "null:") */
if (LocaleCompare(option,"-exit") == 0 )
return(argc); /* just exit, no image write */
- /* If filename looks like an option -- produce an error */
- if (IsCommandOption(option) != MagickFalse) {
+ /* If filename looks like an option,
+ Or the common 'end of line' error of a single space.
+ -- produce an error */
+ if (IfMagickTrue(IsCommandOption(option)) ||
+ (option[0] == ' ' && option[1] == '\0') ) {
CLIWandException(OptionError,"MissingOutputFilename",option);
return(argc);
}
- (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
- cli_wand->wand.exception);
- CLISpecialOperator(cli_wand,"-write",option);
+ cli_wand->command=(const OptionInfo *)NULL;
+ CLIOption(cli_wand,"-write",option);
return(argc);
}
\f
%
% The format of the MagickImageCommand method is:
%
-% MagickBooleanType MagickImageCommand(ImageInfo *image_info,
-% int argc, char **argv, char **metadata, ExceptionInfo *exception)
+% MagickBooleanType MagickImageCommand(ImageInfo *image_info,int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o image_info: the starting image_info structure
-% (for compatibilty with MagickCommandGenisis())
+% (for compatibilty with MagickCommandGenisis())
%
% o argc: the number of elements in the argument vector.
%
% o argv: A text array containing the command line arguments.
%
% o metadata: any metadata (for VBS) is returned here.
-% (for compatibilty with MagickCommandGenisis())
+% (for compatibilty with MagickCommandGenisis())
%
% o exception: return any errors or warnings in this structure.
%
static void MagickUsage(MagickBooleanType verbose)
{
+ const char
+ *name;
+
+ size_t
+ len;
+
+ name=GetClientName();
+ len=strlen(name);
+
+ if (len>=7 && LocaleCompare("convert",name+len-7) == 0) {
+ /* convert usage */
+ (void) FormatLocaleFile(stdout,
+ "Usage: %s [ {option} | {image} ... ] {output_image}\n",name);
+ (void) FormatLocaleFile(stdout,
+ " %s -help | -version | -usage | -list {option}\n\n",name);
+ return;
+ }
+ else if (len>=6 && LocaleCompare("script",name+len-6) == 0) {
+ /* magick-script usage */
+ (void) FormatLocaleFile(stdout,
+ "Usage: %s {filename} [ {script_args} ... ]\n",name);
+ }
+ else {
+ /* magick usage */
+ (void) FormatLocaleFile(stdout,
+ "Usage: %s [ {option} | {image} ... ] {output_image}\n",name);
+ (void) FormatLocaleFile(stdout,
+ " %s [ {option} | {image} ... ] -script {filename} [ {script_args} ...]\n",
+ name);
+ }
(void) FormatLocaleFile(stdout,
- "Usage: %s [{option}|{image}...] {output_image}\n",GetClientName());
- (void) FormatLocaleFile(stdout,
- " %s [{option}|{image}...] -script {filename} [{script_args}...]\n",
- GetClientName());
- (void) FormatLocaleFile(stdout,
- " %s -help|-version|-usage|-list {option}\n",
- GetClientName());
+ " %s -help | -version | -usage | -list {option}\n\n",name);
if (IfMagickFalse(verbose))
return;
- (void) FormatLocaleFile(stdout,"\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ (void) FormatLocaleFile(stdout,"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
"All options are performed in a strict 'as you see them' order\n",
"You must read-in images before you can operate on them.\n",
"\n",
however the last argument provides the output filename.
*/
static MagickBooleanType ConcatenateImages(int argc,char **argv,
- ExceptionInfo *exception)
+ ExceptionInfo *exception )
{
FILE
*input,
register ssize_t
i;
+ if (IfMagickFalse( ExpandFilenames(&argc,&argv) ))
+ ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
+ GetExceptionMessage(errno));
+
output=fopen_utf8(argv[argc-1],"wb");
if (output == (FILE *) NULL) {
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- argv[argc-1]);
+ ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[argc-1]);
return(MagickFalse);
}
for (i=2; i < (ssize_t) (argc-1); i++) {
+#if 0
+ fprintf(stderr, "DEBUG: Concatenate Image: \"%s\"\n", argv[i]);
+#endif
input=fopen_utf8(argv[i],"rb");
- if (input == (FILE *) NULL)
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[i]);
+ if (input == (FILE *) NULL) {
+ ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[i]);
+ continue;
+ }
for (c=fgetc(input); c != EOF; c=fgetc(input))
(void) fputc((char) c,output);
(void) fclose(input);
MagickCLI
*cli_wand;
- const char
- *option;
+ size_t
+ len;
- ProcessOptionFlags
- process_flags = MagickCommandOptionFlags;
+ assert(image_info != (ImageInfo *)NULL);
/* For specific OS command line requirements */
ReadCommandlLine(argc,&argv);
-#if 0
- status=ExpandFilenames(&argc,&argv);
- if ( IfMagickFalse(status) )
- ThrowConvertException(ResourceLimitError,"MemoryAllocationFailed",
- GetExceptionMessage(errno));
-#endif
-
/* Initialize special "CLI Wand" to hold images and settings (empty) */
cli_wand=AcquireMagickCLI(image_info,exception);
+ cli_wand->location="Initializing";
+ cli_wand->filename=argv[0];
cli_wand->line=1;
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "\"%s\"",argv[0]);
+
+
GetPathComponent(argv[0],TailPath,cli_wand->wand.name);
+ SetClientName(cli_wand->wand.name);
ConcatenateMagickString(cli_wand->wand.name,"-CLI",MaxTextExtent);
+ len=strlen(argv[0]); /* precaution */
+
/* "convert" command - give a "depreciation" warning" */
- if ( (LocaleCompare("convert",argv[0]+strlen((argv[0])-7)) == 0) ||
- (LocaleNCompare("convert",argv[0],7) == 0) ||
- (LocaleNCompare("lt-convert",argv[0],10) == 0) ) {
- process_flags = ConvertCommandOptionFlags;
- /*(void) FormatLocaleFile(stderr,"WARNING: %s\n",
- "The convert is depreciated in IMv7, use \"magick\"\n");*/
+ if (len>=7 && LocaleCompare("convert",argv[0]+len-7) == 0) {
+ cli_wand->process_flags = ConvertCommandOptionFlags;
+ (void) FormatLocaleFile(stderr,"WARNING: %s\n",
+ "The convert is depreciated in IMv7, use \"magick\"\n");
}
/* Special Case: If command name ends with "script" implied "-script" */
- if (LocaleCompare("script",argv[0]+strlen(argv[0])-6) == 0) {
- GetPathComponent(argv[1],TailPath,cli_wand->wand.name);
- ProcessScriptOptions(cli_wand,argc,argv,1);
- goto Magick_Command_Cleanup;
+ if (len>=6 && LocaleCompare("script",argv[0]+len-6) == 0) {
+ if (argc >= 2 && ( (*(argv[1]) != '-') || (strlen(argv[1]) == 1) )) {
+ GetPathComponent(argv[1],TailPath,cli_wand->wand.name);
+ ProcessScriptOptions(cli_wand,argv[1],argc,argv,2);
+ goto Magick_Command_Cleanup;
+ }
}
/* Special Case: Version Information and Abort */
if (argc == 2) {
- option=argv[1];
- if (LocaleCompare("-version",option) == 0) {
- CLISpecialOperator(cli_wand, "-version", (char *)NULL);
+ if ((LocaleCompare("-version",argv[1]) == 0) || /* GNU standard option */
+ (LocaleCompare("--version",argv[1]) == 0) ) { /* just version */
+ CLIOption(cli_wand, "-version");
goto Magick_Command_Exit;
}
- if ((LocaleCompare("-help",option) == 0) || /* GNU standard option */
- (LocaleCompare("--help",option) == 0) ) {
+ if ((LocaleCompare("-help",argv[1]) == 0) || /* GNU standard option */
+ (LocaleCompare("--help",argv[1]) == 0) ) { /* just a brief summary */
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "- Special Option \"%s\"", argv[1]);
MagickUsage(MagickFalse);
goto Magick_Command_Exit;
}
- if (LocaleCompare("-usage",option) == 0) {
- CLISpecialOperator(cli_wand, "-version", (char *)NULL);
+ if (LocaleCompare("-usage",argv[1]) == 0) { /* both version & usage */
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "- Special Option \"%s\"", argv[1]);
+ CLIOption(cli_wand, "-version" );
MagickUsage(MagickTrue);
goto Magick_Command_Exit;
}
goto Magick_Command_Exit;
}
- /* List Information and Abort */
- if (LocaleCompare("-list",argv[1]) == 0) {
- CLISpecialOperator(cli_wand, argv[1], argv[2]);
- goto Magick_Command_Exit;
- }
-
/* Special "concatenate option (hidden) for delegate usage */
if (LocaleCompare("-concatenate",argv[1]) == 0) {
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "- Special Option \"%s\"", argv[1]);
ConcatenateImages(argc,argv,exception);
goto Magick_Command_Exit;
}
+ /* List Information and Abort */
+ if (argc == 3 && LocaleCompare("-list",argv[1]) == 0) {
+ CLIOption(cli_wand, argv[1], argv[2]);
+ goto Magick_Command_Exit;
+ }
+
/* ------------- */
/* The Main Call */
First argument in the argv array is the script name to read.
*/
GetPathComponent(argv[2],TailPath,cli_wand->wand.name);
- ProcessScriptOptions(cli_wand,argc,argv,2);
+ ProcessScriptOptions(cli_wand,argv[2],argc,argv,3);
}
else {
/* Normal Command Line, assumes output file as last option */
- ProcessCommandOptions(cli_wand,argc,argv,1, process_flags);
+ ProcessCommandOptions(cli_wand,argc,argv,1);
}
/* ------------- */
Magick_Command_Cleanup:
- /* recover original image_info and clean up stacks */
+ cli_wand->location="Cleanup";
+ cli_wand->filename=argv[0];
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "\"%s\"",argv[0]);
+
+ /* recover original image_info and clean up stacks
+ FUTURE: "-reset stacks" option */
while (cli_wand->image_list_stack != (Stack *)NULL)
- CLISpecialOperator(cli_wand,")",(const char *)NULL);
+ CLIOption(cli_wand,")");
while (cli_wand->image_info_stack != (Stack *)NULL)
- CLISpecialOperator(cli_wand,"}",(const char *)NULL);
+ CLIOption(cli_wand,"}");
/* assert we have recovered the original structures */
assert(cli_wand->wand.image_info == image_info);
format="%w,%h,%m"; // Get this from image_info Option splaytree
text=InterpretImageProperties(image_info,cli_wand->wand.images,format,
- exception);
+ exception);
if (text == (char *) NULL)
ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
- "MemoryAllocationFailed","`%s'", GetExceptionMessage(errno));
+ "MemoryAllocationFailed","`%s'", GetExceptionMessage(errno));
else {
(void) ConcatenateString(&(*metadata),text);
text=DestroyString(text);
}
Magick_Command_Exit:
+ cli_wand->location="Exiting";
+ cli_wand->filename=argv[0];
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "\"%s\"",argv[0]);
+
/* Destroy the special CLI Wand */
cli_wand->wand.image_info = (ImageInfo *)NULL; /* not these */
cli_wand->wand.exception = (ExceptionInfo *)NULL;