]> granicus.if.org Git - imagemagick/blob - MagickWand/wandcli.c
414fc75cd310b22adb776e04caaa5ca5262f7781
[imagemagick] / MagickWand / wandcli.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %     M   M  AA   GGG  III  CCC     W     W  AA  N   N DDD   CCC L    III     %
7 %     MM MM A  A G      I  C        W     W A  A NN  N D  D C    L     I      %
8 %     M M M AAAA G  GG  I  C        W  W  W AAAA N N N D  D C    L     I      %
9 %     M   M A  A G   G  I  C         W W W  A  A N  NN D  D C    L     I      %
10 %     M   M A  A  GGG  III  CCC       W W   A  A N   N DDD   CCC LLLL III     %
11 %                                                                             %
12 %                                                                             %
13 %                         WandCLI Structure Methods                           %
14 %                                                                             %
15 %                              Dragon Computing                               %
16 %                              Anthony Thyssen                                %
17 %                                 April 2011                                  %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    http://www.imagemagick.org/script/license.php                            %
27 %                                                                             %
28 %  Unless required by applicable law or agreed to in writing, software        %
29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31 %  See the License for the specific language governing permissions and        %
32 %  limitations under the License.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 % General methds for handling the WandCLI structure used for Command Line.
37 %
38 % Anthony Thyssen, April 2011
39 */
40 \f
41 /*
42   Include declarations.
43 */
44 #include "MagickWand/studio.h"
45 #include "MagickWand/MagickWand.h"
46 #include "MagickWand/wand.h"
47 #include "MagickWand/magick-wand-private.h"
48 #include "MagickWand/wandcli.h"
49 #include "MagickWand/wandcli-private.h"
50 #include "MagickCore/exception.h"
51 \f
52 /*
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54 %                                                                             %
55 %                                                                             %
56 %                                                                             %
57 +   A c q u i r e W a n d C L I                                               %
58 %                                                                             %
59 %                                                                             %
60 %                                                                             %
61 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62 %
63 %  AcquireMagickCLI() creates a new CLI wand (an expanded form of Magick
64 %  Wand). The given image_info and exception is included as is if provided.
65 %
66 %  Use DestroyMagickCLI() to dispose of the CLI wand when it is no longer
67 %  needed.
68 %
69 %  The format of the NewMagickWand method is:
70 %
71 %      MagickCLI *AcquireMagickCLI(ImageInfo *image_info,
72 %           ExceptionInfo *exception)
73 %
74 */
75 WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info,
76     ExceptionInfo *exception)
77 {
78   MagickCLI
79     *cli_wand;
80
81   /* precaution - as per NewMagickWand() */
82   {
83      size_t depth = MAGICKCORE_QUANTUM_DEPTH;
84      const char *quantum = GetMagickQuantumDepth(&depth);
85      if (depth != MAGICKCORE_QUANTUM_DEPTH)
86        ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
87   }
88
89   /* allocate memory for MgaickCLI */
90   cli_wand=(MagickCLI *) AcquireMagickMemory(sizeof(*cli_wand));
91   if (cli_wand == (MagickCLI *) NULL)
92     {
93       ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
94         GetExceptionMessage(errno));
95       return((MagickCLI *)NULL);
96     }
97
98   /* Initialize Wand Part of MagickCLI
99      FUTURE: this is a repeat of code from NewMagickWand()
100      However some parts may be given fro man external source!
101   */
102   cli_wand->wand.id=AcquireWandId();
103   (void) FormatLocaleString(cli_wand->wand.name,MaxTextExtent,
104            "%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id);
105   cli_wand->wand.images=NewImageList();
106   if ( image_info == (ImageInfo *)NULL)
107     cli_wand->wand.image_info=AcquireImageInfo();
108   else
109     cli_wand->wand.image_info=image_info;
110   if ( exception == (ExceptionInfo *)NULL)
111     cli_wand->wand.exception=AcquireExceptionInfo();
112   else
113     cli_wand->wand.exception=exception;
114   cli_wand->wand.debug=IsEventLogging();
115   cli_wand->wand.signature=WandSignature;
116
117   /* Initialize CLI Part of MagickCLI */
118   cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL);
119   cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
120   cli_wand->process_flags=MagickCommandOptionFlags;  /* assume "magick" CLI */
121   cli_wand->command=(const OptionInfo *)NULL;     /* no option at this time */
122   cli_wand->image_list_stack=(Stack *)NULL;
123   cli_wand->image_info_stack=(Stack *)NULL;
124
125   /* default exception location...
126      EG: sprintf(locaiton, filename, line, column);
127   */
128   cli_wand->location="from \"%s\"";   /* location format using arguments: */
129                                       /*      filename, line, column */
130   cli_wand->filename="unknown";       /* script filename, unknown source */
131   cli_wand->line=0;                   /* line from script OR CLI argument */
132   cli_wand->column=0;                 /* column from script */
133
134   cli_wand->signature=WandSignature;
135   if (IfMagickTrue(cli_wand->wand.debug))
136     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
137   return(cli_wand);
138 }
139 \f
140 /*
141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142 %                                                                             %
143 %                                                                             %
144 %                                                                             %
145 +   D e s t r o y W a n d C L I                                               %
146 %                                                                             %
147 %                                                                             %
148 %                                                                             %
149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150 %
151 %  DestroyMagickCLI() destorys everything in a CLI wand, including image_info
152 %  and any exceptions, if still present in the wand.
153 %
154 %  The format of the NewMagickWand method is:
155 %
156 %    MagickWand *DestroyMagickCLI()
157 %            Exception *exception)
158 %
159 */
160 WandExport MagickCLI *DestroyMagickCLI(MagickCLI *cli_wand)
161 {
162   Stack
163     *node;
164
165   assert(cli_wand != (MagickCLI *) NULL);
166   assert(cli_wand->signature == WandSignature);
167   assert(cli_wand->wand.signature == WandSignature);
168   if (IfMagickTrue(cli_wand->wand.debug))
169     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
170
171   /* Destroy CLI part of MagickCLI */
172   if (cli_wand->draw_info != (DrawInfo *) NULL )
173     cli_wand->draw_info=DestroyDrawInfo(cli_wand->draw_info);
174   if (cli_wand->quantize_info != (QuantizeInfo *) NULL )
175     cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
176   while(cli_wand->image_list_stack != (Stack *)NULL)
177     {
178       node=cli_wand->image_list_stack;
179       cli_wand->image_list_stack=node->next;
180       (void) DestroyImageList((Image *)node->data);
181       (void) RelinquishMagickMemory(node);
182     }
183   while(cli_wand->image_info_stack != (Stack *)NULL)
184     {
185       node=cli_wand->image_info_stack;
186       cli_wand->image_info_stack=node->next;
187       (void) DestroyImageInfo((ImageInfo *)node->data);
188       (void) RelinquishMagickMemory(node);
189     }
190   cli_wand->signature=(~WandSignature);
191
192   /* Destroy Wand part MagickCLI */
193   cli_wand->wand.images=DestroyImageList(cli_wand->wand.images);
194   if (cli_wand->wand.image_info != (ImageInfo *) NULL )
195     cli_wand->wand.image_info=DestroyImageInfo(cli_wand->wand.image_info);
196   if (cli_wand->wand.exception != (ExceptionInfo *) NULL )
197     cli_wand->wand.exception=DestroyExceptionInfo(cli_wand->wand.exception);
198   RelinquishWandId(cli_wand->wand.id);
199   cli_wand->wand.signature=(~WandSignature);
200
201   return((MagickCLI *)NULL);
202 }
203 \f
204 /*
205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
206 %                                                                             %
207 %                                                                             %
208 %                                                                             %
209 +   C L I C a t c h E x c e p t i o n                                         %
210 %                                                                             %
211 %                                                                             %
212 %                                                                             %
213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214 %
215 %  CLICatchException() will report exceptions, either just non-fatal warnings
216 %  only, or all errors, according to 'all_execeptions' boolean argument.
217 %
218 %  The function returns true if errors are fatal, in which case the caller
219 %  should abort and re-call with an 'all_exceptions' argument of true before
220 %  quitting.
221 %
222 %  The cut-off level between fatal and non-fatal may be controlled by options
223 %  (FUTURE), but defaults to 'Error' exceptions.
224 %
225 %  The format of the CLICatchException method is:
226 %
227 %    MagickBooleanType CLICatchException(MagickCLI *cli_wand,
228 %              const MagickBooleanType all_exceptions );
229 %
230 %  Arguments are
231 %
232 %    o cli_wand:   The Wand CLI that holds the exception Information
233 %
234 %    o all_exceptions:   Report all exceptions, including the fatal one
235 %
236 */
237 WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand,
238      const MagickBooleanType all_exceptions )
239 {
240   MagickBooleanType
241     status;
242   assert(cli_wand != (MagickCLI *) NULL);
243   assert(cli_wand->signature == WandSignature);
244   assert(cli_wand->wand.signature == WandSignature);
245   if (IfMagickTrue(cli_wand->wand.debug))
246     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
247
248   // FUTURE: '-regard_warning' should make this more sensitive.
249   // Note pipelined options may like more control over this level
250
251   status = IsMagickTrue(cli_wand->wand.exception->severity > ErrorException);
252
253   if ( IfMagickFalse(status) || IfMagickTrue(all_exceptions) )
254     CatchException(cli_wand->wand.exception); /* output and clear exceptions */
255
256   return(status);
257 }
258 \f
259 /*
260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261 %                                                                             %
262 %                                                                             %
263 %                                                                             %
264 +   C L I T h r o w E x c e p t i o n                                         %
265 %                                                                             %
266 %                                                                             %
267 %                                                                             %
268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269 %
270 % CLIThrowException() formats and records an exception condition, adding to
271 % it the location of the option that caused the exception to occur.
272 */
273 WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand,
274        const char *module,const char *function,const size_t line,
275        const ExceptionType severity,const char *tag,const char *format,...)
276 {
277   char
278     new_format[MaxTextExtent];
279
280   size_t
281     len;
282
283   MagickBooleanType
284     status;
285
286   va_list
287     operands;
288
289   /* HACK - append location to format string.
290      The better way would be append location formats and add more arguments to
291      operands, but that does not appear to be posible!
292      Note:  ThrowMagickExceptionList() was exported specifically for
293      the use of this function.
294   */
295   (void) CopyMagickString(new_format,format,MaxTextExtent);
296   (void) ConcatenateMagickString(new_format," ",MaxTextExtent);
297
298   len=strlen(new_format);
299   (void) FormatLocaleString(new_format+len,MaxTextExtent-len,cli_wand->location,
300        cli_wand->filename, cli_wand->line, cli_wand->column);
301
302   va_start(operands,format);
303   status=ThrowMagickExceptionList(cli_wand->wand.exception,
304               module,function,line,
305               severity,tag,new_format,operands);
306   va_end(operands);
307   return(status);
308 }