]> granicus.if.org Git - imagemagick/blob - MagickWand/wandcli.c
(no commit message)
[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-2014 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     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
93       GetExceptionMessage(errno));
94
95   /* Initialize Wand Part of MagickCLI
96      FUTURE: this is a repeat of code from NewMagickWand()
97      However some parts may be given fro man external source!
98   */
99   cli_wand->wand.id=AcquireWandId();
100   (void) FormatLocaleString(cli_wand->wand.name,MaxTextExtent,
101            "%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id);
102   cli_wand->wand.images=NewImageList();
103   if ( image_info == (ImageInfo *)NULL)
104     cli_wand->wand.image_info=AcquireImageInfo();
105   else
106     cli_wand->wand.image_info=image_info;
107   if ( exception == (ExceptionInfo *)NULL)
108     cli_wand->wand.exception=AcquireExceptionInfo();
109   else
110     cli_wand->wand.exception=exception;
111   cli_wand->wand.debug=IsEventLogging();
112   cli_wand->wand.signature=WandSignature;
113
114   /* Initialize CLI Part of MagickCLI */
115   cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL);
116   cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
117   cli_wand->process_flags=MagickCommandOptionFlags;  /* assume "magick" CLI */
118   cli_wand->command=(const OptionInfo *)NULL;     /* no option at this time */
119   cli_wand->image_list_stack=(Stack *)NULL;
120   cli_wand->image_info_stack=(Stack *)NULL;
121
122   /* default exception location...
123      EG: sprintf(locaiton, filename, line, column);
124   */
125   cli_wand->location="from \"%s\"";   /* location format using arguments: */
126                                       /*      filename, line, column */
127   cli_wand->filename="unknown";       /* script filename, unknown source */
128   cli_wand->line=0;                   /* line from script OR CLI argument */
129   cli_wand->column=0;                 /* column from script */
130
131   cli_wand->signature=WandSignature;
132   if (IfMagickTrue(cli_wand->wand.debug))
133     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
134   return(cli_wand);
135 }
136 \f
137 /*
138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139 %                                                                             %
140 %                                                                             %
141 %                                                                             %
142 +   D e s t r o y W a n d C L I                                               %
143 %                                                                             %
144 %                                                                             %
145 %                                                                             %
146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147 %
148 %  DestroyMagickCLI() destorys everything in a CLI wand, including image_info
149 %  and any exceptions, if still present in the wand.
150 %
151 %  The format of the NewMagickWand method is:
152 %
153 %    MagickWand *DestroyMagickCLI()
154 %            Exception *exception)
155 %
156 */
157 WandExport MagickCLI *DestroyMagickCLI(MagickCLI *cli_wand)
158 {
159   Stack
160     *node;
161
162   assert(cli_wand != (MagickCLI *) NULL);
163   assert(cli_wand->signature == WandSignature);
164   assert(cli_wand->wand.signature == WandSignature);
165   if (IfMagickTrue(cli_wand->wand.debug))
166     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
167
168   /* Destroy CLI part of MagickCLI */
169   if (cli_wand->draw_info != (DrawInfo *) NULL )
170     cli_wand->draw_info=DestroyDrawInfo(cli_wand->draw_info);
171   if (cli_wand->quantize_info != (QuantizeInfo *) NULL )
172     cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
173   while(cli_wand->image_list_stack != (Stack *)NULL)
174     {
175       node=cli_wand->image_list_stack;
176       cli_wand->image_list_stack=node->next;
177       (void) DestroyImageList((Image *)node->data);
178       (void) RelinquishMagickMemory(node);
179     }
180   while(cli_wand->image_info_stack != (Stack *)NULL)
181     {
182       node=cli_wand->image_info_stack;
183       cli_wand->image_info_stack=node->next;
184       (void) DestroyImageInfo((ImageInfo *)node->data);
185       (void) RelinquishMagickMemory(node);
186     }
187   cli_wand->signature=(~WandSignature);
188
189   /* Destroy Wand part MagickCLI */
190   cli_wand->wand.images=DestroyImageList(cli_wand->wand.images);
191   if (cli_wand->wand.image_info != (ImageInfo *) NULL )
192     cli_wand->wand.image_info=DestroyImageInfo(cli_wand->wand.image_info);
193   if (cli_wand->wand.exception != (ExceptionInfo *) NULL )
194     cli_wand->wand.exception=DestroyExceptionInfo(cli_wand->wand.exception);
195   RelinquishWandId(cli_wand->wand.id);
196   cli_wand->wand.signature=(~WandSignature);
197
198   return((MagickCLI *)NULL);
199 }
200 \f
201 /*
202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 %                                                                             %
204 %                                                                             %
205 %                                                                             %
206 +   C L I C a t c h E x c e p t i o n                                         %
207 %                                                                             %
208 %                                                                             %
209 %                                                                             %
210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
211 %
212 %  CLICatchException() will report exceptions, either just non-fatal warnings
213 %  only, or all errors, according to 'all_execeptions' boolean argument.
214 %
215 %  The function returns true if errors are fatal, in which case the caller
216 %  should abort and re-call with an 'all_exceptions' argument of true before
217 %  quitting.
218 %
219 %  The cut-off level between fatal and non-fatal may be controlled by options
220 %  (FUTURE), but defaults to 'Error' exceptions.
221 %
222 %  The format of the CLICatchException method is:
223 %
224 %    MagickBooleanType CLICatchException(MagickCLI *cli_wand,
225 %              const MagickBooleanType all_exceptions );
226 %
227 %  Arguments are
228 %
229 %    o cli_wand:   The Wand CLI that holds the exception Information
230 %
231 %    o all_exceptions:   Report all exceptions, including the fatal one
232 %
233 */
234 WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand,
235      const MagickBooleanType all_exceptions )
236 {
237   MagickBooleanType
238     status;
239   assert(cli_wand != (MagickCLI *) NULL);
240   assert(cli_wand->signature == WandSignature);
241   assert(cli_wand->wand.signature == WandSignature);
242   if (IfMagickTrue(cli_wand->wand.debug))
243     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
244
245   // FUTURE: '-regard_warning' should make this more sensitive.
246   // Note pipelined options may like more control over this level
247
248   status = IsMagickTrue(cli_wand->wand.exception->severity > ErrorException);
249
250   if ( IfMagickFalse(status) || IfMagickTrue(all_exceptions) )
251     CatchException(cli_wand->wand.exception); /* output and clear exceptions */
252
253   return(status);
254 }
255 \f
256 /*
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 %                                                                             %
259 %                                                                             %
260 %                                                                             %
261 +   C L I L o g E v e n t                                                     %
262 %                                                                             %
263 %                                                                             %
264 %                                                                             %
265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 %
267 % CLILogEvent() is a wrapper around LogMagickEvent(), adding to it the
268 % location of the option that is (about) to be executed.
269 %
270 */
271 WandExport MagickBooleanType CLILogEvent(MagickCLI *cli_wand,
272      const LogEventType type,const char *module,const char *function,
273      const size_t line,const char *format,...)
274 {
275   char
276     new_format[MaxTextExtent];
277
278   MagickBooleanType
279     status;
280
281   va_list
282     operands;
283
284   /* HACK - prepend the CLI location to format string.
285      The better way would be add more arguments to to the 'va' oparands
286      list, but that does not appear to be possible! So we do some
287      pre-formating of the location info here.
288   */
289   (void) FormatLocaleString(new_format,MaxTextExtent,cli_wand->location,
290        cli_wand->filename, cli_wand->line, cli_wand->column);
291   (void) ConcatenateMagickString(new_format," ",MaxTextExtent);
292   (void) ConcatenateMagickString(new_format,format,MaxTextExtent);
293
294   va_start(operands,format);
295   status=LogMagickEventList(type,module,function,line,new_format,operands);
296   va_end(operands);
297
298
299   return(status);
300 }
301 \f
302 /*
303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
304 %                                                                             %
305 %                                                                             %
306 %                                                                             %
307 +   C L I T h r o w E x c e p t i o n                                         %
308 %                                                                             %
309 %                                                                             %
310 %                                                                             %
311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
312 %
313 % CLIThrowException() is a wrapper around ThrowMagickException(), adding to
314 % it the location of the option that caused the exception to occur.
315 */
316 WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand,
317        const char *module,const char *function,const size_t line,
318        const ExceptionType severity,const char *tag,const char *format,...)
319 {
320   char
321     new_format[MaxTextExtent];
322
323   size_t
324     len;
325
326   MagickBooleanType
327     status;
328
329   va_list
330     operands;
331
332   /* HACK - append location to format string.
333      The better way would be add more arguments to to the 'va' oparands
334      list, but that does not appear to be possible! So we do some
335      pre-formating of the location info here.
336   */
337   (void) CopyMagickString(new_format,format,MaxTextExtent);
338   (void) ConcatenateMagickString(new_format," ",MaxTextExtent);
339
340   len=strlen(new_format);
341   (void) FormatLocaleString(new_format+len,MaxTextExtent-len,cli_wand->location,
342        cli_wand->filename, cli_wand->line, cli_wand->column);
343
344   va_start(operands,format);
345   status=ThrowMagickExceptionList(cli_wand->wand.exception,
346               module,function,line,
347               severity,tag,new_format,operands);
348   va_end(operands);
349   return(status);
350 }