]> granicus.if.org Git - imagemagick/blob - MagickWand/wandcli.c
Use of set and escapes while no images in memory!
[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-2013 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 L o g E v e n t                                                     %
265 %                                                                             %
266 %                                                                             %
267 %                                                                             %
268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269 %
270 % CLILogEvent() is a wrapper around LogMagickEvent(), adding to it the
271 % location of the option that is (about) to be executed.
272 %
273 */
274 WandExport MagickBooleanType CLILogEvent(MagickCLI *cli_wand,
275      const LogEventType type,const char *module,const char *function,
276      const size_t line,const char *format,...)
277 {
278   char
279     new_format[MaxTextExtent];
280
281   MagickBooleanType
282     status;
283
284   va_list
285     operands;
286
287   /* HACK - prepend the CLI location to format string.
288      The better way would be add more arguments to to the 'va' oparands
289      list, but that does not appear to be possible! So we do some
290      pre-formating of the location info here.
291   */
292   (void) FormatLocaleString(new_format,MaxTextExtent,cli_wand->location,
293        cli_wand->filename, cli_wand->line, cli_wand->column);
294   (void) ConcatenateMagickString(new_format," ",MaxTextExtent);
295   (void) ConcatenateMagickString(new_format,format,MaxTextExtent);
296
297   va_start(operands,format);
298   status=LogMagickEventList(type,module,function,line,new_format,operands);
299   va_end(operands);
300
301
302   return(status);
303 }
304 \f
305 /*
306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
307 %                                                                             %
308 %                                                                             %
309 %                                                                             %
310 +   C L I T h r o w E x c e p t i o n                                         %
311 %                                                                             %
312 %                                                                             %
313 %                                                                             %
314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
315 %
316 % CLIThrowException() is a wrapper around ThrowMagickException(), adding to
317 % it the location of the option that caused the exception to occur.
318 */
319 WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand,
320        const char *module,const char *function,const size_t line,
321        const ExceptionType severity,const char *tag,const char *format,...)
322 {
323   char
324     new_format[MaxTextExtent];
325
326   size_t
327     len;
328
329   MagickBooleanType
330     status;
331
332   va_list
333     operands;
334
335   /* HACK - append location to format string.
336      The better way would be add more arguments to to the 'va' oparands
337      list, but that does not appear to be possible! So we do some
338      pre-formating of the location info here.
339   */
340   (void) CopyMagickString(new_format,format,MaxTextExtent);
341   (void) ConcatenateMagickString(new_format," ",MaxTextExtent);
342
343   len=strlen(new_format);
344   (void) FormatLocaleString(new_format+len,MaxTextExtent-len,cli_wand->location,
345        cli_wand->filename, cli_wand->line, cli_wand->column);
346
347   va_start(operands,format);
348   status=ThrowMagickExceptionList(cli_wand->wand.exception,
349               module,function,line,
350               severity,tag,new_format,operands);
351   va_end(operands);
352   return(status);
353 }