blob: 6049bb0fab3ec102c64e2ddd5dd59b40973010aa [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"
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"
54#include "MagickCore/token.h"
55#include "MagickCore/utility.h"
cristyd1dd6e42011-09-04 01:46:08 +000056#include "MagickCore/utility-private.h"
cristy4c08aed2011-07-01 19:47:50 +000057#include "MagickCore/xml-tree.h"
cristy3ed852e2009-09-05 21:47:34 +000058
59/*
60 Define declarations.
61*/
62#define ConfigureFilename "configure.xml"
63
64/*
cristy54a531d2009-10-21 17:58:01 +000065 Typedef declarations.
66*/
67typedef struct _ConfigureMapInfo
68{
69 const char
70 *name,
71 *value;
72} ConfigureMapInfo;
73
74/*
cristy3ed852e2009-09-05 21:47:34 +000075 Static declarations.
76*/
cristy54a531d2009-10-21 17:58:01 +000077static const ConfigureMapInfo
78 ConfigureMap[] =
79 {
cristyc03a1b52009-10-23 15:43:36 +000080 { "NAME", "ImageMagick" }
cristy54a531d2009-10-21 17:58:01 +000081 };
cristy3ed852e2009-09-05 21:47:34 +000082
83static LinkedListInfo
84 *configure_list = (LinkedListInfo *) NULL;
85
86static SemaphoreInfo
87 *configure_semaphore = (SemaphoreInfo *) NULL;
88
89static volatile MagickBooleanType
90 instantiate_configure = MagickFalse;
91
92/*
93 Forward declarations.
94*/
95static MagickBooleanType
96 InitializeConfigureList(ExceptionInfo *),
97 LoadConfigureLists(const char *,ExceptionInfo *);
98
99/*
100%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101% %
102% %
103% %
cristyf34a1452009-10-24 22:29:27 +0000104+ 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 +0000105% %
106% %
107% %
108%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109%
cristyf34a1452009-10-24 22:29:27 +0000110% ConfigureComponentGenesis() instantiates the configure component.
cristy3ed852e2009-09-05 21:47:34 +0000111%
cristyf34a1452009-10-24 22:29:27 +0000112% The format of the ConfigureComponentGenesis method is:
cristy3ed852e2009-09-05 21:47:34 +0000113%
cristyf34a1452009-10-24 22:29:27 +0000114% MagickBooleanType ConfigureComponentGenesis(void)
115%
116*/
cristy5ff4eaf2011-09-03 01:38:02 +0000117MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +0000118{
cristy165b6092009-10-26 13:52:10 +0000119 AcquireSemaphoreInfo(&configure_semaphore);
cristyf34a1452009-10-24 22:29:27 +0000120 return(MagickTrue);
121}
122
123/*
124%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
125% %
126% %
127% %
128+ 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 %
129% %
130% %
131% %
132%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133%
134% ConfigureComponentTerminus() destroys the configure component.
135%
136% The format of the ConfigureComponentTerminus method is:
137%
138% ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000139%
140*/
141
142static void *DestroyConfigureElement(void *configure_info)
143{
144 register ConfigureInfo
145 *p;
146
147 p=(ConfigureInfo *) configure_info;
cristy54a531d2009-10-21 17:58:01 +0000148 if (p->exempt == MagickFalse)
149 {
150 if (p->value != (char *) NULL)
151 p->value=DestroyString(p->value);
152 if (p->name != (char *) NULL)
153 p->name=DestroyString(p->name);
154 if (p->path != (char *) NULL)
155 p->path=DestroyString(p->path);
156 }
cristy3ed852e2009-09-05 21:47:34 +0000157 p=(ConfigureInfo *) RelinquishMagickMemory(p);
158 return((void *) NULL);
159}
160
cristy5ff4eaf2011-09-03 01:38:02 +0000161MagickPrivate void ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000162{
cristy18b17442009-10-25 18:36:48 +0000163 if (configure_semaphore == (SemaphoreInfo *) NULL)
164 AcquireSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000165 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000166 if (configure_list != (LinkedListInfo *) NULL)
167 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
168 configure_list=(LinkedListInfo *) NULL;
169 instantiate_configure=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000170 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000171 DestroySemaphoreInfo(&configure_semaphore);
172}
173
174/*
175%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
176% %
177% %
178% %
179% D e s t r o y C o n f i g u r e O p t i o n s %
180% %
181% %
182% %
183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184%
185% DestroyConfigureOptions() releases memory associated with an configure
186% options.
187%
188% The format of the DestroyProfiles method is:
189%
190% LinkedListInfo *DestroyConfigureOptions(Image *image)
191%
192% A description of each parameter follows:
193%
194% o image: the image.
195%
196*/
197
198static void *DestroyOptions(void *option)
199{
200 return(DestroyStringInfo((StringInfo *) option));
201}
202
203MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
204{
205 assert(options != (LinkedListInfo *) NULL);
206 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
207 return(DestroyLinkedList(options,DestroyOptions));
208}
209
210/*
211%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
212% %
213% %
214% %
215+ G e t C o n f i g u r e I n f o %
216% %
217% %
218% %
219%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220%
221% GetConfigureInfo() searches the configure list for the specified name and if
222% found returns attributes for that element.
223%
224% The format of the GetConfigureInfo method is:
225%
226% const ConfigureInfo *GetConfigureInfo(const char *name,
227% ExceptionInfo *exception)
228%
229% A description of each parameter follows:
230%
231% o configure_info: GetConfigureInfo() searches the configure list for the
232% specified name and if found returns attributes for that element.
233%
234% o name: the configure name.
235%
236% o exception: return any errors or warnings in this structure.
237%
238*/
239MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
240 ExceptionInfo *exception)
241{
242 register const ConfigureInfo
243 *p;
244
245 assert(exception != (ExceptionInfo *) NULL);
246 if ((configure_list == (LinkedListInfo *) NULL) ||
247 (instantiate_configure == MagickFalse))
248 if (InitializeConfigureList(exception) == MagickFalse)
249 return((const ConfigureInfo *) NULL);
250 if ((configure_list == (LinkedListInfo *) NULL) ||
251 (IsLinkedListEmpty(configure_list) != MagickFalse))
252 return((const ConfigureInfo *) NULL);
253 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
254 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
255 /*
256 Search for configure tag.
257 */
cristyf84a1932010-01-03 18:00:18 +0000258 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000259 ResetLinkedListIterator(configure_list);
260 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
261 while (p != (const ConfigureInfo *) NULL)
262 {
263 if (LocaleCompare(name,p->name) == 0)
264 break;
265 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
266 }
267 if (p != (ConfigureInfo *) NULL)
268 (void) InsertValueInLinkedList(configure_list,0,
269 RemoveElementByValueFromLinkedList(configure_list,p));
cristyf84a1932010-01-03 18:00:18 +0000270 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000271 return(p);
272}
273
274/*
275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
276% %
277% %
278% %
279% G e t C o n f i g u r e I n f o L i s t %
280% %
281% %
282% %
283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284%
285% GetConfigureInfoList() returns any configure options that match the
286% specified pattern.
287%
288% The format of the GetConfigureInfoList function is:
289%
290% const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000291% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000292%
293% A description of each parameter follows:
294%
295% o pattern: Specifies a pointer to a text string containing a pattern.
296%
297% o number_options: This integer returns the number of configure options in
298% the list.
299%
300% o exception: return any errors or warnings in this structure.
301%
302*/
303
304#if defined(__cplusplus) || defined(c_plusplus)
305extern "C" {
306#endif
307
308static int ConfigureInfoCompare(const void *x,const void *y)
309{
310 const ConfigureInfo
311 **p,
312 **q;
313
314 p=(const ConfigureInfo **) x,
315 q=(const ConfigureInfo **) y;
316 if (LocaleCompare((*p)->path,(*q)->path) == 0)
317 return(LocaleCompare((*p)->name,(*q)->name));
318 return(LocaleCompare((*p)->path,(*q)->path));
319}
320
321#if defined(__cplusplus) || defined(c_plusplus)
322}
323#endif
324
325MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000326 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000327{
328 const ConfigureInfo
329 **options;
330
331 register const ConfigureInfo
332 *p;
333
cristybb503372010-05-27 20:51:26 +0000334 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000335 i;
336
337 /*
338 Allocate configure list.
339 */
340 assert(pattern != (char *) NULL);
341 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000342 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000343 *number_options=0;
344 p=GetConfigureInfo("*",exception);
345 if (p == (const ConfigureInfo *) NULL)
346 return((const ConfigureInfo **) NULL);
347 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
348 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
349 if (options == (const ConfigureInfo **) NULL)
350 return((const ConfigureInfo **) NULL);
351 /*
352 Generate configure list.
353 */
cristyf84a1932010-01-03 18:00:18 +0000354 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000355 ResetLinkedListIterator(configure_list);
356 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
357 for (i=0; p != (const ConfigureInfo *) NULL; )
358 {
359 if ((p->stealth == MagickFalse) &&
360 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
361 options[i++]=p;
362 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
363 }
cristyf84a1932010-01-03 18:00:18 +0000364 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000365 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
366 options[i]=(ConfigureInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000367 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000368 return(options);
369}
370
371/*
372%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373% %
374% %
375% %
376% G e t C o n f i g u r e L i s t %
377% %
378% %
379% %
380%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381%
382% GetConfigureList() returns any configure options that match the specified
383% pattern.
384%
385% The format of the GetConfigureList function is:
386%
387% char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000388% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000389%
390% A description of each parameter follows:
391%
392% o pattern: Specifies a pointer to a text string containing a pattern.
393%
394% o number_options: This integer returns the number of options in the list.
395%
396% o exception: return any errors or warnings in this structure.
397%
398*/
399
400#if defined(__cplusplus) || defined(c_plusplus)
401extern "C" {
402#endif
403
404static int ConfigureCompare(const void *x,const void *y)
405{
406 register char
407 **p,
408 **q;
409
410 p=(char **) x;
411 q=(char **) y;
412 return(LocaleCompare(*p,*q));
413}
414
415#if defined(__cplusplus) || defined(c_plusplus)
416}
417#endif
418
419MagickExport char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000420 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000421{
422 char
423 **options;
424
425 register const ConfigureInfo
426 *p;
427
cristybb503372010-05-27 20:51:26 +0000428 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000429 i;
430
431 /*
432 Allocate configure list.
433 */
434 assert(pattern != (char *) NULL);
435 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000436 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000437 *number_options=0;
438 p=GetConfigureInfo("*",exception);
439 if (p == (const ConfigureInfo *) NULL)
440 return((char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000441 options=(char **) AcquireQuantumMemory((size_t)
442 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
443 if (options == (char **) NULL)
444 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000445 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000446 ResetLinkedListIterator(configure_list);
447 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
448 for (i=0; p != (const ConfigureInfo *) NULL; )
449 {
450 if ((p->stealth == MagickFalse) &&
451 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
452 options[i++]=ConstantString(p->name);
453 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
454 }
cristyf84a1932010-01-03 18:00:18 +0000455 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000456 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
457 options[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000458 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000459 return(options);
460}
461
462/*
463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464% %
465% %
466% %
467% G e t C o n f i g u r e O p t i o n %
468% %
469% %
470% %
471%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
472%
473% GetConfigureOption() returns the value associated with the configure option.
474%
475% The format of the GetConfigureOption method is:
476%
477% char *GetConfigureOption(const char *option)
478%
479% A description of each parameter follows:
480%
481% o configure_info: The configure info.
482%
483*/
484MagickExport char *GetConfigureOption(const char *option)
485{
486 const char
487 *value;
488
489 const ConfigureInfo
490 *configure_info;
491
492 ExceptionInfo
493 *exception;
494
495 assert(option != (const char *) NULL);
496 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
497 exception=AcquireExceptionInfo();
498 configure_info=GetConfigureInfo(option,exception);
499 exception=DestroyExceptionInfo(exception);
500 if (configure_info == (ConfigureInfo *) NULL)
501 return((char *) NULL);
502 value=GetConfigureValue(configure_info);
503 if ((value == (const char *) NULL) || (*value == '\0'))
504 return((char *) NULL);
505 return(ConstantString(value));
506}
507
508/*
509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510% %
511% %
512% %
513% G e t C o n f i g u r e O p t i o n s %
514% %
515% %
516% %
517%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
518%
519% GetConfigureOptions() returns any Magick configuration options associated
520% with the specified filename.
521%
522% The format of the GetConfigureOptions method is:
523%
524% LinkedListInfo *GetConfigureOptions(const char *filename,
525% ExceptionInfo *exception)
526%
527% A description of each parameter follows:
528%
529% o filename: the configure file name.
530%
531% o exception: return any errors or warnings in this structure.
532%
533*/
534MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
535 ExceptionInfo *exception)
536{
537 char
538 path[MaxTextExtent];
539
540 const char
541 *element;
542
543 LinkedListInfo
544 *options,
545 *paths;
546
547 StringInfo
548 *xml;
549
550 assert(filename != (const char *) NULL);
551 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
552 assert(exception != (ExceptionInfo *) NULL);
553 (void) CopyMagickString(path,filename,MaxTextExtent);
554 /*
555 Load XML from configuration files to linked-list.
556 */
557 options=NewLinkedList(0);
558 paths=GetConfigurePaths(filename,exception);
559 if (paths != (LinkedListInfo *) NULL)
560 {
561 ResetLinkedListIterator(paths);
562 element=(const char *) GetNextValueInLinkedList(paths);
563 while (element != (const char *) NULL)
564 {
cristyb51dff52011-05-19 16:55:47 +0000565 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
cristy3ed852e2009-09-05 21:47:34 +0000566 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
567 "Searching for configure file: \"%s\"",path);
568 xml=ConfigureFileToStringInfo(path);
569 if (xml != (StringInfo *) NULL)
570 (void) AppendValueToLinkedList(options,xml);
571 element=(const char *) GetNextValueInLinkedList(paths);
572 }
573 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
574 }
cristy0157aea2010-04-24 21:12:18 +0000575#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000576 {
577 char
578 *blob;
579
580 blob=(char *) NTResourceToBlob(filename);
581 if (blob != (char *) NULL)
582 {
583 xml=StringToStringInfo(blob);
584 SetStringInfoPath(xml,filename);
585 (void) AppendValueToLinkedList(options,xml);
586 blob=DestroyString(blob);
587 }
588 }
589#endif
590 if (GetNumberOfElementsInLinkedList(options) == 0)
591 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
592 "UnableToOpenConfigureFile","`%s'",filename);
593 ResetLinkedListIterator(options);
594 return(options);
595}
596
597/*
598%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
599% %
600% %
601% %
602% G e t C o n f i g u r e P a t h s %
603% %
604% %
605% %
606%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
607%
608% GetConfigurePaths() returns any Magick configuration paths associated
609% with the specified filename.
610%
611% The format of the GetConfigurePaths method is:
612%
613% LinkedListInfo *GetConfigurePaths(const char *filename,
614% ExceptionInfo *exception)
615%
616% A description of each parameter follows:
617%
618% o filename: the configure file name.
619%
620% o exception: return any errors or warnings in this structure.
621%
622*/
623MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
624 ExceptionInfo *exception)
625{
626 char
627 path[MaxTextExtent];
628
629 LinkedListInfo
630 *paths;
631
632 assert(filename != (const char *) NULL);
633 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
634 assert(exception != (ExceptionInfo *) NULL);
635 (void) CopyMagickString(path,filename,MaxTextExtent);
636 paths=NewLinkedList(0);
637 {
638 char
639 *configure_path;
640
641 /*
642 Search $MAGICK_CONFIGURE_PATH.
643 */
644 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
645 if (configure_path != (char *) NULL)
646 {
647 register char
648 *p,
649 *q;
650
651 for (p=configure_path-1; p != (char *) NULL; )
652 {
653 (void) CopyMagickString(path,p+1,MaxTextExtent);
654 q=strchr(path,DirectoryListSeparator);
655 if (q != (char *) NULL)
656 *q='\0';
657 q=path+strlen(path)-1;
658 if ((q >= path) && (*q != *DirectorySeparator))
659 (void) ConcatenateMagickString(path,DirectorySeparator,
660 MaxTextExtent);
661 (void) AppendValueToLinkedList(paths,ConstantString(path));
662 p=strchr(p+1,DirectoryListSeparator);
663 }
664 configure_path=DestroyString(configure_path);
665 }
666 }
667#if defined(MAGICKCORE_INSTALLED_SUPPORT)
cristy4f820712011-04-01 12:35:43 +0000668#if defined(MAGICKCORE_SHARE_PATH)
cristy3ed852e2009-09-05 21:47:34 +0000669 (void) AppendValueToLinkedList(paths,ConstantString(
cristy4f820712011-04-01 12:35:43 +0000670 MAGICKCORE_SHARE_PATH));
cristy3ed852e2009-09-05 21:47:34 +0000671#endif
672#if defined(MAGICKCORE_CONFIGURE_PATH)
673 (void) AppendValueToLinkedList(paths,ConstantString(
674 MAGICKCORE_CONFIGURE_PATH));
675#endif
676#if defined(MAGICKCORE_DOCUMENTATION_PATH)
677 (void) AppendValueToLinkedList(paths,ConstantString(
678 MAGICKCORE_DOCUMENTATION_PATH));
679#endif
cristy4f820712011-04-01 12:35:43 +0000680#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
cristy3ed852e2009-09-05 21:47:34 +0000681 {
682 char
683 *registry_key;
684
685 unsigned char
686 *key_value;
687
688 /*
689 Locate file via registry key.
690 */
691 registry_key="ConfigurePath";
692 key_value=NTRegistryKeyLookup(registry_key);
693 if (key_value != (unsigned char *) NULL)
694 {
cristyb51dff52011-05-19 16:55:47 +0000695 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
cristy3ed852e2009-09-05 21:47:34 +0000696 DirectorySeparator);
697 (void) AppendValueToLinkedList(paths,ConstantString(path));
698 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
699 }
700 }
701#endif
702#else
703 {
704 char
705 *home;
706
707 /*
708 Search under MAGICK_HOME.
709 */
710 home=GetEnvironmentValue("MAGICK_HOME");
711 if (home != (char *) NULL)
712 {
713#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000714 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000715 DirectorySeparator);
716 (void) AppendValueToLinkedList(paths,ConstantString(path));
717#else
cristyb51dff52011-05-19 16:55:47 +0000718 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
cristy3ed852e2009-09-05 21:47:34 +0000719 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
720 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000721 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
cristy4f820712011-04-01 12:35:43 +0000722 MAGICKCORE_SHARE_RELATIVE_PATH);
cristy3ed852e2009-09-05 21:47:34 +0000723 (void) AppendValueToLinkedList(paths,ConstantString(path));
724#endif
725 home=DestroyString(home);
726 }
727 }
728 if (*GetClientPath() != '\0')
729 {
730#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000731 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +0000732 DirectorySeparator);
733 (void) AppendValueToLinkedList(paths,ConstantString(path));
734#else
735 char
736 prefix[MaxTextExtent];
737
738 /*
739 Search based on executable directory if directory is known.
740 */
741 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
742 ChopPathComponents(prefix,1);
cristyb51dff52011-05-19 16:55:47 +0000743 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
cristy3ed852e2009-09-05 21:47:34 +0000744 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
745 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000746 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
cristy4f820712011-04-01 12:35:43 +0000747 MAGICKCORE_SHARE_RELATIVE_PATH);
748 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristy3ed852e2009-09-05 21:47:34 +0000749#endif
750 }
cristy51b1ac52010-10-30 02:27:14 +0000751 /*
752 Search current directory.
753 */
754 (void) AppendValueToLinkedList(paths,ConstantString(""));
cristy3ed852e2009-09-05 21:47:34 +0000755#endif
756 {
757 char
758 *home;
759
760 home=GetEnvironmentValue("HOME");
761 if (home == (char *) NULL)
762 home=GetEnvironmentValue("USERPROFILE");
763 if (home != (char *) NULL)
764 {
765 /*
766 Search $HOME/.magick.
767 */
cristyb51dff52011-05-19 16:55:47 +0000768 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000769 DirectorySeparator,DirectorySeparator);
770 (void) AppendValueToLinkedList(paths,ConstantString(path));
771 home=DestroyString(home);
772 }
773 }
cristy0157aea2010-04-24 21:12:18 +0000774#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000775 {
776 char
777 module_path[MaxTextExtent];
778
779 if ((NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse) ||
780 (NTGetModulePath("CORE_DB_magick_.dll",module_path) != MagickFalse))
781 {
782 char
783 *element;
784
785 /*
786 Search module path.
787 */
cristyb51dff52011-05-19 16:55:47 +0000788 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000789 DirectorySeparator);
790 element=(char *) RemoveElementByValueFromLinkedList(paths,path);
791 if (element != (char *) NULL)
792 element=DestroyString(element);
793 (void) AppendValueToLinkedList(paths,ConstantString(path));
794 }
795 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
796 {
797 /*
798 Search PerlMagick module path.
799 */
cristyb51dff52011-05-19 16:55:47 +0000800 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000801 DirectorySeparator);
802 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000803 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000804 "\\inc\\lib\\auto\\Image\\Magick\\");
805 (void) AppendValueToLinkedList(paths,ConstantString(path));
806 }
807 }
808#endif
cristy3ed852e2009-09-05 21:47:34 +0000809 return(paths);
810}
811
812/*
813%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
814% %
815% %
816% %
817% G e t C o n f i g u r e V a l u e %
818% %
819% %
820% %
821%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822%
823% GetConfigureValue() returns the value associated with the configure info.
824%
825% The format of the GetConfigureValue method is:
826%
827% const char *GetConfigureValue(const ConfigureInfo *configure_info)
828%
829% A description of each parameter follows:
830%
831% o configure_info: The configure info.
832%
833*/
834MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
835{
836 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
837 assert(configure_info != (ConfigureInfo *) NULL);
838 assert(configure_info->signature == MagickSignature);
839 return(configure_info->value);
840}
841
842/*
843%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
844% %
845% %
846% %
847+ I n i t i a l i z e C o n f i g u r e L i s t %
848% %
849% %
850% %
851%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852%
853% InitializeConfigureList() initializes the configure list.
854%
855% The format of the InitializeConfigureList method is:
856%
857% MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
858%
859% A description of each parameter follows.
860%
861% o exception: return any errors or warnings in this structure.
862%
863*/
864static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
865{
866 if ((configure_list == (LinkedListInfo *) NULL) &&
867 (instantiate_configure == MagickFalse))
868 {
cristy4e1dff62009-10-25 20:36:03 +0000869 if (configure_semaphore == (SemaphoreInfo *) NULL)
870 AcquireSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000871 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000872 if ((configure_list == (LinkedListInfo *) NULL) &&
873 (instantiate_configure == MagickFalse))
874 {
875 (void) LoadConfigureLists(ConfigureFilename,exception);
876 instantiate_configure=MagickTrue;
877 }
cristyf84a1932010-01-03 18:00:18 +0000878 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000879 }
880 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
881}
882
883/*
884%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885% %
886% %
887% %
cristy3ed852e2009-09-05 21:47:34 +0000888% L i s t C o n f i g u r e I n f o %
889% %
890% %
891% %
892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893%
894% ListConfigureInfo() lists the configure info to a file.
895%
896% The format of the ListConfigureInfo method is:
897%
898% MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
899%
900% A description of each parameter follows.
901%
902% o file: An pointer to a FILE.
903%
904% o exception: return any errors or warnings in this structure.
905%
906*/
907MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
908 ExceptionInfo *exception)
909{
910 const char
911 *name,
912 *path,
913 *value;
914
915 const ConfigureInfo
916 **configure_info;
917
cristybb503372010-05-27 20:51:26 +0000918 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000919 i;
920
cristybb503372010-05-27 20:51:26 +0000921 size_t
cristy3ed852e2009-09-05 21:47:34 +0000922 number_options;
923
cristy9d314ff2011-03-09 01:30:28 +0000924 ssize_t
925 j;
926
cristy3ed852e2009-09-05 21:47:34 +0000927 if (file == (const FILE *) NULL)
928 file=stdout;
929 configure_info=GetConfigureInfoList("*",&number_options,exception);
930 if (configure_info == (const ConfigureInfo **) NULL)
931 return(MagickFalse);
932 path=(const char *) NULL;
cristybb503372010-05-27 20:51:26 +0000933 for (i=0; i < (ssize_t) number_options; i++)
cristy3ed852e2009-09-05 21:47:34 +0000934 {
935 if (configure_info[i]->stealth != MagickFalse)
936 continue;
937 if ((path == (const char *) NULL) ||
938 (LocaleCompare(path,configure_info[i]->path) != 0))
939 {
940 if (configure_info[i]->path != (char *) NULL)
cristy1e604812011-05-19 18:07:50 +0000941 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
942 configure_info[i]->path);
cristyb51dff52011-05-19 16:55:47 +0000943 (void) FormatLocaleFile(file,"Name Value\n");
cristy1e604812011-05-19 18:07:50 +0000944 (void) FormatLocaleFile(file,
945 "-------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000946 "------------------------------\n");
947 }
948 path=configure_info[i]->path;
949 name="unknown";
950 if (configure_info[i]->name != (char *) NULL)
951 name=configure_info[i]->name;
cristyb51dff52011-05-19 16:55:47 +0000952 (void) FormatLocaleFile(file,"%s",name);
cristybb503372010-05-27 20:51:26 +0000953 for (j=(ssize_t) strlen(name); j <= 12; j++)
cristyb51dff52011-05-19 16:55:47 +0000954 (void) FormatLocaleFile(file," ");
955 (void) FormatLocaleFile(file," ");
cristy3ed852e2009-09-05 21:47:34 +0000956 value="unknown";
957 if (configure_info[i]->value != (char *) NULL)
958 value=configure_info[i]->value;
cristyb51dff52011-05-19 16:55:47 +0000959 (void) FormatLocaleFile(file,"%s",value);
960 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +0000961 }
962 (void) fflush(file);
963 configure_info=(const ConfigureInfo **)
964 RelinquishMagickMemory((void *) configure_info);
965 return(MagickTrue);
966}
967
968/*
969%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
970% %
971% %
972% %
973+ L o a d C o n f i g u r e L i s t %
974% %
975% %
976% %
977%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978%
979% LoadConfigureList() loads the configure configuration file which provides a
980% mapping between configure attributes and a configure name.
981%
982% The format of the LoadConfigureList method is:
983%
984% MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000985% const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000986%
987% A description of each parameter follows:
988%
989% o xml: The configure list in XML format.
990%
991% o filename: The configure list filename.
992%
993% o depth: depth of <include /> statements.
994%
995% o exception: return any errors or warnings in this structure.
996%
997*/
998static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000999 const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001000{
1001 char
1002 keyword[MaxTextExtent],
1003 *token;
1004
1005 ConfigureInfo
1006 *configure_info;
1007
1008 const char
1009 *q;
1010
1011 MagickBooleanType
1012 status;
1013
1014 /*
1015 Load the configure map file.
1016 */
1017 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1018 "Loading configure file \"%s\" ...",filename);
1019 if (configure_list == (LinkedListInfo *) NULL)
1020 {
1021 configure_list=NewLinkedList(0);
1022 if (configure_list == (LinkedListInfo *) NULL)
1023 {
1024 ThrowFileException(exception,ResourceLimitError,
1025 "MemoryAllocationFailed",filename);
1026 return(MagickFalse);
1027 }
1028 }
1029 status=MagickTrue;
1030 configure_info=(ConfigureInfo *) NULL;
cristy54a531d2009-10-21 17:58:01 +00001031 token=AcquireString((char *) xml);
cristy3ed852e2009-09-05 21:47:34 +00001032 for (q=(char *) xml; *q != '\0'; )
1033 {
1034 /*
1035 Interpret XML.
1036 */
1037 GetMagickToken(q,&q,token);
1038 if (*token == '\0')
1039 break;
1040 (void) CopyMagickString(keyword,token,MaxTextExtent);
1041 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1042 {
1043 /*
1044 Doctype element.
1045 */
1046 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1047 GetMagickToken(q,&q,token);
1048 continue;
1049 }
1050 if (LocaleNCompare(keyword,"<!--",4) == 0)
1051 {
1052 /*
1053 Comment element.
1054 */
1055 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1056 GetMagickToken(q,&q,token);
1057 continue;
1058 }
1059 if (LocaleCompare(keyword,"<include") == 0)
1060 {
1061 /*
1062 Include element.
1063 */
1064 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1065 {
1066 (void) CopyMagickString(keyword,token,MaxTextExtent);
1067 GetMagickToken(q,&q,token);
1068 if (*token != '=')
1069 continue;
1070 GetMagickToken(q,&q,token);
1071 if (LocaleCompare(keyword,"file") == 0)
1072 {
1073 if (depth > 200)
1074 (void) ThrowMagickException(exception,GetMagickModule(),
1075 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1076 else
1077 {
1078 char
1079 path[MaxTextExtent],
1080 *xml;
1081
1082 GetPathComponent(filename,HeadPath,path);
1083 if (*path != '\0')
1084 (void) ConcatenateMagickString(path,DirectorySeparator,
1085 MaxTextExtent);
1086 if (*token == *DirectorySeparator)
1087 (void) CopyMagickString(path,token,MaxTextExtent);
1088 else
1089 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1090 xml=FileToString(path,~0,exception);
1091 if (xml != (char *) NULL)
1092 {
1093 status=LoadConfigureList(xml,path,depth+1,exception);
1094 xml=(char *) RelinquishMagickMemory(xml);
1095 }
1096 }
1097 }
1098 }
1099 continue;
1100 }
1101 if (LocaleCompare(keyword,"<configure") == 0)
1102 {
1103 /*
1104 Configure element.
1105 */
1106 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1107 sizeof(*configure_info));
1108 if (configure_info == (ConfigureInfo *) NULL)
1109 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1110 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1111 configure_info->path=ConstantString(filename);
cristy54a531d2009-10-21 17:58:01 +00001112 configure_info->exempt=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +00001113 configure_info->signature=MagickSignature;
1114 continue;
1115 }
1116 if (configure_info == (ConfigureInfo *) NULL)
1117 continue;
1118 if (LocaleCompare(keyword,"/>") == 0)
1119 {
1120 status=AppendValueToLinkedList(configure_list,configure_info);
1121 if (status == MagickFalse)
1122 (void) ThrowMagickException(exception,GetMagickModule(),
1123 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1124 configure_info->name);
1125 configure_info=(ConfigureInfo *) NULL;
1126 }
1127 /*
1128 Parse configure element.
1129 */
1130 GetMagickToken(q,(const char **) NULL,token);
1131 if (*token != '=')
1132 continue;
1133 GetMagickToken(q,&q,token);
1134 GetMagickToken(q,&q,token);
1135 switch (*keyword)
1136 {
1137 case 'N':
1138 case 'n':
1139 {
1140 if (LocaleCompare((char *) keyword,"name") == 0)
1141 {
1142 configure_info->name=ConstantString(token);
1143 break;
1144 }
1145 break;
1146 }
1147 case 'S':
1148 case 's':
1149 {
1150 if (LocaleCompare((char *) keyword,"stealth") == 0)
1151 {
1152 configure_info->stealth=IsMagickTrue(token);
1153 break;
1154 }
1155 break;
1156 }
1157 case 'V':
1158 case 'v':
1159 {
1160 if (LocaleCompare((char *) keyword,"value") == 0)
1161 {
1162 configure_info->value=ConstantString(token);
1163 break;
1164 }
1165 break;
1166 }
1167 default:
1168 break;
1169 }
1170 }
1171 token=(char *) RelinquishMagickMemory(token);
1172 return(status);
1173}
1174
1175/*
1176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1177% %
1178% %
1179% %
1180% L o a d C o n f i g u r e L i s t s %
1181% %
1182% %
1183% %
1184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1185%
1186% LoadConfigureList() loads one or more configure configuration files which
1187% provides a mapping between configure attributes and a configure name.
1188%
1189% The format of the LoadConfigureLists method is:
1190%
1191% MagickBooleanType LoadConfigureLists(const char *filename,
1192% ExceptionInfo *exception)
1193%
1194% A description of each parameter follows:
1195%
1196% o filename: the font file name.
1197%
1198% o exception: return any errors or warnings in this structure.
1199%
1200*/
1201static MagickBooleanType LoadConfigureLists(const char *filename,
1202 ExceptionInfo *exception)
1203{
cristy3ed852e2009-09-05 21:47:34 +00001204 const StringInfo
1205 *option;
1206
1207 LinkedListInfo
1208 *options;
1209
1210 MagickStatusType
1211 status;
1212
cristybb503372010-05-27 20:51:26 +00001213 register ssize_t
cristy54a531d2009-10-21 17:58:01 +00001214 i;
1215
1216 /*
1217 Load built-in configure map.
1218 */
cristy3ed852e2009-09-05 21:47:34 +00001219 status=MagickFalse;
cristy54a531d2009-10-21 17:58:01 +00001220 if (configure_list == (LinkedListInfo *) NULL)
1221 {
1222 configure_list=NewLinkedList(0);
1223 if (configure_list == (LinkedListInfo *) NULL)
1224 {
1225 ThrowFileException(exception,ResourceLimitError,
1226 "MemoryAllocationFailed",filename);
1227 return(MagickFalse);
1228 }
1229 }
cristybb503372010-05-27 20:51:26 +00001230 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
cristy54a531d2009-10-21 17:58:01 +00001231 {
1232 ConfigureInfo
1233 *configure_info;
1234
1235 register const ConfigureMapInfo
1236 *p;
1237
1238 p=ConfigureMap+i;
1239 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1240 sizeof(*configure_info));
1241 if (configure_info == (ConfigureInfo *) NULL)
1242 {
1243 (void) ThrowMagickException(exception,GetMagickModule(),
1244 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1245 configure_info->name);
1246 continue;
1247 }
1248 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1249 configure_info->path=(char *) "[built-in]";
1250 configure_info->name=(char *) p->name;
1251 configure_info->value=(char *) p->value;
1252 configure_info->exempt=MagickTrue;
1253 configure_info->signature=MagickSignature;
1254 status=AppendValueToLinkedList(configure_list,configure_info);
1255 if (status == MagickFalse)
1256 (void) ThrowMagickException(exception,GetMagickModule(),
1257 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1258 configure_info->name);
1259 }
1260 /*
1261 Load external configure map.
1262 */
cristy3ed852e2009-09-05 21:47:34 +00001263 options=GetConfigureOptions(filename,exception);
1264 option=(const StringInfo *) GetNextValueInLinkedList(options);
1265 while (option != (const StringInfo *) NULL)
1266 {
1267 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1268 GetStringInfoPath(option),0,exception);
1269 option=(const StringInfo *) GetNextValueInLinkedList(options);
1270 }
1271 options=DestroyConfigureOptions(options);
cristy3ed852e2009-09-05 21:47:34 +00001272 return(status != 0 ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +00001273}