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

Revision 7587, 13.3 KB checked in by anthony, 13 months ago (diff)

Refactoring option handling.

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-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
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 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*/
273WandExport 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}
Note: See TracBrowser for help on using the repository browser.