From 668f43a00586c09376255f536941d61a6c1e63ac Mon Sep 17 00:00:00 2001 From: anthony Date: Mon, 20 Feb 2012 14:55:32 +0000 Subject: [PATCH] Adding "magick -script" to CLI interface (start) --- MagickCore/option.c | 150 ++++---- MagickCore/option.h | 2 +- MagickWand/magick-cli.c | 770 ++++++++++++++++++++++++++++++++++------ MagickWand/magick-cli.h | 31 +- config/english.xml | 9 + config/francais.xml | 13 +- 6 files changed, 771 insertions(+), 204 deletions(-) diff --git a/MagickCore/option.c b/MagickCore/option.c index 253f1a81b..be56618bd 100644 --- a/MagickCore/option.c +++ b/MagickCore/option.c @@ -168,6 +168,7 @@ static const OptionInfo */ { "(", 0L, SpecialOptionFlag, MagickTrue }, { ")", 0L, SpecialOptionFlag, MagickTrue }, + { "--", 0L, SpecialOptionFlag, MagickTrue }, { "+adaptive-blur", 1L, DeprecateOptionFlag, MagickTrue }, { "-adaptive-blur", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+adaptive-resize", 1L, DeprecateOptionFlag, MagickTrue }, @@ -200,8 +201,8 @@ static const OptionInfo { "-auto-orient", 0L, SimpleOperatorOptionFlag, MagickFalse }, { "+average", 0L, ListOperatorOptionFlag | FireOptionFlag | DeprecateOptionFlag, MagickTrue }, { "-average", 0L, ListOperatorOptionFlag | FireOptionFlag | DeprecateOptionFlag, MagickTrue }, - { "+backdrop", 0L, NonConvertOptionFlag, MagickFalse }, - { "-backdrop", 1L, NonConvertOptionFlag, MagickFalse }, + { "+backdrop", 0L, NonMagickOptionFlag, MagickFalse }, + { "-backdrop", 1L, NonMagickOptionFlag, MagickFalse }, { "+background", 0L, ImageInfoOptionFlag, MagickFalse }, { "-background", 1L, ImageInfoOptionFlag, MagickFalse }, { "+bench", 0L, GenesisOptionFlag, MagickFalse }, @@ -212,8 +213,8 @@ static const OptionInfo { "-black-point-compensation", 0L, ImageInfoOptionFlag, MagickFalse }, { "+black-threshold", 0L, DeprecateOptionFlag, MagickTrue }, { "-black-threshold", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+blend", 0L, NonConvertOptionFlag, MagickFalse }, - { "-blend", 1L, NonConvertOptionFlag, MagickFalse }, + { "+blend", 0L, NonMagickOptionFlag, MagickFalse }, + { "-blend", 1L, NonMagickOptionFlag, MagickFalse }, { "+blue-primary", 0L, ImageInfoOptionFlag, MagickFalse }, { "-blue-primary", 1L, ImageInfoOptionFlag, MagickFalse }, { "+blue-shift", 1L, SimpleOperatorOptionFlag, MagickFalse }, @@ -224,8 +225,8 @@ static const OptionInfo { "-border", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+bordercolor", 0L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, { "-bordercolor", 1L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, - { "+borderwidth", 0L, NonConvertOptionFlag, MagickFalse }, - { "-borderwidth", 1L, NonConvertOptionFlag, MagickFalse }, + { "+borderwidth", 0L, NonMagickOptionFlag, MagickFalse }, + { "-borderwidth", 1L, NonMagickOptionFlag, MagickFalse }, { "+box", 0L, ImageInfoOptionFlag | DrawInfoOptionFlag | DeprecateOptionFlag, MagickTrue }, { "-box", 1L, ImageInfoOptionFlag | DrawInfoOptionFlag | DeprecateOptionFlag, MagickTrue }, { "+brightness-contrast", 0L, DeprecateOptionFlag, MagickTrue }, @@ -260,8 +261,8 @@ static const OptionInfo { "-color-matrix", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+colorize", 1L, DeprecateOptionFlag, MagickTrue }, { "-colorize", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+colormap", 0L, NonConvertOptionFlag, MagickFalse }, - { "-colormap", 1L, NonConvertOptionFlag, MagickFalse }, + { "+colormap", 0L, NonMagickOptionFlag, MagickFalse }, + { "-colormap", 1L, NonMagickOptionFlag, MagickFalse }, { "+colors", 1L, DeprecateOptionFlag, MagickTrue }, { "-colors", 1L, ImageInfoOptionFlag, MagickFalse }, { "+colorspace", 0L, ImageInfoOptionFlag | SimpleOperatorOptionFlag, MagickFalse }, @@ -304,22 +305,22 @@ static const OptionInfo { "-density", 1L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, { "+depth", 0L, ImageInfoOptionFlag, MagickFalse }, { "-depth", 1L, ImageInfoOptionFlag, MagickFalse }, - { "+descend", 0L, NonConvertOptionFlag, MagickFalse }, - { "-descend", 1L, NonConvertOptionFlag, MagickFalse }, + { "+descend", 0L, NonMagickOptionFlag, MagickFalse }, + { "-descend", 1L, NonMagickOptionFlag, MagickFalse }, { "+deskew", 0L, SimpleOperatorOptionFlag, MagickFalse }, { "-deskew", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+despeckle", 0L, DeprecateOptionFlag, MagickTrue }, { "-despeckle", 0L, SimpleOperatorOptionFlag, MagickFalse }, { "+direction", 0L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, { "-direction", 1L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, - { "+displace", 0L, NonConvertOptionFlag, MagickFalse }, - { "-displace", 1L, NonConvertOptionFlag, MagickFalse }, + { "+displace", 0L, NonMagickOptionFlag, MagickFalse }, + { "-displace", 1L, NonMagickOptionFlag, MagickFalse }, { "+display", 1L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, { "-display", 1L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, { "+dispose", 0L, ImageInfoOptionFlag, MagickFalse }, { "-dispose", 1L, ImageInfoOptionFlag, MagickFalse }, - { "+dissolve", 0L, NonConvertOptionFlag, MagickFalse }, - { "-dissolve", 1L, NonConvertOptionFlag, MagickFalse }, + { "+dissolve", 0L, NonMagickOptionFlag, MagickFalse }, + { "-dissolve", 1L, NonMagickOptionFlag, MagickFalse }, { "+distort", 2L, SimpleOperatorOptionFlag, MagickFalse }, { "-distort", 2L, SimpleOperatorOptionFlag, MagickFalse }, { "+dither", 0L, ImageInfoOptionFlag | QuantizeInfoOptionFlag, MagickFalse }, @@ -348,7 +349,7 @@ static const OptionInfo { "-evaluate", 2L, SimpleOperatorOptionFlag, MagickFalse }, { "+evaluate-sequence", 1L, DeprecateOptionFlag | FireOptionFlag, MagickTrue }, { "-evaluate-sequence", 1L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, - { "-exit", 1L, SpecialOptionFlag, MagickFalse }, + { "-exit", 0L, SpecialOptionFlag, MagickFalse }, { "+extent", 1L, DeprecateOptionFlag, MagickTrue }, { "-extent", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+extract", 0L, ImageInfoOptionFlag, MagickFalse }, @@ -373,8 +374,8 @@ static const OptionInfo { "-flop", 0L, SimpleOperatorOptionFlag, MagickFalse }, { "+font", 0L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, { "-font", 1L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, - { "+foreground", 0L, NonConvertOptionFlag, MagickFalse }, - { "-foreground", 1L, NonConvertOptionFlag, MagickFalse }, + { "+foreground", 0L, NonMagickOptionFlag, MagickFalse }, + { "-foreground", 1L, NonMagickOptionFlag, MagickFalse }, { "+format", 0L, ImageInfoOptionFlag, MagickFalse }, { "-format", 1L, ImageInfoOptionFlag, MagickFalse }, { "+frame", 1L, DeprecateOptionFlag, MagickTrue }, @@ -401,16 +402,16 @@ static const OptionInfo { "-hald-clut", 0L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, { "+highlight-color", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "-highlight-color", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+iconGeometry", 0L, NonConvertOptionFlag, MagickFalse }, - { "-iconGeometry", 1L, NonConvertOptionFlag, MagickFalse }, - { "+iconic", 0L, NonConvertOptionFlag, MagickFalse }, - { "-iconic", 1L, NonConvertOptionFlag, MagickFalse }, + { "+iconGeometry", 0L, NonMagickOptionFlag, MagickFalse }, + { "-iconGeometry", 1L, NonMagickOptionFlag, MagickFalse }, + { "+iconic", 0L, NonMagickOptionFlag, MagickFalse }, + { "-iconic", 1L, NonMagickOptionFlag, MagickFalse }, { "+identify", 0L, DeprecateOptionFlag | FireOptionFlag, MagickTrue }, { "-identify", 0L, SimpleOperatorOptionFlag | FireOptionFlag, MagickFalse }, { "+ift", 0L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, { "-ift", 0L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, - { "+immutable", 0L, NonConvertOptionFlag, MagickFalse }, - { "-immutable", 0L, NonConvertOptionFlag, MagickFalse }, + { "+immutable", 0L, NonMagickOptionFlag, MagickFalse }, + { "-immutable", 0L, NonMagickOptionFlag, MagickFalse }, { "+implode", 0L, DeprecateOptionFlag, MagickTrue }, { "-implode", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+insert", 0L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, @@ -453,8 +454,8 @@ static const OptionInfo { "-loop", 1L, ImageInfoOptionFlag, MagickFalse }, { "+lowlight-color", 1L, DeprecateOptionFlag, MagickTrue }, { "-lowlight-color", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+magnify", 0L, NonConvertOptionFlag, MagickFalse }, - { "-magnify", 1L, NonConvertOptionFlag, MagickFalse }, + { "+magnify", 0L, NonMagickOptionFlag, MagickFalse }, + { "-magnify", 1L, NonMagickOptionFlag, MagickFalse }, { "+map", 0L, ListOperatorOptionFlag | FireOptionFlag | DeprecateOptionFlag, MagickTrue }, { "-map", 1L, SimpleOperatorOptionFlag | DeprecateOptionFlag, MagickTrue }, { "+mask", 0L, SimpleOperatorOptionFlag, MagickFalse }, @@ -467,11 +468,11 @@ static const OptionInfo { "-maximum", 0L, DeprecateOptionFlag | FireOptionFlag, MagickTrue }, { "+median", 1L, DeprecateOptionFlag, MagickTrue }, { "-median", 1L, DeprecateOptionFlag | FireOptionFlag, MagickTrue }, - { "+metric", 0L, NonConvertOptionFlag, MagickFalse }, - { "-metric", 1L, NonConvertOptionFlag, MagickFalse }, + { "+metric", 0L, NonMagickOptionFlag, MagickFalse }, + { "-metric", 1L, NonMagickOptionFlag, MagickFalse }, { "+minimum", 0L, DeprecateOptionFlag | FireOptionFlag, MagickTrue }, { "-minimum", 0L, DeprecateOptionFlag | FireOptionFlag, MagickTrue }, - { "+mode", 1L, NonConvertOptionFlag, MagickFalse }, + { "+mode", 1L, NonMagickOptionFlag, MagickFalse }, { "-mode", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+modulate", 1L, DeprecateOptionFlag, MagickTrue }, { "-modulate", 1L, SimpleOperatorOptionFlag, MagickFalse }, @@ -487,8 +488,8 @@ static const OptionInfo { "-mosaic", 0L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, { "+motion-blur", 1L, DeprecateOptionFlag, MagickTrue }, { "-motion-blur", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+name", 0L, NonConvertOptionFlag, MagickFalse }, - { "-name", 1L, NonConvertOptionFlag, MagickFalse }, + { "+name", 0L, NonMagickOptionFlag, MagickFalse }, + { "-name", 1L, NonMagickOptionFlag, MagickFalse }, { "+negate", 0L, SimpleOperatorOptionFlag, MagickFalse }, { "-negate", 0L, SimpleOperatorOptionFlag, MagickFalse }, { "+noise", 1L, SimpleOperatorOptionFlag, MagickFalse }, @@ -508,10 +509,10 @@ static const OptionInfo { "-page", 1L, ImageInfoOptionFlag, MagickFalse }, { "+paint", 0L, DeprecateOptionFlag, MagickTrue }, { "-paint", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+path", 0L, NonConvertOptionFlag, MagickFalse }, - { "-path", 1L, NonConvertOptionFlag, MagickFalse }, - { "+pause", 0L, NonConvertOptionFlag, MagickFalse }, - { "-pause", 1L, NonConvertOptionFlag, MagickFalse }, + { "+path", 0L, NonMagickOptionFlag, MagickFalse }, + { "-path", 1L, NonMagickOptionFlag, MagickFalse }, + { "+pause", 0L, NonMagickOptionFlag, MagickFalse }, + { "-pause", 1L, NonMagickOptionFlag, MagickFalse }, { "+passphrase", 0L, DeprecateOptionFlag, MagickTrue }, { "-passphrase", 1L, DeprecateOptionFlag, MagickTrue }, { "+ping", 0L, ImageInfoOptionFlag, MagickFalse }, @@ -544,7 +545,7 @@ static const OptionInfo { "-raise", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+random-threshold", 1L, DeprecateOptionFlag, MagickTrue }, { "-random-threshold", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "-read", 1L, ListOperatorOptionFlag, MagickFalse }, + { "-read", 1L, SpecialOptionFlag, MagickFalse }, { "+recolor", 1L, DeprecateOptionFlag, MagickTrue }, { "-recolor", 1L, DeprecateOptionFlag, MagickTrue }, { "+red-primary", 0L, ImageInfoOptionFlag, MagickFalse }, @@ -555,8 +556,8 @@ static const OptionInfo { "-region", 1L, SpecialOptionFlag, MagickFalse }, { "+remap", 0L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, { "-remap", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+remote", 0L, NonConvertOptionFlag, MagickFalse }, - { "-remote", 1L, NonConvertOptionFlag, MagickFalse }, + { "+remote", 0L, NonMagickOptionFlag, MagickFalse }, + { "-remote", 1L, NonMagickOptionFlag, MagickFalse }, { "+render", 0L, DrawInfoOptionFlag, MagickFalse }, { "-render", 0L, DrawInfoOptionFlag, MagickFalse }, { "+repage", 0L, SimpleOperatorOptionFlag, MagickFalse }, @@ -577,9 +578,9 @@ static const OptionInfo { "-sample", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+sampling-factor", 0L, ImageInfoOptionFlag, MagickFalse }, { "-sampling-factor", 1L, ImageInfoOptionFlag, MagickFalse }, - { "+sans", 1L, SpecialOptionFlag, MagickTrue }, /* equivelent 'noop' */ + { "+sans", 1L, SpecialOptionFlag, MagickTrue }, { "-sans", 1L, SpecialOptionFlag, MagickTrue }, - { "+sans0", 0L, SpecialOptionFlag, MagickTrue }, + { "+sans0", 0L, SpecialOptionFlag, MagickTrue }, /* equivelent to 'noop' */ { "-sans0", 0L, SpecialOptionFlag, MagickTrue }, { "+sans2", 2L, SpecialOptionFlag, MagickTrue }, { "-sans2", 2L, SpecialOptionFlag, MagickTrue }, @@ -587,10 +588,10 @@ static const OptionInfo { "-scale", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+scene", 0L, ImageInfoOptionFlag, MagickFalse }, { "-scene", 1L, ImageInfoOptionFlag, MagickFalse }, - { "+scenes", 0L, NonConvertOptionFlag, MagickFalse }, - { "-scenes", 1L, NonConvertOptionFlag, MagickFalse }, - { "+screen", 0L, NonConvertOptionFlag, MagickFalse }, - { "-screen", 1L, NonConvertOptionFlag, MagickFalse }, + { "+scenes", 0L, NonMagickOptionFlag, MagickFalse }, + { "-scenes", 1L, NonMagickOptionFlag, MagickFalse }, + { "+screen", 0L, NonMagickOptionFlag, MagickFalse }, + { "-screen", 1L, NonMagickOptionFlag, MagickFalse }, { "+seed", 0L, GlobalOptionFlag, MagickFalse }, { "-seed", 1L, GlobalOptionFlag, MagickFalse }, { "+segment", 1L, DeprecateOptionFlag, MagickTrue }, @@ -607,8 +608,8 @@ static const OptionInfo { "-shade", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+shadow", 1L, DeprecateOptionFlag, MagickTrue }, { "-shadow", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+shared-memory", 0L, NonConvertOptionFlag, MagickFalse }, - { "-shared-memory", 1L, NonConvertOptionFlag, MagickFalse }, + { "+shared-memory", 0L, NonMagickOptionFlag, MagickFalse }, + { "-shared-memory", 1L, NonMagickOptionFlag, MagickFalse }, { "+sharpen", 1L, DeprecateOptionFlag, MagickTrue }, { "-sharpen", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+shave", 1L, DeprecateOptionFlag, MagickTrue }, @@ -617,16 +618,16 @@ static const OptionInfo { "-shear", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+sigmoidal-contrast", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "-sigmoidal-contrast", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+silent", 0L, NonConvertOptionFlag, MagickFalse }, - { "-silent", 1L, NonConvertOptionFlag, MagickFalse }, + { "+silent", 0L, NonMagickOptionFlag, MagickFalse }, + { "-silent", 1L, NonMagickOptionFlag, MagickFalse }, { "+size", 0L, ImageInfoOptionFlag, MagickFalse }, { "-size", 1L, ImageInfoOptionFlag, MagickFalse }, { "+sketch", 1L, DeprecateOptionFlag, MagickTrue }, { "-sketch", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+smush", 1L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, { "-smush", 1L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, - { "+snaps", 0L, NonConvertOptionFlag, MagickFalse }, - { "-snaps", 1L, NonConvertOptionFlag, MagickFalse }, + { "+snaps", 0L, NonMagickOptionFlag, MagickFalse }, + { "-snaps", 1L, NonMagickOptionFlag, MagickFalse }, { "+solarize", 1L, DeprecateOptionFlag, MagickTrue }, { "-solarize", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+sparse-color", 2L, DeprecateOptionFlag, MagickTrue }, @@ -637,10 +638,10 @@ static const OptionInfo { "-spread", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+statistic", 2L, DeprecateOptionFlag, MagickTrue }, { "-statistic", 2L, SimpleOperatorOptionFlag, MagickFalse }, - { "+stegano", 0L, NonConvertOptionFlag, MagickFalse }, - { "-stegano", 1L, NonConvertOptionFlag, MagickFalse }, + { "+stegano", 0L, NonMagickOptionFlag, MagickFalse }, + { "-stegano", 1L, NonMagickOptionFlag, MagickFalse }, { "+stereo", 0L, DeprecateOptionFlag, MagickTrue }, - { "-stereo", 1L, NonConvertOptionFlag, MagickFalse }, + { "-stereo", 1L, NonMagickOptionFlag, MagickFalse }, { "+stretch", 1L, DeprecateOptionFlag, MagickTrue }, { "-stretch", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+strip", 0L, DeprecateOptionFlag, MagickTrue }, @@ -651,8 +652,8 @@ static const OptionInfo { "-strokewidth", 1L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse }, { "+style", 0L, DrawInfoOptionFlag, MagickFalse }, { "-style", 1L, DrawInfoOptionFlag, MagickFalse }, - { "+subimage-search", 0L, NonConvertOptionFlag, MagickFalse }, - { "-subimage-search", 0L, NonConvertOptionFlag, MagickFalse }, + { "+subimage-search", 0L, NonMagickOptionFlag, MagickFalse }, + { "-subimage-search", 0L, NonMagickOptionFlag, MagickFalse }, { "+swap", 0L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, { "-swap", 1L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, { "+swirl", 1L, DeprecateOptionFlag, MagickTrue }, @@ -661,8 +662,8 @@ static const OptionInfo { "-synchronize", 0L, ImageInfoOptionFlag, MagickFalse }, { "+taint", 0L, ImageInfoOptionFlag, MagickFalse }, { "-taint", 0L, ImageInfoOptionFlag, MagickFalse }, - { "+text-font", 0L, NonConvertOptionFlag, MagickFalse }, - { "-text-font", 1L, NonConvertOptionFlag, MagickFalse }, + { "+text-font", 0L, NonMagickOptionFlag, MagickFalse }, + { "-text-font", 1L, NonMagickOptionFlag, MagickFalse }, { "+texture", 0L, ImageInfoOptionFlag, MagickFalse }, { "-texture", 1L, ImageInfoOptionFlag, MagickFalse }, { "+threshold", 0L, SimpleOperatorOptionFlag, MagickFalse }, @@ -675,8 +676,8 @@ static const OptionInfo { "-tile-offset", 1L, ImageInfoOptionFlag, MagickFalse }, { "+tint", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "-tint", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+title", 0L, NonConvertOptionFlag, MagickFalse }, - { "-title", 1L, NonConvertOptionFlag, MagickFalse }, + { "+title", 0L, NonMagickOptionFlag, MagickFalse }, + { "-title", 1L, NonMagickOptionFlag, MagickFalse }, { "+transform", 0L, DeprecateOptionFlag, MagickTrue }, { "-transform", 0L, SimpleOperatorOptionFlag | DeprecateOptionFlag, MagickTrue }, { "+transparent", 1L, SimpleOperatorOptionFlag, MagickFalse }, @@ -703,10 +704,10 @@ static const OptionInfo { "-units", 1L, ImageInfoOptionFlag, MagickFalse }, { "+unsharp", 1L, DeprecateOptionFlag, MagickTrue }, { "-unsharp", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+update", 0L, NonConvertOptionFlag, MagickFalse }, - { "-update", 1L, NonConvertOptionFlag, MagickFalse }, - { "+use-pixmap", 0L, NonConvertOptionFlag, MagickFalse }, - { "-use-pixmap", 1L, NonConvertOptionFlag, MagickFalse }, + { "+update", 0L, NonMagickOptionFlag, MagickFalse }, + { "-update", 1L, NonMagickOptionFlag, MagickFalse }, + { "+use-pixmap", 0L, NonMagickOptionFlag, MagickFalse }, + { "-use-pixmap", 1L, NonMagickOptionFlag, MagickFalse }, { "+verbose", 0L, ImageInfoOptionFlag, MagickFalse }, { "-verbose", 0L, ImageInfoOptionFlag, MagickFalse }, { "+version", 0L, DeprecateOptionFlag, MagickTrue }, @@ -717,10 +718,10 @@ static const OptionInfo { "-vignette", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+virtual-pixel", 0L, ImageInfoOptionFlag | SimpleOperatorOptionFlag, MagickFalse }, { "-virtual-pixel", 1L, ImageInfoOptionFlag | SimpleOperatorOptionFlag, MagickFalse }, - { "+visual", 0L, NonConvertOptionFlag, MagickFalse }, - { "-visual", 1L, NonConvertOptionFlag, MagickFalse }, - { "+watermark", 0L, NonConvertOptionFlag, MagickFalse }, - { "-watermark", 1L, NonConvertOptionFlag, MagickFalse }, + { "+visual", 0L, NonMagickOptionFlag, MagickFalse }, + { "-visual", 1L, NonMagickOptionFlag, MagickFalse }, + { "+watermark", 0L, NonMagickOptionFlag, MagickFalse }, + { "-watermark", 1L, NonMagickOptionFlag, MagickFalse }, { "+wave", 1L, DeprecateOptionFlag, MagickTrue }, { "-wave", 1L, SimpleOperatorOptionFlag, MagickFalse }, { "+weight", 1L, DeprecateOptionFlag, MagickTrue }, @@ -729,10 +730,10 @@ static const OptionInfo { "-white-point", 1L, ImageInfoOptionFlag, MagickFalse }, { "+white-threshold", 1L, DeprecateOptionFlag, MagickTrue }, { "-white-threshold", 1L, SimpleOperatorOptionFlag, MagickFalse }, - { "+window", 0L, NonConvertOptionFlag, MagickFalse }, - { "-window", 1L, NonConvertOptionFlag, MagickFalse }, - { "+window-group", 0L, NonConvertOptionFlag, MagickFalse }, - { "-window-group", 1L, NonConvertOptionFlag, MagickFalse }, + { "+window", 0L, NonMagickOptionFlag, MagickFalse }, + { "-window", 1L, NonMagickOptionFlag, MagickFalse }, + { "+window-group", 0L, NonMagickOptionFlag, MagickFalse }, + { "-window-group", 1L, NonMagickOptionFlag, MagickFalse }, { "+write", 1L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, { "-write", 1L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse }, { (char *) NULL, 0L, UndefinedOptionFlag, MagickFalse } @@ -2032,7 +2033,7 @@ MagickExport const OptionInfo *GetCommandOptionInfo(const char *value) /* faster binary search of command table, now that its length is known */ l=0; - h=table_size-1; + h=table_size; while ( l < h ) { int cmp; @@ -2041,11 +2042,12 @@ MagickExport const OptionInfo *GetCommandOptionInfo(const char *value) cmp=LocaleCompare(value+1,option_info[i].mnemonic+1); if ( cmp == 0 ) cmp = *value - *(option_info[i].mnemonic); - - (void) fprintf(stderr,"%d --- %u < %u < %u --- \"%s\" < \"%s\" < \"%s\"\n", +#if 0 + (void) FormatLocaleFile(stderr, + "%d --- %u < %u < %u --- \"%s\" < \"%s\" < \"%s\"\n", cmp,l,i,h,option_info[l].mnemonic,option_info[i].mnemonic, option_info[h].mnemonic); - +#endif if (cmp == 0) return(&option_info[i]); if (cmp > 0) l=i+1; else h=i; /* reassign search bounds */ diff --git a/MagickCore/option.h b/MagickCore/option.h index f7b36f10b..e157996ee 100644 --- a/MagickCore/option.h +++ b/MagickCore/option.h @@ -145,7 +145,7 @@ typedef enum SpecialOptionFlag = 0x0040, /* Special handled Option */ GenesisOptionFlag = 0x0080, /* Genesis Command Wrapper Option */ - NonConvertOptionFlag = 0x1000, /* Option not used by Convert/Magick */ + NonMagickOptionFlag = 0x1000, /* Option not used by Magick Command */ FireOptionFlag = 0x4000, /* Convert operation seq firing point */ DeprecateOptionFlag = 0x8000 /* Deprecate option, give warning */ diff --git a/MagickWand/magick-cli.c b/MagickWand/magick-cli.c index 91e7c2363..6ec30063a 100644 --- a/MagickWand/magick-cli.c +++ b/MagickWand/magick-cli.c @@ -49,34 +49,285 @@ #include "MagickWand/studio.h" #include "MagickWand/MagickWand.h" #include "MagickWand/magick-wand-private.h" -#include "MagickWand/operation.h" -#include "MagickCore/version.h" +#include "MagickCore/memory_.h" #include "MagickCore/string-private.h" +#include "MagickWand/operation.h" #include "MagickCore/utility-private.h" +#include "MagickCore/version.h" +#define MagickCommandDebug 0 /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % -+ M a g i c k C o m m a n d S p e c i a l % +% G e t S c r i p t T o k e n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% MagickS() Reads the various reads various options defining how -% to read, process and write images. The options can be sourced from the -% command line, or from script files, or pipelines. +% GetScriptToken() is fairly general, finite state token parser. That will +% divide a input file stream into tokens, in a way that is almost identical +% to a UNIX shell. +% +% It returns 'MagickTrue' if a token was found. Even in the special case of +% a empty token followed immediatally by a EOF. For example: ''{EOF} +% +% A token is returned immediatally the end of token is found. That is +% parsing is purely character by character, and not line-by-line. This +% should allow for mixed stream of tokens (options), and other data (images) +% without problems. Assuming the other data has a well defined End-Of-Data +% handling (see complex example below). +% +% 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" +% +% 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. % -% Processing is performed using stack of expanded 'Wand' structures, which -% not only define 'image_info' store of current global options, but also the -% current input source of the options. +% For example Quoting the quote chars: +% \' "'" \" '"' "\"" \\ '\' "\\" +% +% Comments start with a '#' character at the start of a new token (generally +% at start of a line, or after a unquoted white space charcater) and continue +% to the end of line. The are simply ignored. You can escape a comment '#' +% character to return a token that starts with such a character. +% +% More complex example... +% Sending a PGM image in the middle of a standard input script. +% +% magick -script - <stream); \ + token_info->curr_column++; \ + if ( c == '\n' ) \ + token_info->curr_line++, token_info->curr_column=0; \ +} +/* macro to collect the token characters */ +#define SaveChar(c) \ +{ \ + if ((size_t) offset >= (token_info->length-1)) \ + { token_info->token[offset++]='\0'; \ + token_info->status=TokenStatusTokenTooBig; \ + return(MagickFalse); \ + } \ + token_info->token[offset++]=(char) (c); \ +} + +static MagickBooleanType GetScriptToken(ScriptTokenInfo *token_info) +{ + + int + quote, + c; + + int + state; + + ssize_t + offset; + + /* EOF - no more tokens! */ + if (token_info->status != TokenStatusOK) + { + token_info->token[0]='\0'; + return(MagickFalse); + } + + state=IN_WHITE; + quote='\0'; + offset=0; + while(1) + { + /* get character */ + GetChar(c); + if (c == '\0' || c == EOF) + break; + + /* hash comment handling */ + if ( state == IN_COMMENT ) + { if ( c == '\n' ) + state=IN_WHITE; + continue; + } + if (c == '#' && state == IN_WHITE) + state=IN_COMMENT; + /* whitespace break character */ + if (strchr(" \n\r\t",c) != (char *)NULL) + { + switch (state) + { + case IN_TOKEN: + token_info->token[offset]='\0'; + return(MagickTrue); + case IN_QUOTE: + SaveChar(c); + break; + } + continue; + } + /* quote character */ + if (strchr("'\"",c) != (char *)NULL) + { + switch (state) + { + case IN_WHITE: + token_info->token_line=token_info->curr_line; + token_info->token_column=token_info->curr_column; + case IN_TOKEN: + state=IN_QUOTE; + quote=c; + break; + case IN_QUOTE: + if (c == quote) + { + state=IN_TOKEN; + quote='\0'; + } + else + SaveChar(c); + break; + } + continue; + } + /* escape char (preserve in quotes - unless escaping the same quote) */ + if (c == '\\') + { + if ( state==IN_QUOTE && quote == '\'' ) + { + SaveChar('\\'); + continue; + } + GetChar(c); + if (c == '\0' || c == EOF) + { + SaveChar('\\'); + break; + } + switch (state) + { + case IN_WHITE: + token_info->token_line=token_info->curr_line; + token_info->token_column=token_info->curr_column; + state=IN_TOKEN; + break; + case IN_QUOTE: + if (c != quote && c != '\\') + SaveChar('\\'); + break; + } + SaveChar(c); + continue; + } + /* ordinary character */ + switch (state) + { + case IN_WHITE: + token_info->token_line=token_info->curr_line; + token_info->token_column=token_info->curr_column; + state=IN_TOKEN; + case IN_TOKEN: + case IN_QUOTE: + SaveChar(c); + break; + case IN_COMMENT: + break; + } + } + /* stream has EOF or produced a fatal error */ + token_info->token[offset]='\0'; + token_info->status = TokenStatusEOF; + if (state == IN_QUOTE) + token_info->status = TokenStatusBadQuotes; + if (c == '\0' ) + token_info->status = TokenStatusBinary; + if (state == IN_TOKEN && token_info->status == TokenStatusEOF) + return(MagickTrue); + return(MagickFalse); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % ++ P r o c e s s S p e c i a l O p t i o n % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ProcessSpecialOption() Apply certian options that are specific to Shell +% API interface. Specifically reading images and handling image and +% image_info (settings) stacks. +% +% The format of the ProcessSpecialOption method is: +% +% void ProcessSpecialOption(MagickWand *wand,const char *option, +% const char *arg, ProcessOptionFlags process_flags ) % % A description of each parameter follows: % @@ -86,14 +337,14 @@ % % o arg: Argument for option, if required % +% o process_flags: Wether to process specific options or not. +% */ -WandExport void MagickSpecialOption(MagickWand *wand, - const char *option, const char *arg) +WandExport void ProcessSpecialOption(MagickWand *wand, + const char *option, const char *arg, ProcessOptionFlags process_flags) { - if (LocaleCompare("-read",option) == 0) + if ( LocaleCompare("-read",option) == 0 ) { -#if 1 - /* MagickCore style of Read */ Image * new_images; @@ -103,14 +354,17 @@ WandExport void MagickSpecialOption(MagickWand *wand, else new_images=ReadImages(wand->image_info,wand->exception); AppendImageToList(&wand->images, new_images); -#else - /* MagickWand style of Read - append new images -- FAILS */ - MagickSetLastIterator(wand); - MagickReadImage(wand, arg); - MagickSetFirstIterator(wand); -#endif return; } + if (LocaleCompare("-sans",option) == 0) + return; + if (LocaleCompare("-sans0",option) == 0) + return; + if (LocaleCompare("-sans2",option) == 0) + return; + if (LocaleCompare("-noop",option) == 0) + return; + #if 0 if (LocaleCompare(option,"(") == 0) // push images/settings @@ -119,28 +373,41 @@ WandExport void MagickSpecialOption(MagickWand *wand, if (LocaleCompare(option,"respect_parenthesis") == 0) // adjust stack handling // Other 'special' options this should handle - // "region" "clone" "list" "version" "noop" "sans*"? + // "region" "clone" "list" "version" // It does not do "exit" however as due to its side-effect requirements + + if ( ( process_flags & ProcessUnknownOptionError ) != 0 ) + MagickExceptionReturn(OptionError,"InvalidUseOfOption",option); #endif } + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % -+ M a g i c k C o m m a n d P r o c e s s O p t i o n s % ++ P r o c e s s S c r i p t O p t i o n s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% MagickCommandProcessOptions() reads and processes arguments in the given -% command line argument array. +% ProcessScriptOptions() reads options and processes options as they are +% found in the given file, or pipeline. The filename to open and read +% options is given as the zeroth argument of the argument array given. % -% The format of the MagickImageCommand method is: +% A script not 'return' to the command line processing, nor can they +% call (and return from) other scripts. At least not at this time. +% +% However special script options may used to read and process the other +% argument provided, typically those that followed a "-script" option on the +% command line. These extra script arguments may be interpreted as being +% images to read or write, settings (strings), or more options to be +% processed. How they are treated is up to the script being processed. % -% void MagickCommandArgs(MagickWand *wand,int argc,char **argv, -% int *index, ) +% The format of the ProcessScriptOptions method is: +% +% void ProcessScriptOptions(MagickWand *wand,int argc,char **argv) % % A description of each parameter follows: % @@ -150,21 +417,292 @@ WandExport void MagickSpecialOption(MagickWand *wand, % % o argv: A text array containing the command line arguments. % -% o index: where we are upto in processing given arguments +*/ +#define MagickExceptionScript(severity,tag,arg,line,col) \ + (void) ThrowMagickException(wand->exception,GetMagickModule(),severity,tag, \ + "'%s' : Line %u Column %u of script \"%s\"", arg, line, col, wand->name); + +WandExport void ProcessScriptOptions(MagickWand *wand,int argc, + char **argv) +{ + char + *option, + *arg1, + *arg2; + + ssize_t + count; + + size_t + option_line, /* line and column of current option */ + option_column; + + CommandOptionFlags + option_type; + + ScriptTokenInfo + token_info; + + MagickBooleanType + plus_alt_op, + file_opened; + + assert(argc>0 && argv[argc-1] != (char *)NULL); + assert(wand != (MagickWand *) NULL); + assert(wand->signature == WandSignature); + assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */ + if (wand->debug != MagickFalse) + (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); + + /* Initialize variables */ + /* FUTURE handle file opening for '-' 'fd:N' or script filename */ + file_opened=MagickFalse; + if ( LocaleCompare(argv[0],"-") == 0 ) + { + CopyMagickString(wand->name,"stdin",MaxTextExtent); + token_info.stream=stdin; + file_opened=MagickFalse; + } + else + { + GetPathComponent(argv[0],TailPath,wand->name); + token_info.stream=fopen(argv[0], "r"); + file_opened=MagickTrue; + } + + option = arg1 = arg2 = (char*)NULL; + token_info.curr_line=1; + token_info.curr_column=0; + token_info.status=TokenStatusOK; + token_info.length=MaxTextExtent; + token_info.token=(char *) AcquireQuantumMemory(MaxTextExtent,sizeof(char)); + if (token_info.token == (char *) NULL) + { + if ( file_opened != MagickFalse ) + fclose(token_info.stream); + MagickExceptionScript(ResourceLimitError,"MemoryAllocationFailed","",0,0); + (void) ThrowMagickException(wand->exception,GetMagickModule(), + ResourceLimitError,"MemoryAllocationFailed","script token buffer"); + return; + } + + /* Process Options from Script */ + while (1) + { + /* Get a option */ + if( GetScriptToken(&token_info) == MagickFalse ) + break; + + /* option length sanity check */ + if( strlen(token_info.token) > 40 ) + { token_info.token[37] = '.'; + token_info.token[38] = '.'; + token_info.token[39] = '.'; + token_info.token[40] = '\0'; + MagickExceptionScript(OptionFatalError,"UnrecognizedOption", + token_info.token,token_info.token_line,token_info.token_column); + break; + } + + /* save option details */ + CloneString(&option,token_info.token); + option_line=token_info.token_line; + option_column=token_info.token_column; + +#if MagickCommandDebug + (void) FormatLocaleFile(stderr, "Script Option Token: %u,%u: \"%s\"\n", + option_line, option_column, option ); +#endif + /* get option type and argument count */ + { const OptionInfo *option_info = GetCommandOptionInfo(option); + count=option_info->type; + option_type=option_info->flags; +#if MagickCommandDebug >= 2 + (void) FormatLocaleFile(stderr, "option \"%s\" matched \"%s\"\n", + option, option_info->mnemonic ); +#endif + } + + /* handle a undefined option - image read? */ + if ( option_type == UndefinedOptionFlag || + (option_type & NonMagickOptionFlag) != 0 ) + { +#if MagickCommandDebug + (void) FormatLocaleFile(stderr, "Script Non-Option: \"%s\"\n", option); +#endif + if ( IsCommandOption(option) == MagickFalse) + { + /* non-option -- treat as a image read */ + ProcessSpecialOption(wand,"-read",option,MagickScriptReadFlags); + count = 0; + continue; + } + MagickExceptionScript(OptionFatalError,"UnrecognizedOption", + option,option_line,option_column); + break; + } + + plus_alt_op = MagickFalse; + if (*option=='+') plus_alt_op = MagickTrue; + + if ( count >= 1 ) + { + if( GetScriptToken(&token_info) == MagickFalse ) + { + MagickExceptionScript(OptionError,"MissingArgument",option, + option_line,option_column); + break; + } + CloneString(&arg1,token_info.token); + } + else + CloneString(&arg1,(*option!='+')?"true":(char *)NULL); + + if ( count >= 2 ) + { + if( GetScriptToken(&token_info) == MagickFalse ) + { + MagickExceptionScript(OptionError,"MissingArgument",option, + option_line,option_column); + break; + } + CloneString(&arg2,token_info.token); + } + else + CloneString(&arg2,(char *)NULL); + + /* handle script special options */ + //either continue processing command line + // or making use of the command line options. + //ProcessCommandOptions(wand,count+1,argv, MagickScriptArgsFlags); + +#if MagickCommandDebug + (void) FormatLocaleFile(stderr, + "Script Option: \"%s\" \tCount: %d Flags: %04x Args: \"%s\" \"%s\"\n", + option,(int) count,option_type,arg1,arg2); +#endif + + /* Process non-script specific option from file */ + if ( (option_type & SpecialOptionFlag) != 0 ) + { + if ( LocaleCompare(option,"-exit") == 0 ) + break; + /* No "-script" from script at this time */ + ProcessSpecialOption(wand,option,arg1,MagickScriptReadFlags); + } + + if ( (option_type & SettingOptionFlags) != 0 ) + { + WandSettingOptionInfo(wand, option+1, arg1); + // FUTURE: Sync Specific Settings into Images + } + + if ( (option_type & SimpleOperatorOptionFlag) != 0) + WandSimpleOperatorImages(wand, plus_alt_op, option+1, arg1, arg2); + + if ( (option_type & ListOperatorOptionFlag) != 0 ) + WandListOperatorImages(wand, plus_alt_op, option+1, arg1, arg2); + + // FUTURE: '-regard_warning' causes IM to exit more prematurely! + // Note pipelined options may like more control over this level + if (wand->exception->severity > ErrorException) + { + if (wand->exception->severity > ErrorException) + //(regard_warnings != MagickFalse)) + break; /* FATAL - caller handles exception */ + CatchException(wand->exception); /* output warnings and clear!!! */ + } + } +#if MagickCommandDebug + (void) FormatLocaleFile(stderr, "Script End: %d\n", token_info.status); +#endif + /* token sanity for error report */ + if( strlen(token_info.token) > 40 ) + { token_info.token[37] = '.'; + token_info.token[38] = '.'; + token_info.token[39] = '.'; + token_info.token[40] = '\0'; + } + + switch( token_info.status ) + { + case TokenStatusBadQuotes: + MagickExceptionScript(OptionFatalError,"ScriptUnbalancedQuotes", + token_info.token,token_info.token_line,token_info.token_column); + break; + case TokenStatusTokenTooBig: + MagickExceptionScript(OptionFatalError,"ScriptTokenTooBig", + token_info.token,token_info.token_line,token_info.token_column); + break; + case TokenStatusBinary: + MagickExceptionScript(OptionFatalError,"ScriptIsBinary","", + token_info.curr_line,token_info.curr_column); + break; + case TokenStatusOK: + case TokenStatusEOF: + break; + } + + /* Clean up */ + if ( file_opened != MagickFalse ) + fclose(token_info.stream); + + CloneString(&option,(char *)NULL); + CloneString(&arg1,(char *)NULL); + CloneString(&arg2,(char *)NULL); + + return; +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % ++ P r o c e s s C o m m a n d O p t i o n s % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ProcessCommandOptions() reads and processes arguments in the given +% command line argument array. The array does not contain the command +% being processed, only the options. +% +% 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 +% are to be handled, and if the last argument in array is to be regarded as a +% final image write argument (filename or special coder). +% +% The format of the ProcessCommandOptions method is: +% +% int ProcessCommandOptions(MagickWand *wand,int argc,char **argv, +% int *index, ProcessOptionFlags process_flags ) +% +% A description of each parameter follows: +% +% o wand: the main CLI Wand to use. +% +% o argc: the number of elements in the argument vector. +% +% o argv: A text array containing the command line arguments. +% +% o process_flags: What type of arguments we are allowed to process % -% o flags: Allow or disallow specific options */ -#define MagickExceptionContinue(severity,tag,option,arg) \ +/* FUTURE: correctly identify option... CLI arg, Script line,column */ +#define MagickExceptionContinue(severity,tag,arg,index) \ (void) ThrowMagickException(wand->exception,GetMagickModule(),severity,tag, \ - "'%s' arg#%lu", option, (unsigned long)arg) + "'%s' : CLI Arg #%d", arg, (int) index); \ + #define MagickExceptionReturn(severity,tag,option,arg) \ { \ MagickExceptionContinue(severity,tag,option,arg); \ return; \ } -WandExport void MagickCommandProcessOptions(MagickWand *wand,int argc, - char **argv, int *index, OptionProcessFlags process_flags ) +WandExport void ProcessCommandOptions(MagickWand *wand,int argc, + char **argv, ProcessOptionFlags process_flags ) { const char *option, @@ -176,11 +714,13 @@ WandExport void MagickCommandProcessOptions(MagickWand *wand,int argc, ssize_t i, + end, count; CommandOptionFlags option_type; + assert(argc>0 && argv[argc-1] != (char *)NULL); assert(wand != (MagickWand *) NULL); assert(wand->signature == WandSignature); assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */ @@ -190,80 +730,89 @@ WandExport void MagickCommandProcessOptions(MagickWand *wand,int argc, /* Parse command-line options. */ - count=0; - for (i=*index; i < (ssize_t) (argc-1); i+=count+1) + end = argc; + if ( ( process_flags & ProcessOutputFile ) != 0 ) + end--; + for (i=0; i < end; i += count +1) { - *index=i; +#if MagickCommandDebug >= 2 + (void) FormatLocaleFile(stderr, "index= %d\n", i ); +#endif + /* Finished processing one option? */ + if ( ( process_flags & ProcessOneOptionOnly ) != 0 && i != 0 ) + return; + option=argv[i]; plus_alt_op = MagickFalse; arg1=(char *)NULL; arg2=(char *)NULL; -#define MagickCommandDebug 1 -#if 1 - { const OptionInfo *option_info = - GetCommandOptionInfo(argv[i]); + + { const OptionInfo *option_info = GetCommandOptionInfo(argv[i]); count=option_info->type; option_type=option_info->flags; -#if MagickCommandDebug - (void) FormatLocaleFile(stderr, "Option: \"%s\"\n", option_info->mnemonic); +#if MagickCommandDebug >= 2 + (void) FormatLocaleFile(stderr, "option \"%s\" matched \"%s\"\n", + argv[i], option_info->mnemonic ); #endif } -#else - count=ParseCommandOption(MagickCommandOptions,MagickFalse,argv[i]); - option_type=(CommandOptionFlags) GetCommandOptionFlags( - MagickCommandOptions,MagickFalse,argv[i]); -#endif - - if ( count == -1 || option_type == UndefinedOptionFlag || - (option_type & NonConvertOptionFlag) != 0 ) + if ( option_type == UndefinedOptionFlag || + (option_type & NonMagickOptionFlag) != 0 ) { #if MagickCommandDebug (void) FormatLocaleFile(stderr, "CLI Non-Option: \"%s\"\n", option); #endif - - if (IsCommandOption(option) == MagickFalse) + if ( IsCommandOption(option) != MagickFalse ) { - /* non-option -- treat as a image read */ - MagickSpecialOption(wand,"-read",option); - count = 0; - continue; + if ( ( process_flags & ProcessNonOptionImageRead ) != 0 ) + { + /* non-option -- treat as a image read */ + ProcessSpecialOption(wand,"-read",option,process_flags); + count = 0; + } + } + else if ( ( process_flags & ProcessUnknownOptionError ) != 0 ) + { + MagickExceptionReturn(OptionFatalError,"UnrecognizedOption", + option,i); + return; } - else - MagickExceptionReturn(OptionError,"UnrecognizedOption",option,i); + continue; } -#if MagickCommandDebug - (void) FormatLocaleFile(stderr, - "CLI Option: \"%s\" \tCount: %d Flags: %04x Args: \"%s\" \"%s\"\n", - option,(int) count,option_type,arg1,arg2); -#endif - if ( (option_type & DeprecateOptionFlag) != 0 ) MagickExceptionContinue(OptionWarning,"DeprecatedOption",option,i); /* continue processing option anyway */ - if ((i+count) > (ssize_t) (argc-1)) + if ((i+count) >= end ) MagickExceptionReturn(OptionError,"MissingArgument",option,i); + if (*option=='+') plus_alt_op = MagickTrue; if (*option!='+') arg1 = "true"; if ( count >= 1 ) arg1 = argv[i+1]; if ( count >= 2 ) arg2 = argv[i+2]; +#if MagickCommandDebug + (void) FormatLocaleFile(stderr, + "CLI Option: \"%s\" \tCount: %d Flags: %04x Args: \"%s\" \"%s\"\n", + option,(int) count,option_type,arg1,arg2); +#endif + if ( (option_type & SpecialOptionFlag) != 0 ) { - if (LocaleCompare(option,"-exit") == 0) + if ( ( process_flags & ProcessExitOption ) != 0 + && LocaleCompare(option,"-exit") == 0 ) return; -#if 0 - if (LocaleCompare(option,"-script") == 0) + if ( ( process_flags & ProcessScriptOption ) != 0 + && LocaleCompare(option,"-script") == 0) { // Unbalanced Parenthesis if stack not empty - // Call Script, with filename as argv[0] + // Call Script, with a filename as a zeroth argument + ProcessScriptOptions(wand,argc-(i+1),argv+(i+1)); return; } -#endif - MagickSpecialOption(wand,option,arg1); + ProcessSpecialOption(wand,option,arg1,process_flags); } if ( (option_type & SettingOptionFlags) != 0 ) @@ -273,14 +822,10 @@ WandExport void MagickCommandProcessOptions(MagickWand *wand,int argc, } if ( (option_type & SimpleOperatorOptionFlag) != 0) - { - WandSimpleOperatorImages(wand, plus_alt_op, option+1, arg1, arg2); - } + WandSimpleOperatorImages(wand, plus_alt_op, option+1, arg1, arg2); if ( (option_type & ListOperatorOptionFlag) != 0 ) - { - WandListOperatorImages(wand, plus_alt_op, option+1, arg1, arg2); - } + WandListOperatorImages(wand, plus_alt_op, option+1, arg1, arg2); // FUTURE: '-regard_warning' causes IM to exit more prematurely! // Note pipelined options may like more control over this level @@ -288,13 +833,19 @@ WandExport void MagickCommandProcessOptions(MagickWand *wand,int argc, { if (wand->exception->severity > ErrorException) //(regard_warnings != MagickFalse)) - return; /* FATAL - let caller handle */ + return; /* FATAL - caller handles exception */ CatchException(wand->exception); /* output warnings and clear!!! */ } } - assert(i==(ssize_t)(argc-1)); - option=argv[i]; /* the last argument - output filename! */ + if ( ( process_flags & ProcessOutputFile ) == 0 ) + return; + assert(end==argc-1); + + /* + Write out final image! + */ + option=argv[i]; #if MagickCommandDebug (void) FormatLocaleFile(stderr, "CLI Output: \"%s\"\n", option ); @@ -303,31 +854,24 @@ WandExport void MagickCommandProcessOptions(MagickWand *wand,int argc, // if stacks are not empty // ThrowConvertException(OptionError,"UnbalancedParenthesis",option,i); - /* FUTURE: in the following produce a better error report - -- Missing Output filename - */ - - - /* This is the only value 'do no write' option for a CLI */ + /* This is a valid 'do no write' option for a CLI */ if (LocaleCompare(option,"-exit") == 0 ) return; /* just exit, no image write */ /* If there is an option -- produce an error */ if (IsCommandOption(option) != MagickFalse) - MagickExceptionReturn(OptionError,"MissingAnImageFilename",option,i); + /* FUTURE: Better Error - Output Filename not Found */ + MagickExceptionReturn(OptionError,"MissingOutputFilename",option,i); - /* If no images */ + /* If no images in MagickWand */ if ( wand->images == (Image *) NULL ) { - /* a "null:" output coder with no images is ok */ + /* a "null:" output coder with no images is not an error! */ if ( LocaleCompare(option,"null:") == 0 ) return; - MagickExceptionReturn(OptionError,"MissingAnImageFilename",option,i); + MagickExceptionReturn(OptionError,"NoImagesForFinalWrite",option,i); } - /* - Write out final image! - */ //WandListOperatorImages(wand,MagickFalse,"write",option,(const char *)NULL); (void) SyncImagesSettings(wand->image_info,wand->images,wand->exception); (void) WriteImages(wand->image_info,wand->images,option,wand->exception); @@ -346,9 +890,12 @@ WandExport void MagickCommandProcessOptions(MagickWand *wand,int argc, % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% MagickImageCommand() Handle special 'once only' CLI arguments and -% prepare to process the command line using a special CLI Magick Wand -% via the MagickImageProcess() function. +% MagickImageCommand() Handle special use CLI arguments and prepare a +% CLI MagickWand to process the command line or directly specified script. +% +% This is essentualy interface function between the MagickCore library +% initialization function MagickCommandGenesis(), and the option MagickWand +% processing functions ProcessCommandOptions() or ProcessScriptOptions() % % The format of the MagickImageCommand method is: % @@ -469,21 +1016,26 @@ WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info, return(MagickFalse); } } + /* The "magick" command must have at least two arguments */ if (argc < 3) return(MagickUsage()); ReadCommandlLine(argc,&argv); + #if 0 + /* FUTURE: This does not make sense! Remove it. + Only implied 'image read' needs to expand file name glob patterns + */ status=ExpandFilenames(&argc,&argv); if (status == MagickFalse) ThrowConvertException(ResourceLimitError,"MemoryAllocationFailed", GetExceptionMessage(errno)); #endif - /* Special hidden option for 'delegates' */ + /* Special hidden option for 'delegates' - no wand needed */ if (LocaleCompare("-concatenate",argv[1]) == 0) return(ConcatenateImages(argc,argv,exception)); - /* Create a special "CLI Wand" to hold images and settings */ + /* Initialize special "CLI Wand" to hold images and settings (empty) */ /* FUTURE: add this to 'operations.c' */ wand=NewMagickWand(); wand->image_info=DestroyImageInfo(wand->image_info); @@ -494,29 +1046,19 @@ WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info, wand->quantize_info=AcquireQuantizeInfo(image_info); if (LocaleCompare("-list",argv[1]) == 0) + /* Special option - list argument constants and other information */ + /* FUTURE - this really should be a direct MagickCore Function */ WandSettingOptionInfo(wand, argv[1]+1, argv[2]); -#if 0 else if (LocaleCompare("-script",argv[1]) == 0) { /* Start processing from script, no pre-script options */ - int - index; - - index=2; GetPathComponent(argv[2],TailPath,wand->name); - MagickScriptProcessOptions(wand,argc,argv,&index); + ProcessScriptOptions(wand,argc-2,argv+2); } -#endif else { /* Processing Command line, assuming output file as last option */ - int - index; - - index=1; - GetPathComponent(argv[0],TailPath,wand->name); - MagickCommandProcessOptions(wand,argc,argv, &index, - ProcessCommandOptions|ProcessOutputFile); + ProcessCommandOptions(wand,argc-1,argv+1,MagickCommandOptionFlags); } assert(wand->exception == exception); diff --git a/MagickWand/magick-cli.h b/MagickWand/magick-cli.h index 5b13ad320..9b862a0fb 100644 --- a/MagickWand/magick-cli.h +++ b/MagickWand/magick-cli.h @@ -25,25 +25,30 @@ extern "C" { typedef enum { /* What options should be processed */ - ProcessNonOptionImageRead = 0x0001, /* non-option is a image read */ - ProcessUnknownOptionError = 0x0002, /* unknown option produces error */ + /* NonOption Handling */ + ProcessNonOptionImageRead = 0x0001, /* non-option is a image read */ + ProcessUnknownOptionError = 0x0002, /* unknown option produces error */ - ProcessReadOption = 0x0010, /* allow '-read' to read images */ + /* Special Option Handling */ + ProcessExitOption = 0x0100, /* allow '-exit' use */ + ProcessScriptOption = 0x0200, /* allow '-script' use */ - ProcessListOption = 0x0040, /* Process Image List Operators */ + /* Option Processing Flags */ + ProcessOneOptionOnly = 0x4000, /* Process One Option Only */ + ProcessOutputFile = 0x8000, /* Process the output file */ - ProcessCommandOptions = 0x0FFF, /* Magick Command Flags */ + /* Flag Groups for specific Situations */ + MagickCommandOptionFlags = 0x8FFF, /* Magick Command Flags */ + MagickScriptArgsFlags = 0x00FF, /* Script Args Flags */ + MagickScriptReadFlags = 0x01FF /* Script Read Flags */ - /* Modify Option Handling */ - ProcessOutputFile = 0x1000, /* Process the output file */ - ProcessOneOptionOnly = 0x8000 /* Process One Option Only */ - -} OptionProcessFlags; +} ProcessOptionFlags; extern WandExport void - MagickSpecialOption(MagickWand *,const char *,const char *), - MagickCommandProcessOptions(MagickWand *,int,char **, - int *index, OptionProcessFlags flags); + ProcessSpecialOption(MagickWand *,const char *,const char *, + ProcessOptionFlags), + ProcessScriptOptions(MagickWand *,int,char **), + ProcessCommandOptions(MagickWand *,int,char **,ProcessOptionFlags); extern WandExport MagickBooleanType MagickImageCommand(ImageInfo *,int,char **,char **,ExceptionInfo *); diff --git a/config/english.xml b/config/english.xml index 4f7e32973..3f07612f4 100644 --- a/config/english.xml +++ b/config/english.xml @@ -859,6 +859,15 @@ missing an image filename + + script is binary + + + script token too big + + + script token with unbalanced quotes + unrecognized colormap type diff --git a/config/francais.xml b/config/francais.xml index 5ca75d491..0ecf5fa4c 100644 --- a/config/francais.xml +++ b/config/francais.xml @@ -841,11 +841,20 @@ + + image filename truncated + nom de fichier d'image absent - - image filename truncated + + de script en binaire + + + de script token trop gros + + + de script token avec des citations asymétriques type de table de couleurs non reconnnu -- 2.40.0