blob: 7fdfb45869660ea1e357ca6229e346f9f08304e0 [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*/
42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/client.h"
45#include "magick/configure.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/hashmap.h"
49#include "magick/log.h"
50#include "magick/memory_.h"
51#include "magick/semaphore.h"
52#include "magick/string_.h"
53#include "magick/token.h"
54#include "magick/utility.h"
55#include "magick/xml-tree.h"
56
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 {
563 (void) FormatMagickString(path,MaxTextExtent,"%s%s",element,filename);
564 (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)
666#if defined(MAGICKCORE_SHARE_CONFIGURE_PATH)
667 (void) AppendValueToLinkedList(paths,ConstantString(
668 MAGICKCORE_SHARE_CONFIGURE_PATH));
669#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
678#if defined(MAGICKCORE_SHARE_PATH)
679 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
680#endif
cristy0157aea2010-04-24 21:12:18 +0000681#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_CONFIGURE_PATH))
cristy3ed852e2009-09-05 21:47:34 +0000682 {
683 char
684 *registry_key;
685
686 unsigned char
687 *key_value;
688
689 /*
690 Locate file via registry key.
691 */
692 registry_key="ConfigurePath";
693 key_value=NTRegistryKeyLookup(registry_key);
694 if (key_value != (unsigned char *) NULL)
695 {
696 (void) FormatMagickString(path,MaxTextExtent,"%s%s",(char *) key_value,
697 DirectorySeparator);
698 (void) AppendValueToLinkedList(paths,ConstantString(path));
699 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
700 }
701 }
702#endif
703#else
704 {
705 char
706 *home;
707
708 /*
709 Search under MAGICK_HOME.
710 */
711 home=GetEnvironmentValue("MAGICK_HOME");
712 if (home != (char *) NULL)
713 {
714#if !defined(MAGICKCORE_POSIX_SUPPORT)
715 (void) FormatMagickString(path,MaxTextExtent,"%s%s",home,
716 DirectorySeparator);
717 (void) AppendValueToLinkedList(paths,ConstantString(path));
718#else
719 (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/",home,
720 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
721 (void) AppendValueToLinkedList(paths,ConstantString(path));
722 (void) FormatMagickString(path,MaxTextExtent,"%s/share/%s/",home,
723 MAGICKCORE_SHARE_CONFIGURE_RELATIVE_PATH);
724 (void) AppendValueToLinkedList(paths,ConstantString(path));
725#endif
726 home=DestroyString(home);
727 }
728 }
729 if (*GetClientPath() != '\0')
730 {
731#if !defined(MAGICKCORE_POSIX_SUPPORT)
732 (void) FormatMagickString(path,MaxTextExtent,"%s%s",GetClientPath(),
733 DirectorySeparator);
734 (void) AppendValueToLinkedList(paths,ConstantString(path));
735#else
736 char
737 prefix[MaxTextExtent];
738
739 /*
740 Search based on executable directory if directory is known.
741 */
742 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
743 ChopPathComponents(prefix,1);
744 (void) FormatMagickString(path,MaxTextExtent,"%s/share/%s/",prefix,
745 MAGICKCORE_SHARE_CONFIGURE_RELATIVE_PATH);
746 (void) AppendValueToLinkedList(paths,ConstantString(path));
747 (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/",prefix,
748 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
749 (void) AppendValueToLinkedList(paths,ConstantString(path));
750#endif
751 }
cristy51b1ac52010-10-30 02:27:14 +0000752 /*
753 Search current directory.
754 */
755 (void) AppendValueToLinkedList(paths,ConstantString(""));
cristy3ed852e2009-09-05 21:47:34 +0000756#endif
757 {
758 char
759 *home;
760
761 home=GetEnvironmentValue("HOME");
762 if (home == (char *) NULL)
763 home=GetEnvironmentValue("USERPROFILE");
764 if (home != (char *) NULL)
765 {
766 /*
767 Search $HOME/.magick.
768 */
769 (void) FormatMagickString(path,MaxTextExtent,"%s%s.magick%s",home,
770 DirectorySeparator,DirectorySeparator);
771 (void) AppendValueToLinkedList(paths,ConstantString(path));
772 home=DestroyString(home);
773 }
774 }
cristy0157aea2010-04-24 21:12:18 +0000775#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000776 {
777 char
778 module_path[MaxTextExtent];
779
780 if ((NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse) ||
781 (NTGetModulePath("CORE_DB_magick_.dll",module_path) != MagickFalse))
782 {
783 char
784 *element;
785
786 /*
787 Search module path.
788 */
789 (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
790 DirectorySeparator);
791 element=(char *) RemoveElementByValueFromLinkedList(paths,path);
792 if (element != (char *) NULL)
793 element=DestroyString(element);
794 (void) AppendValueToLinkedList(paths,ConstantString(path));
795 }
796 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
797 {
798 /*
799 Search PerlMagick module path.
800 */
801 (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
802 DirectorySeparator);
803 (void) AppendValueToLinkedList(paths,ConstantString(path));
804 (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
805 "\\inc\\lib\\auto\\Image\\Magick\\");
806 (void) AppendValueToLinkedList(paths,ConstantString(path));
807 }
808 }
809#endif
cristy3ed852e2009-09-05 21:47:34 +0000810 return(paths);
811}
812
813/*
814%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
815% %
816% %
817% %
818% G e t C o n f i g u r e V a l u e %
819% %
820% %
821% %
822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
823%
824% GetConfigureValue() returns the value associated with the configure info.
825%
826% The format of the GetConfigureValue method is:
827%
828% const char *GetConfigureValue(const ConfigureInfo *configure_info)
829%
830% A description of each parameter follows:
831%
832% o configure_info: The configure info.
833%
834*/
835MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
836{
837 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
838 assert(configure_info != (ConfigureInfo *) NULL);
839 assert(configure_info->signature == MagickSignature);
840 return(configure_info->value);
841}
842
843/*
844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845% %
846% %
847% %
848+ I n i t i a l i z e C o n f i g u r e L i s t %
849% %
850% %
851% %
852%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853%
854% InitializeConfigureList() initializes the configure list.
855%
856% The format of the InitializeConfigureList method is:
857%
858% MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
859%
860% A description of each parameter follows.
861%
862% o exception: return any errors or warnings in this structure.
863%
864*/
865static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
866{
867 if ((configure_list == (LinkedListInfo *) NULL) &&
868 (instantiate_configure == MagickFalse))
869 {
cristy4e1dff62009-10-25 20:36:03 +0000870 if (configure_semaphore == (SemaphoreInfo *) NULL)
871 AcquireSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000872 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000873 if ((configure_list == (LinkedListInfo *) NULL) &&
874 (instantiate_configure == MagickFalse))
875 {
876 (void) LoadConfigureLists(ConfigureFilename,exception);
877 instantiate_configure=MagickTrue;
878 }
cristyf84a1932010-01-03 18:00:18 +0000879 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000880 }
881 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
882}
883
884/*
885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886% %
887% %
888% %
cristy3ed852e2009-09-05 21:47:34 +0000889% L i s t C o n f i g u r e I n f o %
890% %
891% %
892% %
893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894%
895% ListConfigureInfo() lists the configure info to a file.
896%
897% The format of the ListConfigureInfo method is:
898%
899% MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
900%
901% A description of each parameter follows.
902%
903% o file: An pointer to a FILE.
904%
905% o exception: return any errors or warnings in this structure.
906%
907*/
908MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
909 ExceptionInfo *exception)
910{
911 const char
912 *name,
913 *path,
914 *value;
915
916 const ConfigureInfo
917 **configure_info;
918
cristybb503372010-05-27 20:51:26 +0000919 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000920 i;
921
cristybb503372010-05-27 20:51:26 +0000922 size_t
cristy3ed852e2009-09-05 21:47:34 +0000923 number_options;
924
cristy9d314ff2011-03-09 01:30:28 +0000925 ssize_t
926 j;
927
cristy3ed852e2009-09-05 21:47:34 +0000928 if (file == (const FILE *) NULL)
929 file=stdout;
930 configure_info=GetConfigureInfoList("*",&number_options,exception);
931 if (configure_info == (const ConfigureInfo **) NULL)
932 return(MagickFalse);
933 path=(const char *) NULL;
cristybb503372010-05-27 20:51:26 +0000934 for (i=0; i < (ssize_t) number_options; i++)
cristy3ed852e2009-09-05 21:47:34 +0000935 {
936 if (configure_info[i]->stealth != MagickFalse)
937 continue;
938 if ((path == (const char *) NULL) ||
939 (LocaleCompare(path,configure_info[i]->path) != 0))
940 {
941 if (configure_info[i]->path != (char *) NULL)
942 (void) fprintf(file,"\nPath: %s\n\n",configure_info[i]->path);
943 (void) fprintf(file,"Name Value\n");
944 (void) fprintf(file,"-------------------------------------------------"
945 "------------------------------\n");
946 }
947 path=configure_info[i]->path;
948 name="unknown";
949 if (configure_info[i]->name != (char *) NULL)
950 name=configure_info[i]->name;
951 (void) fprintf(file,"%s",name);
cristybb503372010-05-27 20:51:26 +0000952 for (j=(ssize_t) strlen(name); j <= 12; j++)
cristy3ed852e2009-09-05 21:47:34 +0000953 (void) fprintf(file," ");
954 (void) fprintf(file," ");
955 value="unknown";
956 if (configure_info[i]->value != (char *) NULL)
957 value=configure_info[i]->value;
958 (void) fprintf(file,"%s",value);
959 (void) fprintf(file,"\n");
960 }
961 (void) fflush(file);
962 configure_info=(const ConfigureInfo **)
963 RelinquishMagickMemory((void *) configure_info);
964 return(MagickTrue);
965}
966
967/*
968%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969% %
970% %
971% %
972+ L o a d C o n f i g u r e L i s t %
973% %
974% %
975% %
976%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977%
978% LoadConfigureList() loads the configure configuration file which provides a
979% mapping between configure attributes and a configure name.
980%
981% The format of the LoadConfigureList method is:
982%
983% MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000984% const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000985%
986% A description of each parameter follows:
987%
988% o xml: The configure list in XML format.
989%
990% o filename: The configure list filename.
991%
992% o depth: depth of <include /> statements.
993%
994% o exception: return any errors or warnings in this structure.
995%
996*/
997static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000998 const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000999{
1000 char
1001 keyword[MaxTextExtent],
1002 *token;
1003
1004 ConfigureInfo
1005 *configure_info;
1006
1007 const char
1008 *q;
1009
1010 MagickBooleanType
1011 status;
1012
1013 /*
1014 Load the configure map file.
1015 */
1016 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1017 "Loading configure file \"%s\" ...",filename);
1018 if (configure_list == (LinkedListInfo *) NULL)
1019 {
1020 configure_list=NewLinkedList(0);
1021 if (configure_list == (LinkedListInfo *) NULL)
1022 {
1023 ThrowFileException(exception,ResourceLimitError,
1024 "MemoryAllocationFailed",filename);
1025 return(MagickFalse);
1026 }
1027 }
1028 status=MagickTrue;
1029 configure_info=(ConfigureInfo *) NULL;
cristy54a531d2009-10-21 17:58:01 +00001030 token=AcquireString((char *) xml);
cristy3ed852e2009-09-05 21:47:34 +00001031 for (q=(char *) xml; *q != '\0'; )
1032 {
1033 /*
1034 Interpret XML.
1035 */
1036 GetMagickToken(q,&q,token);
1037 if (*token == '\0')
1038 break;
1039 (void) CopyMagickString(keyword,token,MaxTextExtent);
1040 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1041 {
1042 /*
1043 Doctype element.
1044 */
1045 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1046 GetMagickToken(q,&q,token);
1047 continue;
1048 }
1049 if (LocaleNCompare(keyword,"<!--",4) == 0)
1050 {
1051 /*
1052 Comment element.
1053 */
1054 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1055 GetMagickToken(q,&q,token);
1056 continue;
1057 }
1058 if (LocaleCompare(keyword,"<include") == 0)
1059 {
1060 /*
1061 Include element.
1062 */
1063 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1064 {
1065 (void) CopyMagickString(keyword,token,MaxTextExtent);
1066 GetMagickToken(q,&q,token);
1067 if (*token != '=')
1068 continue;
1069 GetMagickToken(q,&q,token);
1070 if (LocaleCompare(keyword,"file") == 0)
1071 {
1072 if (depth > 200)
1073 (void) ThrowMagickException(exception,GetMagickModule(),
1074 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1075 else
1076 {
1077 char
1078 path[MaxTextExtent],
1079 *xml;
1080
1081 GetPathComponent(filename,HeadPath,path);
1082 if (*path != '\0')
1083 (void) ConcatenateMagickString(path,DirectorySeparator,
1084 MaxTextExtent);
1085 if (*token == *DirectorySeparator)
1086 (void) CopyMagickString(path,token,MaxTextExtent);
1087 else
1088 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1089 xml=FileToString(path,~0,exception);
1090 if (xml != (char *) NULL)
1091 {
1092 status=LoadConfigureList(xml,path,depth+1,exception);
1093 xml=(char *) RelinquishMagickMemory(xml);
1094 }
1095 }
1096 }
1097 }
1098 continue;
1099 }
1100 if (LocaleCompare(keyword,"<configure") == 0)
1101 {
1102 /*
1103 Configure element.
1104 */
1105 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1106 sizeof(*configure_info));
1107 if (configure_info == (ConfigureInfo *) NULL)
1108 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1109 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1110 configure_info->path=ConstantString(filename);
cristy54a531d2009-10-21 17:58:01 +00001111 configure_info->exempt=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +00001112 configure_info->signature=MagickSignature;
1113 continue;
1114 }
1115 if (configure_info == (ConfigureInfo *) NULL)
1116 continue;
1117 if (LocaleCompare(keyword,"/>") == 0)
1118 {
1119 status=AppendValueToLinkedList(configure_list,configure_info);
1120 if (status == MagickFalse)
1121 (void) ThrowMagickException(exception,GetMagickModule(),
1122 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1123 configure_info->name);
1124 configure_info=(ConfigureInfo *) NULL;
1125 }
1126 /*
1127 Parse configure element.
1128 */
1129 GetMagickToken(q,(const char **) NULL,token);
1130 if (*token != '=')
1131 continue;
1132 GetMagickToken(q,&q,token);
1133 GetMagickToken(q,&q,token);
1134 switch (*keyword)
1135 {
1136 case 'N':
1137 case 'n':
1138 {
1139 if (LocaleCompare((char *) keyword,"name") == 0)
1140 {
1141 configure_info->name=ConstantString(token);
1142 break;
1143 }
1144 break;
1145 }
1146 case 'S':
1147 case 's':
1148 {
1149 if (LocaleCompare((char *) keyword,"stealth") == 0)
1150 {
1151 configure_info->stealth=IsMagickTrue(token);
1152 break;
1153 }
1154 break;
1155 }
1156 case 'V':
1157 case 'v':
1158 {
1159 if (LocaleCompare((char *) keyword,"value") == 0)
1160 {
1161 configure_info->value=ConstantString(token);
1162 break;
1163 }
1164 break;
1165 }
1166 default:
1167 break;
1168 }
1169 }
1170 token=(char *) RelinquishMagickMemory(token);
1171 return(status);
1172}
1173
1174/*
1175%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1176% %
1177% %
1178% %
1179% L o a d C o n f i g u r e L i s t s %
1180% %
1181% %
1182% %
1183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1184%
1185% LoadConfigureList() loads one or more configure configuration files which
1186% provides a mapping between configure attributes and a configure name.
1187%
1188% The format of the LoadConfigureLists method is:
1189%
1190% MagickBooleanType LoadConfigureLists(const char *filename,
1191% ExceptionInfo *exception)
1192%
1193% A description of each parameter follows:
1194%
1195% o filename: the font file name.
1196%
1197% o exception: return any errors or warnings in this structure.
1198%
1199*/
1200static MagickBooleanType LoadConfigureLists(const char *filename,
1201 ExceptionInfo *exception)
1202{
cristy3ed852e2009-09-05 21:47:34 +00001203 const StringInfo
1204 *option;
1205
1206 LinkedListInfo
1207 *options;
1208
1209 MagickStatusType
1210 status;
1211
cristybb503372010-05-27 20:51:26 +00001212 register ssize_t
cristy54a531d2009-10-21 17:58:01 +00001213 i;
1214
1215 /*
1216 Load built-in configure map.
1217 */
cristy3ed852e2009-09-05 21:47:34 +00001218 status=MagickFalse;
cristy54a531d2009-10-21 17:58:01 +00001219 if (configure_list == (LinkedListInfo *) NULL)
1220 {
1221 configure_list=NewLinkedList(0);
1222 if (configure_list == (LinkedListInfo *) NULL)
1223 {
1224 ThrowFileException(exception,ResourceLimitError,
1225 "MemoryAllocationFailed",filename);
1226 return(MagickFalse);
1227 }
1228 }
cristybb503372010-05-27 20:51:26 +00001229 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
cristy54a531d2009-10-21 17:58:01 +00001230 {
1231 ConfigureInfo
1232 *configure_info;
1233
1234 register const ConfigureMapInfo
1235 *p;
1236
1237 p=ConfigureMap+i;
1238 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1239 sizeof(*configure_info));
1240 if (configure_info == (ConfigureInfo *) NULL)
1241 {
1242 (void) ThrowMagickException(exception,GetMagickModule(),
1243 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1244 configure_info->name);
1245 continue;
1246 }
1247 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1248 configure_info->path=(char *) "[built-in]";
1249 configure_info->name=(char *) p->name;
1250 configure_info->value=(char *) p->value;
1251 configure_info->exempt=MagickTrue;
1252 configure_info->signature=MagickSignature;
1253 status=AppendValueToLinkedList(configure_list,configure_info);
1254 if (status == MagickFalse)
1255 (void) ThrowMagickException(exception,GetMagickModule(),
1256 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1257 configure_info->name);
1258 }
1259 /*
1260 Load external configure map.
1261 */
cristy3ed852e2009-09-05 21:47:34 +00001262 options=GetConfigureOptions(filename,exception);
1263 option=(const StringInfo *) GetNextValueInLinkedList(options);
1264 while (option != (const StringInfo *) NULL)
1265 {
1266 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1267 GetStringInfoPath(option),0,exception);
1268 option=(const StringInfo *) GetNextValueInLinkedList(options);
1269 }
1270 options=DestroyConfigureOptions(options);
cristy3ed852e2009-09-05 21:47:34 +00001271 return(status != 0 ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +00001272}