blob: a3f10e3ad1a1c918f32cfef54b066bd13acd65be [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% CCCC OOO N N FFFFF IIIII GGGG U U RRRR EEEEE %
7% C O O NN N F I G U U R R E %
8% C O O N N N FFF I G GG U U RRRR EEE %
9% C O O N NN F I G G U U R R E %
10% CCCC OOO N N F IIIII GGG UUU R R EEEEE %
11% %
12% %
13% MagickCore Image Configure Methods %
14% %
15% Software Design %
cristyde984cd2013-12-01 14:49:27 +000016% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000017% July 2003 %
18% %
19% %
cristyfe676ee2013-11-18 13:03:38 +000020% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% 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%
37*/
38
39/*
40 Include declarations.
41*/
cristy4c08aed2011-07-01 19:47:50 +000042#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/client.h"
45#include "MagickCore/configure.h"
cristy5ff4eaf2011-09-03 01:38:02 +000046#include "MagickCore/configure-private.h"
cristy4c08aed2011-07-01 19:47:50 +000047#include "MagickCore/exception.h"
48#include "MagickCore/exception-private.h"
49#include "MagickCore/hashmap.h"
50#include "MagickCore/log.h"
51#include "MagickCore/memory_.h"
52#include "MagickCore/semaphore.h"
53#include "MagickCore/string_.h"
cristy7832dc22011-09-05 01:21:53 +000054#include "MagickCore/string-private.h"
cristy4c08aed2011-07-01 19:47:50 +000055#include "MagickCore/token.h"
56#include "MagickCore/utility.h"
cristyd1dd6e42011-09-04 01:46:08 +000057#include "MagickCore/utility-private.h"
cristy4c08aed2011-07-01 19:47:50 +000058#include "MagickCore/xml-tree.h"
cristy3291f512014-03-16 22:16:22 +000059#include "MagickCore/xml-tree-private.h"
cristy3ed852e2009-09-05 21:47:34 +000060
61/*
62 Define declarations.
63*/
64#define ConfigureFilename "configure.xml"
cristy154f9fa2012-12-05 19:30:42 +000065
66#ifdef _OPENMP
67#define MAGICKCORE_FEATURE_OPENMP_STR "OpenMP "
68#else
69#define MAGICKCORE_FEATURE_OPENMP_STR ""
70#endif
71#ifdef _OPENCL
72#define MAGICKCORE_FEATURE_OPENCL_STR "OpenCL "
73#else
74#define MAGICKCORE_FEATURE_OPENCL_STR ""
75#endif
76#ifdef MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
77#define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR "Zero-Configuration "
78#else
79#define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR ""
80#endif
81#ifdef HDRI_SUPPORT
82#define MAGICKCORE_FEATURE_HDRI_STR "HDRI"
83#else
84#define MAGICKCORE_FEATURE_HDRI_STR ""
85#endif
86
87#define MAGICKCORE_FEATURES_STR MAGICKCORE_FEATURE_OPENMP_STR MAGICKCORE_FEATURE_OPENCL_STR MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR MAGICKCORE_FEATURE_HDRI_STR
cristy3ed852e2009-09-05 21:47:34 +000088
89/*
cristy54a531d2009-10-21 17:58:01 +000090 Typedef declarations.
91*/
92typedef struct _ConfigureMapInfo
93{
94 const char
95 *name,
96 *value;
97} ConfigureMapInfo;
98
99/*
cristy3ed852e2009-09-05 21:47:34 +0000100 Static declarations.
101*/
cristy54a531d2009-10-21 17:58:01 +0000102static const ConfigureMapInfo
103 ConfigureMap[] =
104 {
cristy154f9fa2012-12-05 19:30:42 +0000105 { "NAME", "ImageMagick" },
106 { "QuantumDepth", MAGICKCORE_STRING_XQUOTE(MAGICKCORE_QUANTUM_DEPTH) } ,
cristybb017a02012-12-07 00:43:45 +0000107 { "FEATURES", MAGICKCORE_FEATURES_STR }
cristy54a531d2009-10-21 17:58:01 +0000108 };
cristy3ed852e2009-09-05 21:47:34 +0000109
110static LinkedListInfo
cristy86e5ac92014-03-16 19:27:39 +0000111 *configure_cache = (LinkedListInfo *) NULL;
cristy3ed852e2009-09-05 21:47:34 +0000112
113static SemaphoreInfo
114 *configure_semaphore = (SemaphoreInfo *) NULL;
cristy3ed852e2009-09-05 21:47:34 +0000115
116/*
117 Forward declarations.
118*/
119static MagickBooleanType
cristy86e5ac92014-03-16 19:27:39 +0000120 IsConfigureCacheInstantiated(ExceptionInfo *),
cristycd2cd182014-03-18 12:10:55 +0000121 LoadConfigureCache(LinkedListInfo *,const char *,const char *,const size_t,
122 ExceptionInfo *);
cristy86e5ac92014-03-16 19:27:39 +0000123
124/*
125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126% %
127% %
128% %
129% A c q u i r e C o n f i g u r e C a c h e %
130% %
131% %
132% %
133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134%
cristycd2cd182014-03-18 12:10:55 +0000135% AcquireConfigureCache() caches one or more configure configurations which
cristy86e5ac92014-03-16 19:27:39 +0000136% provides a mapping between configure attributes and a configure name.
137%
138% The format of the AcquireConfigureCache method is:
139%
140% LinkedListInfo *AcquireConfigureCache(const char *filename,
141% ExceptionInfo *exception)
142%
143% A description of each parameter follows:
144%
145% o filename: the font file name.
146%
147% o exception: return any errors or warnings in this structure.
148%
149*/
150static LinkedListInfo *AcquireConfigureCache(const char *filename,
151 ExceptionInfo *exception)
152{
153 const StringInfo
154 *option;
155
156 LinkedListInfo
157 *configure_cache,
158 *options;
159
160 MagickStatusType
161 status;
162
163 register ssize_t
164 i;
165
166 /*
167 Load external configure map.
168 */
169 configure_cache=NewLinkedList(0);
170 if (configure_cache == (LinkedListInfo *) NULL)
171 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
172 status=MagickTrue;
173 options=GetConfigureOptions(filename,exception);
174 option=(const StringInfo *) GetNextValueInLinkedList(options);
175 while (option != (const StringInfo *) NULL)
176 {
cristycd2cd182014-03-18 12:10:55 +0000177 status&=LoadConfigureCache(configure_cache,(const char *)
178 GetStringInfoDatum(option),GetStringInfoPath(option),0,exception);
cristy86e5ac92014-03-16 19:27:39 +0000179 option=(const StringInfo *) GetNextValueInLinkedList(options);
180 }
181 options=DestroyConfigureOptions(options);
182 /*
183 Load built-in configure map.
184 */
185 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
186 {
187 ConfigureInfo
188 *configure_info;
189
190 register const ConfigureMapInfo
191 *p;
192
193 p=ConfigureMap+i;
194 configure_info=(ConfigureInfo *) AcquireMagickMemory(
195 sizeof(*configure_info));
196 if (configure_info == (ConfigureInfo *) NULL)
197 {
198 (void) ThrowMagickException(exception,GetMagickModule(),
199 ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
200 continue;
201 }
202 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
203 configure_info->path=(char *) "[built-in]";
204 configure_info->name=(char *) p->name;
205 configure_info->value=(char *) p->value;
206 configure_info->exempt=MagickTrue;
207 configure_info->signature=MagickSignature;
208 status&=AppendValueToLinkedList(configure_cache,configure_info);
209 if (status == MagickFalse)
210 (void) ThrowMagickException(exception,GetMagickModule(),
211 ResourceLimitError,"MemoryAllocationFailed","`%s'",
212 configure_info->name);
213 }
214 return(configure_cache);
215}
cristy3ed852e2009-09-05 21:47:34 +0000216
217/*
218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219% %
220% %
221% %
cristyf34a1452009-10-24 22:29:27 +0000222+ C o n f i g u r e C o m p o n e n t G e n e s i s %
cristy3ed852e2009-09-05 21:47:34 +0000223% %
224% %
225% %
226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227%
cristyf34a1452009-10-24 22:29:27 +0000228% ConfigureComponentGenesis() instantiates the configure component.
cristy3ed852e2009-09-05 21:47:34 +0000229%
cristyf34a1452009-10-24 22:29:27 +0000230% The format of the ConfigureComponentGenesis method is:
cristy3ed852e2009-09-05 21:47:34 +0000231%
cristyf34a1452009-10-24 22:29:27 +0000232% MagickBooleanType ConfigureComponentGenesis(void)
233%
234*/
cristy5ff4eaf2011-09-03 01:38:02 +0000235MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +0000236{
cristy7c977062014-04-04 14:05:53 +0000237 if (configure_semaphore == (SemaphoreInfo *) NULL)
238 configure_semaphore=AcquireSemaphoreInfo();
cristyf34a1452009-10-24 22:29:27 +0000239 return(MagickTrue);
240}
241
242/*
243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244% %
245% %
246% %
247+ C o n f i g u r e C o m p o n e n t T e r m i n u s %
248% %
249% %
250% %
251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252%
253% ConfigureComponentTerminus() destroys the configure component.
254%
255% The format of the ConfigureComponentTerminus method is:
256%
257% ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000258%
259*/
260
261static void *DestroyConfigureElement(void *configure_info)
262{
263 register ConfigureInfo
264 *p;
265
266 p=(ConfigureInfo *) configure_info;
cristy54a531d2009-10-21 17:58:01 +0000267 if (p->exempt == MagickFalse)
268 {
269 if (p->value != (char *) NULL)
270 p->value=DestroyString(p->value);
271 if (p->name != (char *) NULL)
272 p->name=DestroyString(p->name);
273 if (p->path != (char *) NULL)
274 p->path=DestroyString(p->path);
275 }
cristy3ed852e2009-09-05 21:47:34 +0000276 p=(ConfigureInfo *) RelinquishMagickMemory(p);
277 return((void *) NULL);
278}
279
cristy5ff4eaf2011-09-03 01:38:02 +0000280MagickPrivate void ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000281{
cristy18b17442009-10-25 18:36:48 +0000282 if (configure_semaphore == (SemaphoreInfo *) NULL)
cristy04b11db2014-02-16 15:10:39 +0000283 ActivateSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000284 LockSemaphoreInfo(configure_semaphore);
cristy86e5ac92014-03-16 19:27:39 +0000285 if (configure_cache != (LinkedListInfo *) NULL)
286 configure_cache=DestroyLinkedList(configure_cache,DestroyConfigureElement);
287 configure_cache=(LinkedListInfo *) NULL;
cristyf84a1932010-01-03 18:00:18 +0000288 UnlockSemaphoreInfo(configure_semaphore);
cristy3d162a92014-02-16 14:05:06 +0000289 RelinquishSemaphoreInfo(&configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000290}
291
292/*
293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294% %
295% %
296% %
297% D e s t r o y C o n f i g u r e O p t i o n s %
298% %
299% %
300% %
301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302%
303% DestroyConfigureOptions() releases memory associated with an configure
304% options.
305%
306% The format of the DestroyProfiles method is:
307%
308% LinkedListInfo *DestroyConfigureOptions(Image *image)
309%
310% A description of each parameter follows:
311%
312% o image: the image.
313%
314*/
315
316static void *DestroyOptions(void *option)
317{
318 return(DestroyStringInfo((StringInfo *) option));
319}
320
321MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
322{
323 assert(options != (LinkedListInfo *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000324 return(DestroyLinkedList(options,DestroyOptions));
325}
326
327/*
328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329% %
330% %
331% %
332+ G e t C o n f i g u r e I n f o %
333% %
334% %
335% %
336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337%
338% GetConfigureInfo() searches the configure list for the specified name and if
339% found returns attributes for that element.
340%
341% The format of the GetConfigureInfo method is:
342%
343% const ConfigureInfo *GetConfigureInfo(const char *name,
344% ExceptionInfo *exception)
345%
346% A description of each parameter follows:
347%
348% o configure_info: GetConfigureInfo() searches the configure list for the
349% specified name and if found returns attributes for that element.
350%
351% o name: the configure name.
352%
353% o exception: return any errors or warnings in this structure.
354%
355*/
356MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
357 ExceptionInfo *exception)
358{
359 register const ConfigureInfo
360 *p;
361
362 assert(exception != (ExceptionInfo *) NULL);
cristy86e5ac92014-03-16 19:27:39 +0000363 if (IsConfigureCacheInstantiated(exception) == MagickFalse)
cristy904e5912014-03-15 19:53:14 +0000364 return((const ConfigureInfo *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000365 /*
366 Search for configure tag.
367 */
cristyf84a1932010-01-03 18:00:18 +0000368 LockSemaphoreInfo(configure_semaphore);
cristy86e5ac92014-03-16 19:27:39 +0000369 ResetLinkedListIterator(configure_cache);
370 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
cristy49d4d222014-03-16 00:37:58 +0000371 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
372 {
373 UnlockSemaphoreInfo(configure_semaphore);
374 return(p);
375 }
cristy3ed852e2009-09-05 21:47:34 +0000376 while (p != (const ConfigureInfo *) NULL)
377 {
378 if (LocaleCompare(name,p->name) == 0)
379 break;
cristy86e5ac92014-03-16 19:27:39 +0000380 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
cristy3ed852e2009-09-05 21:47:34 +0000381 }
382 if (p != (ConfigureInfo *) NULL)
cristy86e5ac92014-03-16 19:27:39 +0000383 (void) InsertValueInLinkedList(configure_cache,0,
384 RemoveElementByValueFromLinkedList(configure_cache,p));
cristyf84a1932010-01-03 18:00:18 +0000385 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000386 return(p);
387}
388
389/*
390%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391% %
392% %
393% %
394% G e t C o n f i g u r e I n f o L i s t %
395% %
396% %
397% %
398%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399%
400% GetConfigureInfoList() returns any configure options that match the
401% specified pattern.
402%
403% The format of the GetConfigureInfoList function is:
404%
405% const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000406% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000407%
408% A description of each parameter follows:
409%
410% o pattern: Specifies a pointer to a text string containing a pattern.
411%
412% o number_options: This integer returns the number of configure options in
413% the list.
414%
415% o exception: return any errors or warnings in this structure.
416%
417*/
418
419#if defined(__cplusplus) || defined(c_plusplus)
420extern "C" {
421#endif
422
423static int ConfigureInfoCompare(const void *x,const void *y)
424{
425 const ConfigureInfo
426 **p,
427 **q;
428
429 p=(const ConfigureInfo **) x,
430 q=(const ConfigureInfo **) y;
431 if (LocaleCompare((*p)->path,(*q)->path) == 0)
432 return(LocaleCompare((*p)->name,(*q)->name));
433 return(LocaleCompare((*p)->path,(*q)->path));
434}
435
436#if defined(__cplusplus) || defined(c_plusplus)
437}
438#endif
439
440MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000441 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000442{
443 const ConfigureInfo
444 **options;
445
446 register const ConfigureInfo
447 *p;
448
cristybb503372010-05-27 20:51:26 +0000449 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000450 i;
451
452 /*
453 Allocate configure list.
454 */
455 assert(pattern != (char *) NULL);
456 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000457 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000458 *number_options=0;
459 p=GetConfigureInfo("*",exception);
460 if (p == (const ConfigureInfo *) NULL)
461 return((const ConfigureInfo **) NULL);
462 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
cristy86e5ac92014-03-16 19:27:39 +0000463 GetNumberOfElementsInLinkedList(configure_cache)+1UL,sizeof(*options));
cristy3ed852e2009-09-05 21:47:34 +0000464 if (options == (const ConfigureInfo **) NULL)
465 return((const ConfigureInfo **) NULL);
466 /*
467 Generate configure list.
468 */
cristyf84a1932010-01-03 18:00:18 +0000469 LockSemaphoreInfo(configure_semaphore);
cristy86e5ac92014-03-16 19:27:39 +0000470 ResetLinkedListIterator(configure_cache);
471 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
cristy3ed852e2009-09-05 21:47:34 +0000472 for (i=0; p != (const ConfigureInfo *) NULL; )
473 {
474 if ((p->stealth == MagickFalse) &&
475 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
476 options[i++]=p;
cristy86e5ac92014-03-16 19:27:39 +0000477 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
cristy3ed852e2009-09-05 21:47:34 +0000478 }
cristyf84a1932010-01-03 18:00:18 +0000479 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000480 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
481 options[i]=(ConfigureInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000482 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000483 return(options);
484}
485
486/*
487%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488% %
489% %
490% %
491% G e t C o n f i g u r e L i s t %
492% %
493% %
494% %
495%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496%
497% GetConfigureList() returns any configure options that match the specified
498% pattern.
499%
500% The format of the GetConfigureList function is:
501%
502% char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000503% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000504%
505% A description of each parameter follows:
506%
507% o pattern: Specifies a pointer to a text string containing a pattern.
508%
509% o number_options: This integer returns the number of options in the list.
510%
511% o exception: return any errors or warnings in this structure.
512%
513*/
514
515#if defined(__cplusplus) || defined(c_plusplus)
516extern "C" {
517#endif
518
519static int ConfigureCompare(const void *x,const void *y)
520{
521 register char
522 **p,
523 **q;
524
525 p=(char **) x;
526 q=(char **) y;
527 return(LocaleCompare(*p,*q));
528}
529
530#if defined(__cplusplus) || defined(c_plusplus)
531}
532#endif
533
534MagickExport char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000535 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000536{
537 char
538 **options;
539
540 register const ConfigureInfo
541 *p;
542
cristybb503372010-05-27 20:51:26 +0000543 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000544 i;
545
546 /*
547 Allocate configure list.
548 */
549 assert(pattern != (char *) NULL);
550 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000551 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000552 *number_options=0;
553 p=GetConfigureInfo("*",exception);
554 if (p == (const ConfigureInfo *) NULL)
555 return((char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000556 options=(char **) AcquireQuantumMemory((size_t)
cristy86e5ac92014-03-16 19:27:39 +0000557 GetNumberOfElementsInLinkedList(configure_cache)+1UL,sizeof(*options));
cristy3ed852e2009-09-05 21:47:34 +0000558 if (options == (char **) NULL)
559 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000560 LockSemaphoreInfo(configure_semaphore);
cristy86e5ac92014-03-16 19:27:39 +0000561 ResetLinkedListIterator(configure_cache);
562 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
cristy3ed852e2009-09-05 21:47:34 +0000563 for (i=0; p != (const ConfigureInfo *) NULL; )
564 {
565 if ((p->stealth == MagickFalse) &&
566 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
567 options[i++]=ConstantString(p->name);
cristy86e5ac92014-03-16 19:27:39 +0000568 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
cristy3ed852e2009-09-05 21:47:34 +0000569 }
cristyf84a1932010-01-03 18:00:18 +0000570 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000571 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
572 options[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000573 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000574 return(options);
575}
576
577/*
578%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
579% %
580% %
581% %
582% G e t C o n f i g u r e O p t i o n %
583% %
584% %
585% %
586%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587%
588% GetConfigureOption() returns the value associated with the configure option.
589%
590% The format of the GetConfigureOption method is:
591%
592% char *GetConfigureOption(const char *option)
593%
594% A description of each parameter follows:
595%
596% o configure_info: The configure info.
597%
598*/
599MagickExport char *GetConfigureOption(const char *option)
600{
601 const char
602 *value;
603
604 const ConfigureInfo
605 *configure_info;
606
607 ExceptionInfo
608 *exception;
609
610 assert(option != (const char *) NULL);
611 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
612 exception=AcquireExceptionInfo();
613 configure_info=GetConfigureInfo(option,exception);
614 exception=DestroyExceptionInfo(exception);
615 if (configure_info == (ConfigureInfo *) NULL)
616 return((char *) NULL);
617 value=GetConfigureValue(configure_info);
618 if ((value == (const char *) NULL) || (*value == '\0'))
619 return((char *) NULL);
620 return(ConstantString(value));
621}
622
623/*
624%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
625% %
626% %
627% %
628% G e t C o n f i g u r e O p t i o n s %
629% %
630% %
631% %
632%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633%
634% GetConfigureOptions() returns any Magick configuration options associated
635% with the specified filename.
636%
637% The format of the GetConfigureOptions method is:
638%
639% LinkedListInfo *GetConfigureOptions(const char *filename,
640% ExceptionInfo *exception)
641%
642% A description of each parameter follows:
643%
644% o filename: the configure file name.
645%
646% o exception: return any errors or warnings in this structure.
647%
648*/
649MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
650 ExceptionInfo *exception)
651{
652 char
653 path[MaxTextExtent];
654
655 const char
656 *element;
657
658 LinkedListInfo
659 *options,
660 *paths;
661
662 StringInfo
663 *xml;
664
665 assert(filename != (const char *) NULL);
666 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
667 assert(exception != (ExceptionInfo *) NULL);
668 (void) CopyMagickString(path,filename,MaxTextExtent);
669 /*
670 Load XML from configuration files to linked-list.
671 */
672 options=NewLinkedList(0);
673 paths=GetConfigurePaths(filename,exception);
674 if (paths != (LinkedListInfo *) NULL)
675 {
676 ResetLinkedListIterator(paths);
677 element=(const char *) GetNextValueInLinkedList(paths);
678 while (element != (const char *) NULL)
679 {
cristyb51dff52011-05-19 16:55:47 +0000680 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
cristy3ed852e2009-09-05 21:47:34 +0000681 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
682 "Searching for configure file: \"%s\"",path);
683 xml=ConfigureFileToStringInfo(path);
684 if (xml != (StringInfo *) NULL)
685 (void) AppendValueToLinkedList(options,xml);
686 element=(const char *) GetNextValueInLinkedList(paths);
687 }
688 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
689 }
cristy0157aea2010-04-24 21:12:18 +0000690#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy7e247522011-11-29 14:59:23 +0000691 if (GetNumberOfElementsInLinkedList(options) == 0)
692 {
693 char
694 *blob;
cristy3ed852e2009-09-05 21:47:34 +0000695
cristy7e247522011-11-29 14:59:23 +0000696 blob=(char *) NTResourceToBlob(filename);
697 if (blob != (char *) NULL)
698 {
699 xml=AcquireStringInfo(0);
700 SetStringInfoLength(xml,strlen(blob)+1);
cristy52070b42012-02-19 22:03:21 +0000701 SetStringInfoDatum(xml,(unsigned char *) blob);
cristy7e247522011-11-29 14:59:23 +0000702 SetStringInfoPath(xml,filename);
703 (void) AppendValueToLinkedList(options,xml);
704 }
705 }
cristy3ed852e2009-09-05 21:47:34 +0000706#endif
707 if (GetNumberOfElementsInLinkedList(options) == 0)
708 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
cristyefe601c2013-01-05 17:51:12 +0000709 "UnableToOpenConfigureFile","`%s'",filename);
cristy3ed852e2009-09-05 21:47:34 +0000710 ResetLinkedListIterator(options);
711 return(options);
712}
713
714/*
715%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716% %
717% %
718% %
719% G e t C o n f i g u r e P a t h s %
720% %
721% %
722% %
723%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
724%
725% GetConfigurePaths() returns any Magick configuration paths associated
726% with the specified filename.
727%
728% The format of the GetConfigurePaths method is:
729%
730% LinkedListInfo *GetConfigurePaths(const char *filename,
731% ExceptionInfo *exception)
732%
733% A description of each parameter follows:
734%
735% o filename: the configure file name.
736%
737% o exception: return any errors or warnings in this structure.
738%
739*/
740MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
741 ExceptionInfo *exception)
742{
cristy7e247522011-11-29 14:59:23 +0000743#define RegistryKey "ConfigurePath"
cristy6c28ec02011-10-28 11:37:57 +0000744#define MagickCoreDLL "CORE_RL_MagickCore_.dll"
745#define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll"
746
cristy3ed852e2009-09-05 21:47:34 +0000747 char
748 path[MaxTextExtent];
749
750 LinkedListInfo
751 *paths;
752
753 assert(filename != (const char *) NULL);
754 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
755 assert(exception != (ExceptionInfo *) NULL);
756 (void) CopyMagickString(path,filename,MaxTextExtent);
757 paths=NewLinkedList(0);
758 {
759 char
760 *configure_path;
761
762 /*
763 Search $MAGICK_CONFIGURE_PATH.
764 */
765 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
766 if (configure_path != (char *) NULL)
767 {
768 register char
769 *p,
770 *q;
771
772 for (p=configure_path-1; p != (char *) NULL; )
773 {
774 (void) CopyMagickString(path,p+1,MaxTextExtent);
775 q=strchr(path,DirectoryListSeparator);
776 if (q != (char *) NULL)
777 *q='\0';
778 q=path+strlen(path)-1;
779 if ((q >= path) && (*q != *DirectorySeparator))
780 (void) ConcatenateMagickString(path,DirectorySeparator,
781 MaxTextExtent);
782 (void) AppendValueToLinkedList(paths,ConstantString(path));
783 p=strchr(p+1,DirectoryListSeparator);
784 }
785 configure_path=DestroyString(configure_path);
786 }
787 }
788#if defined(MAGICKCORE_INSTALLED_SUPPORT)
cristy4f820712011-04-01 12:35:43 +0000789#if defined(MAGICKCORE_SHARE_PATH)
cristy6c28ec02011-10-28 11:37:57 +0000790 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
cristy3ed852e2009-09-05 21:47:34 +0000791#endif
cristy670aa3c2011-11-03 00:54:00 +0000792#if defined(MAGICKCORE_SHAREARCH_PATH)
793 (void) AppendValueToLinkedList(paths,ConstantString(
794 MAGICKCORE_SHAREARCH_PATH));
795#endif
cristy3ed852e2009-09-05 21:47:34 +0000796#if defined(MAGICKCORE_CONFIGURE_PATH)
797 (void) AppendValueToLinkedList(paths,ConstantString(
798 MAGICKCORE_CONFIGURE_PATH));
799#endif
800#if defined(MAGICKCORE_DOCUMENTATION_PATH)
801 (void) AppendValueToLinkedList(paths,ConstantString(
802 MAGICKCORE_DOCUMENTATION_PATH));
803#endif
cristy4f820712011-04-01 12:35:43 +0000804#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
cristy3ed852e2009-09-05 21:47:34 +0000805 {
cristy3ed852e2009-09-05 21:47:34 +0000806 unsigned char
807 *key_value;
808
809 /*
810 Locate file via registry key.
811 */
cristy7e247522011-11-29 14:59:23 +0000812 key_value=NTRegistryKeyLookup(RegistryKey);
cristy3ed852e2009-09-05 21:47:34 +0000813 if (key_value != (unsigned char *) NULL)
814 {
cristyb51dff52011-05-19 16:55:47 +0000815 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
cristy3ed852e2009-09-05 21:47:34 +0000816 DirectorySeparator);
817 (void) AppendValueToLinkedList(paths,ConstantString(path));
818 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
819 }
820 }
821#endif
822#else
823 {
824 char
825 *home;
826
827 /*
828 Search under MAGICK_HOME.
829 */
830 home=GetEnvironmentValue("MAGICK_HOME");
831 if (home != (char *) NULL)
832 {
833#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000834 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000835 DirectorySeparator);
836 (void) AppendValueToLinkedList(paths,ConstantString(path));
837#else
cristyb51dff52011-05-19 16:55:47 +0000838 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
cristy3ed852e2009-09-05 21:47:34 +0000839 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
840 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000841 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
cristy4f820712011-04-01 12:35:43 +0000842 MAGICKCORE_SHARE_RELATIVE_PATH);
cristy3ed852e2009-09-05 21:47:34 +0000843 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristy780d58c2013-05-03 13:49:00 +0000844 (void) FormatLocaleString(path,MaxTextExtent,"%s",
845 MAGICKCORE_SHAREARCH_PATH);
846 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristy3ed852e2009-09-05 21:47:34 +0000847#endif
848 home=DestroyString(home);
849 }
850 }
851 if (*GetClientPath() != '\0')
852 {
853#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000854 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +0000855 DirectorySeparator);
856 (void) AppendValueToLinkedList(paths,ConstantString(path));
857#else
858 char
859 prefix[MaxTextExtent];
860
861 /*
862 Search based on executable directory if directory is known.
863 */
864 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
865 ChopPathComponents(prefix,1);
cristyb51dff52011-05-19 16:55:47 +0000866 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
cristy3ed852e2009-09-05 21:47:34 +0000867 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
868 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000869 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
cristy4f820712011-04-01 12:35:43 +0000870 MAGICKCORE_SHARE_RELATIVE_PATH);
871 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristy780d58c2013-05-03 13:49:00 +0000872 (void) FormatLocaleString(path,MaxTextExtent,"%s",
873 MAGICKCORE_SHAREARCH_PATH);
874 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristy3ed852e2009-09-05 21:47:34 +0000875#endif
876 }
cristy51b1ac52010-10-30 02:27:14 +0000877 /*
878 Search current directory.
879 */
880 (void) AppendValueToLinkedList(paths,ConstantString(""));
cristy3ed852e2009-09-05 21:47:34 +0000881#endif
882 {
883 char
884 *home;
885
886 home=GetEnvironmentValue("HOME");
887 if (home == (char *) NULL)
888 home=GetEnvironmentValue("USERPROFILE");
889 if (home != (char *) NULL)
890 {
891 /*
cristy9f3b4fc2014-02-08 14:56:20 +0000892 Search $HOME/.config/ImageMagick.
cristy3ed852e2009-09-05 21:47:34 +0000893 */
cristy9f3b4fc2014-02-08 14:56:20 +0000894 (void) FormatLocaleString(path,MaxTextExtent,
895 "%s%s.config%sImageMagick%s",home,DirectorySeparator,
cristy3ed852e2009-09-05 21:47:34 +0000896 DirectorySeparator,DirectorySeparator);
897 (void) AppendValueToLinkedList(paths,ConstantString(path));
898 home=DestroyString(home);
899 }
900 }
cristy0157aea2010-04-24 21:12:18 +0000901#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000902 {
903 char
904 module_path[MaxTextExtent];
905
cristy6c28ec02011-10-28 11:37:57 +0000906 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
907 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +0000908 {
cristy7e247522011-11-29 14:59:23 +0000909 unsigned char
910 *key_value;
cristy3ed852e2009-09-05 21:47:34 +0000911
912 /*
913 Search module path.
914 */
cristyb51dff52011-05-19 16:55:47 +0000915 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000916 DirectorySeparator);
cristy7e247522011-11-29 14:59:23 +0000917 key_value=NTRegistryKeyLookup(RegistryKey);
918 if (key_value == (unsigned char *) NULL)
919 (void) AppendValueToLinkedList(paths,ConstantString(path));
920 else
921 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
cristy3ed852e2009-09-05 21:47:34 +0000922 }
923 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
924 {
925 /*
926 Search PerlMagick module path.
927 */
cristyb51dff52011-05-19 16:55:47 +0000928 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000929 DirectorySeparator);
930 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000931 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000932 "\\inc\\lib\\auto\\Image\\Magick\\");
933 (void) AppendValueToLinkedList(paths,ConstantString(path));
934 }
935 }
936#endif
cristy3ed852e2009-09-05 21:47:34 +0000937 return(paths);
938}
939
940/*
941%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942% %
943% %
944% %
945% G e t C o n f i g u r e V a l u e %
946% %
947% %
948% %
949%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
950%
951% GetConfigureValue() returns the value associated with the configure info.
952%
953% The format of the GetConfigureValue method is:
954%
955% const char *GetConfigureValue(const ConfigureInfo *configure_info)
956%
957% A description of each parameter follows:
958%
959% o configure_info: The configure info.
960%
961*/
962MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
963{
964 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
965 assert(configure_info != (ConfigureInfo *) NULL);
966 assert(configure_info->signature == MagickSignature);
967 return(configure_info->value);
968}
969
970/*
971%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
972% %
973% %
974% %
cristy86e5ac92014-03-16 19:27:39 +0000975+ I s C o n f i g u r e C a c h e I n s t a n t i a t e d %
cristy3ed852e2009-09-05 21:47:34 +0000976% %
977% %
978% %
979%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
980%
cristy86e5ac92014-03-16 19:27:39 +0000981% IsConfigureCacheInstantiated() determines if the configure list is
cristy904e5912014-03-15 19:53:14 +0000982% instantiated. If not, it instantiates the list and returns it.
cristy3ed852e2009-09-05 21:47:34 +0000983%
cristy904e5912014-03-15 19:53:14 +0000984% The format of the IsConfigureInstantiated method is:
cristy3ed852e2009-09-05 21:47:34 +0000985%
cristy86e5ac92014-03-16 19:27:39 +0000986% MagickBooleanType IsConfigureCacheInstantiated(ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000987%
988% A description of each parameter follows.
989%
990% o exception: return any errors or warnings in this structure.
991%
992*/
cristy86e5ac92014-03-16 19:27:39 +0000993static MagickBooleanType IsConfigureCacheInstantiated(ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000994{
cristy86e5ac92014-03-16 19:27:39 +0000995 if (configure_cache == (LinkedListInfo *) NULL)
996 {
997 if (configure_semaphore == (SemaphoreInfo *) NULL)
998 ActivateSemaphoreInfo(&configure_semaphore);
999 LockSemaphoreInfo(configure_semaphore);
1000 if (configure_cache == (LinkedListInfo *) NULL)
1001 configure_cache=AcquireConfigureCache(ConfigureFilename,exception);
1002 UnlockSemaphoreInfo(configure_semaphore);
1003 }
1004 return(configure_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +00001005}
1006
1007/*
1008%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1009% %
1010% %
1011% %
cristy3ed852e2009-09-05 21:47:34 +00001012% L i s t C o n f i g u r e I n f o %
1013% %
1014% %
1015% %
1016%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1017%
1018% ListConfigureInfo() lists the configure info to a file.
1019%
1020% The format of the ListConfigureInfo method is:
1021%
1022% MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
1023%
1024% A description of each parameter follows.
1025%
1026% o file: An pointer to a FILE.
1027%
1028% o exception: return any errors or warnings in this structure.
1029%
1030*/
1031MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
1032 ExceptionInfo *exception)
1033{
1034 const char
1035 *name,
1036 *path,
1037 *value;
1038
1039 const ConfigureInfo
1040 **configure_info;
1041
cristybb503372010-05-27 20:51:26 +00001042 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001043 i;
1044
cristybb503372010-05-27 20:51:26 +00001045 size_t
cristy3ed852e2009-09-05 21:47:34 +00001046 number_options;
1047
cristy9d314ff2011-03-09 01:30:28 +00001048 ssize_t
1049 j;
1050
cristy3ed852e2009-09-05 21:47:34 +00001051 if (file == (const FILE *) NULL)
1052 file=stdout;
1053 configure_info=GetConfigureInfoList("*",&number_options,exception);
1054 if (configure_info == (const ConfigureInfo **) NULL)
1055 return(MagickFalse);
1056 path=(const char *) NULL;
cristybb503372010-05-27 20:51:26 +00001057 for (i=0; i < (ssize_t) number_options; i++)
cristy3ed852e2009-09-05 21:47:34 +00001058 {
1059 if (configure_info[i]->stealth != MagickFalse)
1060 continue;
1061 if ((path == (const char *) NULL) ||
1062 (LocaleCompare(path,configure_info[i]->path) != 0))
1063 {
1064 if (configure_info[i]->path != (char *) NULL)
cristy1e604812011-05-19 18:07:50 +00001065 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
1066 configure_info[i]->path);
cristy9f973042012-12-06 01:28:59 +00001067 (void) FormatLocaleFile(file,"Name Value\n");
cristy1e604812011-05-19 18:07:50 +00001068 (void) FormatLocaleFile(file,
1069 "-------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +00001070 "------------------------------\n");
1071 }
1072 path=configure_info[i]->path;
1073 name="unknown";
1074 if (configure_info[i]->name != (char *) NULL)
1075 name=configure_info[i]->name;
cristyb51dff52011-05-19 16:55:47 +00001076 (void) FormatLocaleFile(file,"%s",name);
cristy9f973042012-12-06 01:28:59 +00001077 for (j=(ssize_t) strlen(name); j <= 13; j++)
cristyb51dff52011-05-19 16:55:47 +00001078 (void) FormatLocaleFile(file," ");
1079 (void) FormatLocaleFile(file," ");
cristy3ed852e2009-09-05 21:47:34 +00001080 value="unknown";
1081 if (configure_info[i]->value != (char *) NULL)
1082 value=configure_info[i]->value;
cristyb51dff52011-05-19 16:55:47 +00001083 (void) FormatLocaleFile(file,"%s",value);
1084 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +00001085 }
1086 (void) fflush(file);
cristycd2cd182014-03-18 12:10:55 +00001087 configure_info=(const ConfigureInfo **) RelinquishMagickMemory((void *)
1088 configure_info);
cristy3ed852e2009-09-05 21:47:34 +00001089 return(MagickTrue);
1090}
1091
1092/*
1093%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1094% %
1095% %
1096% %
1097+ L o a d C o n f i g u r e L i s t %
1098% %
1099% %
1100% %
1101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1102%
cristy86e5ac92014-03-16 19:27:39 +00001103% LoadConfigureCache() loads the configure configurations which provides a
cristy3ed852e2009-09-05 21:47:34 +00001104% mapping between configure attributes and a configure name.
1105%
cristy86e5ac92014-03-16 19:27:39 +00001106% The format of the LoadConfigureCache method is:
cristy3ed852e2009-09-05 21:47:34 +00001107%
cristycd2cd182014-03-18 12:10:55 +00001108% MagickBooleanType LoadConfigureCache(LinkedListInfo *configure_cache,
cristy0d8101e2014-04-10 00:13:05 +00001109% const char *xml,const char *filename,const size_t depth,
1110% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001111%
1112% A description of each parameter follows:
1113%
1114% o xml: The configure list in XML format.
1115%
1116% o filename: The configure list filename.
1117%
1118% o depth: depth of <include /> statements.
1119%
1120% o exception: return any errors or warnings in this structure.
1121%
1122*/
cristycd2cd182014-03-18 12:10:55 +00001123static MagickBooleanType LoadConfigureCache(LinkedListInfo *configure_cache,
1124 const char *xml,const char *filename,const size_t depth,
1125 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001126{
1127 char
1128 keyword[MaxTextExtent],
1129 *token;
1130
1131 ConfigureInfo
1132 *configure_info;
1133
1134 const char
1135 *q;
1136
1137 MagickBooleanType
1138 status;
1139
1140 /*
1141 Load the configure map file.
1142 */
1143 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1144 "Loading configure file \"%s\" ...",filename);
cristy3ed852e2009-09-05 21:47:34 +00001145 status=MagickTrue;
1146 configure_info=(ConfigureInfo *) NULL;
cristy54a531d2009-10-21 17:58:01 +00001147 token=AcquireString((char *) xml);
cristy3ed852e2009-09-05 21:47:34 +00001148 for (q=(char *) xml; *q != '\0'; )
1149 {
1150 /*
1151 Interpret XML.
1152 */
1153 GetMagickToken(q,&q,token);
1154 if (*token == '\0')
1155 break;
1156 (void) CopyMagickString(keyword,token,MaxTextExtent);
1157 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1158 {
1159 /*
1160 Doctype element.
1161 */
1162 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1163 GetMagickToken(q,&q,token);
1164 continue;
1165 }
1166 if (LocaleNCompare(keyword,"<!--",4) == 0)
1167 {
1168 /*
1169 Comment element.
1170 */
1171 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1172 GetMagickToken(q,&q,token);
1173 continue;
1174 }
1175 if (LocaleCompare(keyword,"<include") == 0)
1176 {
1177 /*
1178 Include element.
1179 */
1180 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1181 {
1182 (void) CopyMagickString(keyword,token,MaxTextExtent);
1183 GetMagickToken(q,&q,token);
1184 if (*token != '=')
1185 continue;
1186 GetMagickToken(q,&q,token);
1187 if (LocaleCompare(keyword,"file") == 0)
1188 {
1189 if (depth > 200)
1190 (void) ThrowMagickException(exception,GetMagickModule(),
cristyefe601c2013-01-05 17:51:12 +00001191 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
cristy3ed852e2009-09-05 21:47:34 +00001192 else
1193 {
1194 char
1195 path[MaxTextExtent],
1196 *xml;
1197
1198 GetPathComponent(filename,HeadPath,path);
1199 if (*path != '\0')
1200 (void) ConcatenateMagickString(path,DirectorySeparator,
1201 MaxTextExtent);
1202 if (*token == *DirectorySeparator)
1203 (void) CopyMagickString(path,token,MaxTextExtent);
1204 else
1205 (void) ConcatenateMagickString(path,token,MaxTextExtent);
cristy3291f512014-03-16 22:16:22 +00001206 xml=FileToXML(path,~0UL);
cristy3ed852e2009-09-05 21:47:34 +00001207 if (xml != (char *) NULL)
1208 {
cristycd2cd182014-03-18 12:10:55 +00001209 status&=LoadConfigureCache(configure_cache,xml,path,
1210 depth+1,exception);
cristy3ed852e2009-09-05 21:47:34 +00001211 xml=(char *) RelinquishMagickMemory(xml);
1212 }
1213 }
1214 }
1215 }
1216 continue;
1217 }
1218 if (LocaleCompare(keyword,"<configure") == 0)
1219 {
1220 /*
1221 Configure element.
1222 */
1223 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1224 sizeof(*configure_info));
1225 if (configure_info == (ConfigureInfo *) NULL)
1226 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1227 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1228 configure_info->path=ConstantString(filename);
cristy54a531d2009-10-21 17:58:01 +00001229 configure_info->exempt=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +00001230 configure_info->signature=MagickSignature;
1231 continue;
1232 }
1233 if (configure_info == (ConfigureInfo *) NULL)
1234 continue;
1235 if (LocaleCompare(keyword,"/>") == 0)
1236 {
cristy86e5ac92014-03-16 19:27:39 +00001237 status=AppendValueToLinkedList(configure_cache,configure_info);
cristy3ed852e2009-09-05 21:47:34 +00001238 if (status == MagickFalse)
1239 (void) ThrowMagickException(exception,GetMagickModule(),
cristyefe601c2013-01-05 17:51:12 +00001240 ResourceLimitError,"MemoryAllocationFailed","`%s'",
cristy3ed852e2009-09-05 21:47:34 +00001241 configure_info->name);
1242 configure_info=(ConfigureInfo *) NULL;
cristyd45122f2014-01-14 23:46:16 +00001243 continue;
cristy3ed852e2009-09-05 21:47:34 +00001244 }
1245 /*
1246 Parse configure element.
1247 */
1248 GetMagickToken(q,(const char **) NULL,token);
1249 if (*token != '=')
1250 continue;
1251 GetMagickToken(q,&q,token);
1252 GetMagickToken(q,&q,token);
1253 switch (*keyword)
1254 {
1255 case 'N':
1256 case 'n':
1257 {
1258 if (LocaleCompare((char *) keyword,"name") == 0)
1259 {
1260 configure_info->name=ConstantString(token);
1261 break;
1262 }
1263 break;
1264 }
1265 case 'S':
1266 case 's':
1267 {
1268 if (LocaleCompare((char *) keyword,"stealth") == 0)
1269 {
anthony6f201312012-03-30 04:08:15 +00001270 configure_info->stealth=IsStringTrue(token);
cristy3ed852e2009-09-05 21:47:34 +00001271 break;
1272 }
1273 break;
1274 }
1275 case 'V':
1276 case 'v':
1277 {
1278 if (LocaleCompare((char *) keyword,"value") == 0)
1279 {
1280 configure_info->value=ConstantString(token);
1281 break;
1282 }
1283 break;
1284 }
1285 default:
1286 break;
1287 }
1288 }
1289 token=(char *) RelinquishMagickMemory(token);
1290 return(status);
1291}