source: ImageMagick/trunk/MagickWand/wandcli.c @ 12017

Revision 12017, 15.0 KB checked in by anthony, 7 weeks ago (diff)

Use of set and escapes while no images in memory!
(does not include %[fx:...] and %[pixel:...] yet.

Line 
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
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
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*/
75WandExport 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
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*/
160WandExport 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
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*/
237WandExport 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
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*/
274WandExport 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
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*/
319WandExport 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}
Note: See TracBrowser for help on using the repository browser.