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