blob: b9b2bee694655e1329afc91550ec9d3c02a6f09b [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 %
16% John Cristy %
17% July 2003 %
18% %
19% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 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"
46#include "MagickCore/exception.h"
47#include "MagickCore/exception-private.h"
48#include "MagickCore/hashmap.h"
49#include "MagickCore/log.h"
50#include "MagickCore/memory_.h"
51#include "MagickCore/semaphore.h"
52#include "MagickCore/string_.h"
53#include "MagickCore/token.h"
54#include "MagickCore/utility.h"
55#include "MagickCore/xml-tree.h"
cristy3ed852e2009-09-05 21:47:34 +000056
57/*
58 Define declarations.
59*/
60#define ConfigureFilename "configure.xml"
61
62/*
cristy54a531d2009-10-21 17:58:01 +000063 Typedef declarations.
64*/
65typedef struct _ConfigureMapInfo
66{
67 const char
68 *name,
69 *value;
70} ConfigureMapInfo;
71
72/*
cristy3ed852e2009-09-05 21:47:34 +000073 Static declarations.
74*/
cristy54a531d2009-10-21 17:58:01 +000075static const ConfigureMapInfo
76 ConfigureMap[] =
77 {
cristyc03a1b52009-10-23 15:43:36 +000078 { "NAME", "ImageMagick" }
cristy54a531d2009-10-21 17:58:01 +000079 };
cristy3ed852e2009-09-05 21:47:34 +000080
81static LinkedListInfo
82 *configure_list = (LinkedListInfo *) NULL;
83
84static SemaphoreInfo
85 *configure_semaphore = (SemaphoreInfo *) NULL;
86
87static volatile MagickBooleanType
88 instantiate_configure = MagickFalse;
89
90/*
91 Forward declarations.
92*/
93static MagickBooleanType
94 InitializeConfigureList(ExceptionInfo *),
95 LoadConfigureLists(const char *,ExceptionInfo *);
96
97/*
98%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99% %
100% %
101% %
cristyf34a1452009-10-24 22:29:27 +0000102+ 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 +0000103% %
104% %
105% %
106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107%
cristyf34a1452009-10-24 22:29:27 +0000108% ConfigureComponentGenesis() instantiates the configure component.
cristy3ed852e2009-09-05 21:47:34 +0000109%
cristyf34a1452009-10-24 22:29:27 +0000110% The format of the ConfigureComponentGenesis method is:
cristy3ed852e2009-09-05 21:47:34 +0000111%
cristyf34a1452009-10-24 22:29:27 +0000112% MagickBooleanType ConfigureComponentGenesis(void)
113%
114*/
115MagickExport MagickBooleanType ConfigureComponentGenesis(void)
116{
cristy165b6092009-10-26 13:52:10 +0000117 AcquireSemaphoreInfo(&configure_semaphore);
cristyf34a1452009-10-24 22:29:27 +0000118 return(MagickTrue);
119}
120
121/*
122%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123% %
124% %
125% %
126+ 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 %
127% %
128% %
129% %
130%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131%
132% ConfigureComponentTerminus() destroys the configure component.
133%
134% The format of the ConfigureComponentTerminus method is:
135%
136% ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000137%
138*/
139
140static void *DestroyConfigureElement(void *configure_info)
141{
142 register ConfigureInfo
143 *p;
144
145 p=(ConfigureInfo *) configure_info;
cristy54a531d2009-10-21 17:58:01 +0000146 if (p->exempt == MagickFalse)
147 {
148 if (p->value != (char *) NULL)
149 p->value=DestroyString(p->value);
150 if (p->name != (char *) NULL)
151 p->name=DestroyString(p->name);
152 if (p->path != (char *) NULL)
153 p->path=DestroyString(p->path);
154 }
cristy3ed852e2009-09-05 21:47:34 +0000155 p=(ConfigureInfo *) RelinquishMagickMemory(p);
156 return((void *) NULL);
157}
158
cristyf34a1452009-10-24 22:29:27 +0000159MagickExport void ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000160{
cristy18b17442009-10-25 18:36:48 +0000161 if (configure_semaphore == (SemaphoreInfo *) NULL)
162 AcquireSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000163 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000164 if (configure_list != (LinkedListInfo *) NULL)
165 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
166 configure_list=(LinkedListInfo *) NULL;
167 instantiate_configure=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000168 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000169 DestroySemaphoreInfo(&configure_semaphore);
170}
171
172/*
173%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
174% %
175% %
176% %
177% D e s t r o y C o n f i g u r e O p t i o n s %
178% %
179% %
180% %
181%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182%
183% DestroyConfigureOptions() releases memory associated with an configure
184% options.
185%
186% The format of the DestroyProfiles method is:
187%
188% LinkedListInfo *DestroyConfigureOptions(Image *image)
189%
190% A description of each parameter follows:
191%
192% o image: the image.
193%
194*/
195
196static void *DestroyOptions(void *option)
197{
198 return(DestroyStringInfo((StringInfo *) option));
199}
200
201MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
202{
203 assert(options != (LinkedListInfo *) NULL);
204 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
205 return(DestroyLinkedList(options,DestroyOptions));
206}
207
208/*
209%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210% %
211% %
212% %
213+ G e t C o n f i g u r e I n f o %
214% %
215% %
216% %
217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218%
219% GetConfigureInfo() searches the configure list for the specified name and if
220% found returns attributes for that element.
221%
222% The format of the GetConfigureInfo method is:
223%
224% const ConfigureInfo *GetConfigureInfo(const char *name,
225% ExceptionInfo *exception)
226%
227% A description of each parameter follows:
228%
229% o configure_info: GetConfigureInfo() searches the configure list for the
230% specified name and if found returns attributes for that element.
231%
232% o name: the configure name.
233%
234% o exception: return any errors or warnings in this structure.
235%
236*/
237MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
238 ExceptionInfo *exception)
239{
240 register const ConfigureInfo
241 *p;
242
243 assert(exception != (ExceptionInfo *) NULL);
244 if ((configure_list == (LinkedListInfo *) NULL) ||
245 (instantiate_configure == MagickFalse))
246 if (InitializeConfigureList(exception) == MagickFalse)
247 return((const ConfigureInfo *) NULL);
248 if ((configure_list == (LinkedListInfo *) NULL) ||
249 (IsLinkedListEmpty(configure_list) != MagickFalse))
250 return((const ConfigureInfo *) NULL);
251 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
252 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
253 /*
254 Search for configure tag.
255 */
cristyf84a1932010-01-03 18:00:18 +0000256 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000257 ResetLinkedListIterator(configure_list);
258 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
259 while (p != (const ConfigureInfo *) NULL)
260 {
261 if (LocaleCompare(name,p->name) == 0)
262 break;
263 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
264 }
265 if (p != (ConfigureInfo *) NULL)
266 (void) InsertValueInLinkedList(configure_list,0,
267 RemoveElementByValueFromLinkedList(configure_list,p));
cristyf84a1932010-01-03 18:00:18 +0000268 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000269 return(p);
270}
271
272/*
273%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274% %
275% %
276% %
277% G e t C o n f i g u r e I n f o L i s t %
278% %
279% %
280% %
281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282%
283% GetConfigureInfoList() returns any configure options that match the
284% specified pattern.
285%
286% The format of the GetConfigureInfoList function is:
287%
288% const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000289% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000290%
291% A description of each parameter follows:
292%
293% o pattern: Specifies a pointer to a text string containing a pattern.
294%
295% o number_options: This integer returns the number of configure options in
296% the list.
297%
298% o exception: return any errors or warnings in this structure.
299%
300*/
301
302#if defined(__cplusplus) || defined(c_plusplus)
303extern "C" {
304#endif
305
306static int ConfigureInfoCompare(const void *x,const void *y)
307{
308 const ConfigureInfo
309 **p,
310 **q;
311
312 p=(const ConfigureInfo **) x,
313 q=(const ConfigureInfo **) y;
314 if (LocaleCompare((*p)->path,(*q)->path) == 0)
315 return(LocaleCompare((*p)->name,(*q)->name));
316 return(LocaleCompare((*p)->path,(*q)->path));
317}
318
319#if defined(__cplusplus) || defined(c_plusplus)
320}
321#endif
322
323MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000324 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000325{
326 const ConfigureInfo
327 **options;
328
329 register const ConfigureInfo
330 *p;
331
cristybb503372010-05-27 20:51:26 +0000332 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000333 i;
334
335 /*
336 Allocate configure list.
337 */
338 assert(pattern != (char *) NULL);
339 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000340 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000341 *number_options=0;
342 p=GetConfigureInfo("*",exception);
343 if (p == (const ConfigureInfo *) NULL)
344 return((const ConfigureInfo **) NULL);
345 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
346 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
347 if (options == (const ConfigureInfo **) NULL)
348 return((const ConfigureInfo **) NULL);
349 /*
350 Generate configure list.
351 */
cristyf84a1932010-01-03 18:00:18 +0000352 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000353 ResetLinkedListIterator(configure_list);
354 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
355 for (i=0; p != (const ConfigureInfo *) NULL; )
356 {
357 if ((p->stealth == MagickFalse) &&
358 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
359 options[i++]=p;
360 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
361 }
cristyf84a1932010-01-03 18:00:18 +0000362 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000363 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
364 options[i]=(ConfigureInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000365 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000366 return(options);
367}
368
369/*
370%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
371% %
372% %
373% %
374% G e t C o n f i g u r e L i s t %
375% %
376% %
377% %
378%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379%
380% GetConfigureList() returns any configure options that match the specified
381% pattern.
382%
383% The format of the GetConfigureList function is:
384%
385% char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000386% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000387%
388% A description of each parameter follows:
389%
390% o pattern: Specifies a pointer to a text string containing a pattern.
391%
392% o number_options: This integer returns the number of options in the list.
393%
394% o exception: return any errors or warnings in this structure.
395%
396*/
397
398#if defined(__cplusplus) || defined(c_plusplus)
399extern "C" {
400#endif
401
402static int ConfigureCompare(const void *x,const void *y)
403{
404 register char
405 **p,
406 **q;
407
408 p=(char **) x;
409 q=(char **) y;
410 return(LocaleCompare(*p,*q));
411}
412
413#if defined(__cplusplus) || defined(c_plusplus)
414}
415#endif
416
417MagickExport char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000418 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000419{
420 char
421 **options;
422
423 register const ConfigureInfo
424 *p;
425
cristybb503372010-05-27 20:51:26 +0000426 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000427 i;
428
429 /*
430 Allocate configure list.
431 */
432 assert(pattern != (char *) NULL);
433 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000434 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000435 *number_options=0;
436 p=GetConfigureInfo("*",exception);
437 if (p == (const ConfigureInfo *) NULL)
438 return((char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000439 options=(char **) AcquireQuantumMemory((size_t)
440 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
441 if (options == (char **) NULL)
442 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000443 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000444 ResetLinkedListIterator(configure_list);
445 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
446 for (i=0; p != (const ConfigureInfo *) NULL; )
447 {
448 if ((p->stealth == MagickFalse) &&
449 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
450 options[i++]=ConstantString(p->name);
451 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
452 }
cristyf84a1932010-01-03 18:00:18 +0000453 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000454 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
455 options[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000456 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000457 return(options);
458}
459
460/*
461%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
462% %
463% %
464% %
465% G e t C o n f i g u r e O p t i o n %
466% %
467% %
468% %
469%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470%
471% GetConfigureOption() returns the value associated with the configure option.
472%
473% The format of the GetConfigureOption method is:
474%
475% char *GetConfigureOption(const char *option)
476%
477% A description of each parameter follows:
478%
479% o configure_info: The configure info.
480%
481*/
482MagickExport char *GetConfigureOption(const char *option)
483{
484 const char
485 *value;
486
487 const ConfigureInfo
488 *configure_info;
489
490 ExceptionInfo
491 *exception;
492
493 assert(option != (const char *) NULL);
494 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
495 exception=AcquireExceptionInfo();
496 configure_info=GetConfigureInfo(option,exception);
497 exception=DestroyExceptionInfo(exception);
498 if (configure_info == (ConfigureInfo *) NULL)
499 return((char *) NULL);
500 value=GetConfigureValue(configure_info);
501 if ((value == (const char *) NULL) || (*value == '\0'))
502 return((char *) NULL);
503 return(ConstantString(value));
504}
505
506/*
507%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
508% %
509% %
510% %
511% G e t C o n f i g u r e O p t i o n s %
512% %
513% %
514% %
515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
516%
517% GetConfigureOptions() returns any Magick configuration options associated
518% with the specified filename.
519%
520% The format of the GetConfigureOptions method is:
521%
522% LinkedListInfo *GetConfigureOptions(const char *filename,
523% ExceptionInfo *exception)
524%
525% A description of each parameter follows:
526%
527% o filename: the configure file name.
528%
529% o exception: return any errors or warnings in this structure.
530%
531*/
532MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
533 ExceptionInfo *exception)
534{
535 char
536 path[MaxTextExtent];
537
538 const char
539 *element;
540
541 LinkedListInfo
542 *options,
543 *paths;
544
545 StringInfo
546 *xml;
547
548 assert(filename != (const char *) NULL);
549 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
550 assert(exception != (ExceptionInfo *) NULL);
551 (void) CopyMagickString(path,filename,MaxTextExtent);
552 /*
553 Load XML from configuration files to linked-list.
554 */
555 options=NewLinkedList(0);
556 paths=GetConfigurePaths(filename,exception);
557 if (paths != (LinkedListInfo *) NULL)
558 {
559 ResetLinkedListIterator(paths);
560 element=(const char *) GetNextValueInLinkedList(paths);
561 while (element != (const char *) NULL)
562 {
cristyb51dff52011-05-19 16:55:47 +0000563 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
cristy3ed852e2009-09-05 21:47:34 +0000564 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
565 "Searching for configure file: \"%s\"",path);
566 xml=ConfigureFileToStringInfo(path);
567 if (xml != (StringInfo *) NULL)
568 (void) AppendValueToLinkedList(options,xml);
569 element=(const char *) GetNextValueInLinkedList(paths);
570 }
571 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
572 }
cristy0157aea2010-04-24 21:12:18 +0000573#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000574 {
575 char
576 *blob;
577
578 blob=(char *) NTResourceToBlob(filename);
579 if (blob != (char *) NULL)
580 {
581 xml=StringToStringInfo(blob);
582 SetStringInfoPath(xml,filename);
583 (void) AppendValueToLinkedList(options,xml);
584 blob=DestroyString(blob);
585 }
586 }
587#endif
588 if (GetNumberOfElementsInLinkedList(options) == 0)
589 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
590 "UnableToOpenConfigureFile","`%s'",filename);
591 ResetLinkedListIterator(options);
592 return(options);
593}
594
595/*
596%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597% %
598% %
599% %
600% G e t C o n f i g u r e P a t h s %
601% %
602% %
603% %
604%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
605%
606% GetConfigurePaths() returns any Magick configuration paths associated
607% with the specified filename.
608%
609% The format of the GetConfigurePaths method is:
610%
611% LinkedListInfo *GetConfigurePaths(const char *filename,
612% ExceptionInfo *exception)
613%
614% A description of each parameter follows:
615%
616% o filename: the configure file name.
617%
618% o exception: return any errors or warnings in this structure.
619%
620*/
621MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
622 ExceptionInfo *exception)
623{
624 char
625 path[MaxTextExtent];
626
627 LinkedListInfo
628 *paths;
629
630 assert(filename != (const char *) NULL);
631 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
632 assert(exception != (ExceptionInfo *) NULL);
633 (void) CopyMagickString(path,filename,MaxTextExtent);
634 paths=NewLinkedList(0);
635 {
636 char
637 *configure_path;
638
639 /*
640 Search $MAGICK_CONFIGURE_PATH.
641 */
642 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
643 if (configure_path != (char *) NULL)
644 {
645 register char
646 *p,
647 *q;
648
649 for (p=configure_path-1; p != (char *) NULL; )
650 {
651 (void) CopyMagickString(path,p+1,MaxTextExtent);
652 q=strchr(path,DirectoryListSeparator);
653 if (q != (char *) NULL)
654 *q='\0';
655 q=path+strlen(path)-1;
656 if ((q >= path) && (*q != *DirectorySeparator))
657 (void) ConcatenateMagickString(path,DirectorySeparator,
658 MaxTextExtent);
659 (void) AppendValueToLinkedList(paths,ConstantString(path));
660 p=strchr(p+1,DirectoryListSeparator);
661 }
662 configure_path=DestroyString(configure_path);
663 }
664 }
665#if defined(MAGICKCORE_INSTALLED_SUPPORT)
cristy4f820712011-04-01 12:35:43 +0000666#if defined(MAGICKCORE_SHARE_PATH)
cristy3ed852e2009-09-05 21:47:34 +0000667 (void) AppendValueToLinkedList(paths,ConstantString(
cristy4f820712011-04-01 12:35:43 +0000668 MAGICKCORE_SHARE_PATH));
cristy3ed852e2009-09-05 21:47:34 +0000669#endif
670#if defined(MAGICKCORE_CONFIGURE_PATH)
671 (void) AppendValueToLinkedList(paths,ConstantString(
672 MAGICKCORE_CONFIGURE_PATH));
673#endif
674#if defined(MAGICKCORE_DOCUMENTATION_PATH)
675 (void) AppendValueToLinkedList(paths,ConstantString(
676 MAGICKCORE_DOCUMENTATION_PATH));
677#endif
cristy4f820712011-04-01 12:35:43 +0000678#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
cristy3ed852e2009-09-05 21:47:34 +0000679 {
680 char
681 *registry_key;
682
683 unsigned char
684 *key_value;
685
686 /*
687 Locate file via registry key.
688 */
689 registry_key="ConfigurePath";
690 key_value=NTRegistryKeyLookup(registry_key);
691 if (key_value != (unsigned char *) NULL)
692 {
cristyb51dff52011-05-19 16:55:47 +0000693 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
cristy3ed852e2009-09-05 21:47:34 +0000694 DirectorySeparator);
695 (void) AppendValueToLinkedList(paths,ConstantString(path));
696 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
697 }
698 }
699#endif
700#else
701 {
702 char
703 *home;
704
705 /*
706 Search under MAGICK_HOME.
707 */
708 home=GetEnvironmentValue("MAGICK_HOME");
709 if (home != (char *) NULL)
710 {
711#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000712 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000713 DirectorySeparator);
714 (void) AppendValueToLinkedList(paths,ConstantString(path));
715#else
cristyb51dff52011-05-19 16:55:47 +0000716 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
cristy3ed852e2009-09-05 21:47:34 +0000717 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
718 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000719 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
cristy4f820712011-04-01 12:35:43 +0000720 MAGICKCORE_SHARE_RELATIVE_PATH);
cristy3ed852e2009-09-05 21:47:34 +0000721 (void) AppendValueToLinkedList(paths,ConstantString(path));
722#endif
723 home=DestroyString(home);
724 }
725 }
726 if (*GetClientPath() != '\0')
727 {
728#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000729 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +0000730 DirectorySeparator);
731 (void) AppendValueToLinkedList(paths,ConstantString(path));
732#else
733 char
734 prefix[MaxTextExtent];
735
736 /*
737 Search based on executable directory if directory is known.
738 */
739 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
740 ChopPathComponents(prefix,1);
cristyb51dff52011-05-19 16:55:47 +0000741 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
cristy3ed852e2009-09-05 21:47:34 +0000742 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
743 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000744 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
cristy4f820712011-04-01 12:35:43 +0000745 MAGICKCORE_SHARE_RELATIVE_PATH);
746 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristy3ed852e2009-09-05 21:47:34 +0000747#endif
748 }
cristy51b1ac52010-10-30 02:27:14 +0000749 /*
750 Search current directory.
751 */
752 (void) AppendValueToLinkedList(paths,ConstantString(""));
cristy3ed852e2009-09-05 21:47:34 +0000753#endif
754 {
755 char
756 *home;
757
758 home=GetEnvironmentValue("HOME");
759 if (home == (char *) NULL)
760 home=GetEnvironmentValue("USERPROFILE");
761 if (home != (char *) NULL)
762 {
763 /*
764 Search $HOME/.magick.
765 */
cristyb51dff52011-05-19 16:55:47 +0000766 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000767 DirectorySeparator,DirectorySeparator);
768 (void) AppendValueToLinkedList(paths,ConstantString(path));
769 home=DestroyString(home);
770 }
771 }
cristy0157aea2010-04-24 21:12:18 +0000772#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000773 {
774 char
775 module_path[MaxTextExtent];
776
777 if ((NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse) ||
778 (NTGetModulePath("CORE_DB_magick_.dll",module_path) != MagickFalse))
779 {
780 char
781 *element;
782
783 /*
784 Search module path.
785 */
cristyb51dff52011-05-19 16:55:47 +0000786 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000787 DirectorySeparator);
788 element=(char *) RemoveElementByValueFromLinkedList(paths,path);
789 if (element != (char *) NULL)
790 element=DestroyString(element);
791 (void) AppendValueToLinkedList(paths,ConstantString(path));
792 }
793 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
794 {
795 /*
796 Search PerlMagick module path.
797 */
cristyb51dff52011-05-19 16:55:47 +0000798 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000799 DirectorySeparator);
800 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000801 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000802 "\\inc\\lib\\auto\\Image\\Magick\\");
803 (void) AppendValueToLinkedList(paths,ConstantString(path));
804 }
805 }
806#endif
cristy3ed852e2009-09-05 21:47:34 +0000807 return(paths);
808}
809
810/*
811%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
812% %
813% %
814% %
815% G e t C o n f i g u r e V a l u e %
816% %
817% %
818% %
819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820%
821% GetConfigureValue() returns the value associated with the configure info.
822%
823% The format of the GetConfigureValue method is:
824%
825% const char *GetConfigureValue(const ConfigureInfo *configure_info)
826%
827% A description of each parameter follows:
828%
829% o configure_info: The configure info.
830%
831*/
832MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
833{
834 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
835 assert(configure_info != (ConfigureInfo *) NULL);
836 assert(configure_info->signature == MagickSignature);
837 return(configure_info->value);
838}
839
840/*
841%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842% %
843% %
844% %
845+ I n i t i a l i z e C o n f i g u r e L i s t %
846% %
847% %
848% %
849%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
850%
851% InitializeConfigureList() initializes the configure list.
852%
853% The format of the InitializeConfigureList method is:
854%
855% MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
856%
857% A description of each parameter follows.
858%
859% o exception: return any errors or warnings in this structure.
860%
861*/
862static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
863{
864 if ((configure_list == (LinkedListInfo *) NULL) &&
865 (instantiate_configure == MagickFalse))
866 {
cristy4e1dff62009-10-25 20:36:03 +0000867 if (configure_semaphore == (SemaphoreInfo *) NULL)
868 AcquireSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000869 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000870 if ((configure_list == (LinkedListInfo *) NULL) &&
871 (instantiate_configure == MagickFalse))
872 {
873 (void) LoadConfigureLists(ConfigureFilename,exception);
874 instantiate_configure=MagickTrue;
875 }
cristyf84a1932010-01-03 18:00:18 +0000876 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000877 }
878 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
879}
880
881/*
882%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
883% %
884% %
885% %
cristy3ed852e2009-09-05 21:47:34 +0000886% L i s t C o n f i g u r e I n f o %
887% %
888% %
889% %
890%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
891%
892% ListConfigureInfo() lists the configure info to a file.
893%
894% The format of the ListConfigureInfo method is:
895%
896% MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
897%
898% A description of each parameter follows.
899%
900% o file: An pointer to a FILE.
901%
902% o exception: return any errors or warnings in this structure.
903%
904*/
905MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
906 ExceptionInfo *exception)
907{
908 const char
909 *name,
910 *path,
911 *value;
912
913 const ConfigureInfo
914 **configure_info;
915
cristybb503372010-05-27 20:51:26 +0000916 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000917 i;
918
cristybb503372010-05-27 20:51:26 +0000919 size_t
cristy3ed852e2009-09-05 21:47:34 +0000920 number_options;
921
cristy9d314ff2011-03-09 01:30:28 +0000922 ssize_t
923 j;
924
cristy3ed852e2009-09-05 21:47:34 +0000925 if (file == (const FILE *) NULL)
926 file=stdout;
927 configure_info=GetConfigureInfoList("*",&number_options,exception);
928 if (configure_info == (const ConfigureInfo **) NULL)
929 return(MagickFalse);
930 path=(const char *) NULL;
cristybb503372010-05-27 20:51:26 +0000931 for (i=0; i < (ssize_t) number_options; i++)
cristy3ed852e2009-09-05 21:47:34 +0000932 {
933 if (configure_info[i]->stealth != MagickFalse)
934 continue;
935 if ((path == (const char *) NULL) ||
936 (LocaleCompare(path,configure_info[i]->path) != 0))
937 {
938 if (configure_info[i]->path != (char *) NULL)
cristy1e604812011-05-19 18:07:50 +0000939 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
940 configure_info[i]->path);
cristyb51dff52011-05-19 16:55:47 +0000941 (void) FormatLocaleFile(file,"Name Value\n");
cristy1e604812011-05-19 18:07:50 +0000942 (void) FormatLocaleFile(file,
943 "-------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000944 "------------------------------\n");
945 }
946 path=configure_info[i]->path;
947 name="unknown";
948 if (configure_info[i]->name != (char *) NULL)
949 name=configure_info[i]->name;
cristyb51dff52011-05-19 16:55:47 +0000950 (void) FormatLocaleFile(file,"%s",name);
cristybb503372010-05-27 20:51:26 +0000951 for (j=(ssize_t) strlen(name); j <= 12; j++)
cristyb51dff52011-05-19 16:55:47 +0000952 (void) FormatLocaleFile(file," ");
953 (void) FormatLocaleFile(file," ");
cristy3ed852e2009-09-05 21:47:34 +0000954 value="unknown";
955 if (configure_info[i]->value != (char *) NULL)
956 value=configure_info[i]->value;
cristyb51dff52011-05-19 16:55:47 +0000957 (void) FormatLocaleFile(file,"%s",value);
958 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +0000959 }
960 (void) fflush(file);
961 configure_info=(const ConfigureInfo **)
962 RelinquishMagickMemory((void *) configure_info);
963 return(MagickTrue);
964}
965
966/*
967%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
968% %
969% %
970% %
971+ L o a d C o n f i g u r e L i s t %
972% %
973% %
974% %
975%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
976%
977% LoadConfigureList() loads the configure configuration file which provides a
978% mapping between configure attributes and a configure name.
979%
980% The format of the LoadConfigureList method is:
981%
982% MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000983% const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000984%
985% A description of each parameter follows:
986%
987% o xml: The configure list in XML format.
988%
989% o filename: The configure list filename.
990%
991% o depth: depth of <include /> statements.
992%
993% o exception: return any errors or warnings in this structure.
994%
995*/
996static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000997 const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000998{
999 char
1000 keyword[MaxTextExtent],
1001 *token;
1002
1003 ConfigureInfo
1004 *configure_info;
1005
1006 const char
1007 *q;
1008
1009 MagickBooleanType
1010 status;
1011
1012 /*
1013 Load the configure map file.
1014 */
1015 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1016 "Loading configure file \"%s\" ...",filename);
1017 if (configure_list == (LinkedListInfo *) NULL)
1018 {
1019 configure_list=NewLinkedList(0);
1020 if (configure_list == (LinkedListInfo *) NULL)
1021 {
1022 ThrowFileException(exception,ResourceLimitError,
1023 "MemoryAllocationFailed",filename);
1024 return(MagickFalse);
1025 }
1026 }
1027 status=MagickTrue;
1028 configure_info=(ConfigureInfo *) NULL;
cristy54a531d2009-10-21 17:58:01 +00001029 token=AcquireString((char *) xml);
cristy3ed852e2009-09-05 21:47:34 +00001030 for (q=(char *) xml; *q != '\0'; )
1031 {
1032 /*
1033 Interpret XML.
1034 */
1035 GetMagickToken(q,&q,token);
1036 if (*token == '\0')
1037 break;
1038 (void) CopyMagickString(keyword,token,MaxTextExtent);
1039 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1040 {
1041 /*
1042 Doctype element.
1043 */
1044 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1045 GetMagickToken(q,&q,token);
1046 continue;
1047 }
1048 if (LocaleNCompare(keyword,"<!--",4) == 0)
1049 {
1050 /*
1051 Comment element.
1052 */
1053 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1054 GetMagickToken(q,&q,token);
1055 continue;
1056 }
1057 if (LocaleCompare(keyword,"<include") == 0)
1058 {
1059 /*
1060 Include element.
1061 */
1062 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1063 {
1064 (void) CopyMagickString(keyword,token,MaxTextExtent);
1065 GetMagickToken(q,&q,token);
1066 if (*token != '=')
1067 continue;
1068 GetMagickToken(q,&q,token);
1069 if (LocaleCompare(keyword,"file") == 0)
1070 {
1071 if (depth > 200)
1072 (void) ThrowMagickException(exception,GetMagickModule(),
1073 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1074 else
1075 {
1076 char
1077 path[MaxTextExtent],
1078 *xml;
1079
1080 GetPathComponent(filename,HeadPath,path);
1081 if (*path != '\0')
1082 (void) ConcatenateMagickString(path,DirectorySeparator,
1083 MaxTextExtent);
1084 if (*token == *DirectorySeparator)
1085 (void) CopyMagickString(path,token,MaxTextExtent);
1086 else
1087 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1088 xml=FileToString(path,~0,exception);
1089 if (xml != (char *) NULL)
1090 {
1091 status=LoadConfigureList(xml,path,depth+1,exception);
1092 xml=(char *) RelinquishMagickMemory(xml);
1093 }
1094 }
1095 }
1096 }
1097 continue;
1098 }
1099 if (LocaleCompare(keyword,"<configure") == 0)
1100 {
1101 /*
1102 Configure element.
1103 */
1104 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1105 sizeof(*configure_info));
1106 if (configure_info == (ConfigureInfo *) NULL)
1107 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1108 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1109 configure_info->path=ConstantString(filename);
cristy54a531d2009-10-21 17:58:01 +00001110 configure_info->exempt=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +00001111 configure_info->signature=MagickSignature;
1112 continue;
1113 }
1114 if (configure_info == (ConfigureInfo *) NULL)
1115 continue;
1116 if (LocaleCompare(keyword,"/>") == 0)
1117 {
1118 status=AppendValueToLinkedList(configure_list,configure_info);
1119 if (status == MagickFalse)
1120 (void) ThrowMagickException(exception,GetMagickModule(),
1121 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1122 configure_info->name);
1123 configure_info=(ConfigureInfo *) NULL;
1124 }
1125 /*
1126 Parse configure element.
1127 */
1128 GetMagickToken(q,(const char **) NULL,token);
1129 if (*token != '=')
1130 continue;
1131 GetMagickToken(q,&q,token);
1132 GetMagickToken(q,&q,token);
1133 switch (*keyword)
1134 {
1135 case 'N':
1136 case 'n':
1137 {
1138 if (LocaleCompare((char *) keyword,"name") == 0)
1139 {
1140 configure_info->name=ConstantString(token);
1141 break;
1142 }
1143 break;
1144 }
1145 case 'S':
1146 case 's':
1147 {
1148 if (LocaleCompare((char *) keyword,"stealth") == 0)
1149 {
1150 configure_info->stealth=IsMagickTrue(token);
1151 break;
1152 }
1153 break;
1154 }
1155 case 'V':
1156 case 'v':
1157 {
1158 if (LocaleCompare((char *) keyword,"value") == 0)
1159 {
1160 configure_info->value=ConstantString(token);
1161 break;
1162 }
1163 break;
1164 }
1165 default:
1166 break;
1167 }
1168 }
1169 token=(char *) RelinquishMagickMemory(token);
1170 return(status);
1171}
1172
1173/*
1174%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1175% %
1176% %
1177% %
1178% L o a d C o n f i g u r e L i s t s %
1179% %
1180% %
1181% %
1182%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1183%
1184% LoadConfigureList() loads one or more configure configuration files which
1185% provides a mapping between configure attributes and a configure name.
1186%
1187% The format of the LoadConfigureLists method is:
1188%
1189% MagickBooleanType LoadConfigureLists(const char *filename,
1190% ExceptionInfo *exception)
1191%
1192% A description of each parameter follows:
1193%
1194% o filename: the font file name.
1195%
1196% o exception: return any errors or warnings in this structure.
1197%
1198*/
1199static MagickBooleanType LoadConfigureLists(const char *filename,
1200 ExceptionInfo *exception)
1201{
cristy3ed852e2009-09-05 21:47:34 +00001202 const StringInfo
1203 *option;
1204
1205 LinkedListInfo
1206 *options;
1207
1208 MagickStatusType
1209 status;
1210
cristybb503372010-05-27 20:51:26 +00001211 register ssize_t
cristy54a531d2009-10-21 17:58:01 +00001212 i;
1213
1214 /*
1215 Load built-in configure map.
1216 */
cristy3ed852e2009-09-05 21:47:34 +00001217 status=MagickFalse;
cristy54a531d2009-10-21 17:58:01 +00001218 if (configure_list == (LinkedListInfo *) NULL)
1219 {
1220 configure_list=NewLinkedList(0);
1221 if (configure_list == (LinkedListInfo *) NULL)
1222 {
1223 ThrowFileException(exception,ResourceLimitError,
1224 "MemoryAllocationFailed",filename);
1225 return(MagickFalse);
1226 }
1227 }
cristybb503372010-05-27 20:51:26 +00001228 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
cristy54a531d2009-10-21 17:58:01 +00001229 {
1230 ConfigureInfo
1231 *configure_info;
1232
1233 register const ConfigureMapInfo
1234 *p;
1235
1236 p=ConfigureMap+i;
1237 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1238 sizeof(*configure_info));
1239 if (configure_info == (ConfigureInfo *) NULL)
1240 {
1241 (void) ThrowMagickException(exception,GetMagickModule(),
1242 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1243 configure_info->name);
1244 continue;
1245 }
1246 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1247 configure_info->path=(char *) "[built-in]";
1248 configure_info->name=(char *) p->name;
1249 configure_info->value=(char *) p->value;
1250 configure_info->exempt=MagickTrue;
1251 configure_info->signature=MagickSignature;
1252 status=AppendValueToLinkedList(configure_list,configure_info);
1253 if (status == MagickFalse)
1254 (void) ThrowMagickException(exception,GetMagickModule(),
1255 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1256 configure_info->name);
1257 }
1258 /*
1259 Load external configure map.
1260 */
cristy3ed852e2009-09-05 21:47:34 +00001261 options=GetConfigureOptions(filename,exception);
1262 option=(const StringInfo *) GetNextValueInLinkedList(options);
1263 while (option != (const StringInfo *) NULL)
1264 {
1265 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1266 GetStringInfoPath(option),0,exception);
1267 option=(const StringInfo *) GetNextValueInLinkedList(options);
1268 }
1269 options=DestroyConfigureOptions(options);
cristy3ed852e2009-09-05 21:47:34 +00001270 return(status != 0 ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +00001271}