blob: 83051b3d5cadab66f2916f4c3393270ba2cadb2b [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"
56#include "MagickCore/xml-tree.h"
cristy3ed852e2009-09-05 21:47:34 +000057
58/*
59 Define declarations.
60*/
61#define ConfigureFilename "configure.xml"
62
63/*
cristy54a531d2009-10-21 17:58:01 +000064 Typedef declarations.
65*/
66typedef struct _ConfigureMapInfo
67{
68 const char
69 *name,
70 *value;
71} ConfigureMapInfo;
72
73/*
cristy3ed852e2009-09-05 21:47:34 +000074 Static declarations.
75*/
cristy54a531d2009-10-21 17:58:01 +000076static const ConfigureMapInfo
77 ConfigureMap[] =
78 {
cristyc03a1b52009-10-23 15:43:36 +000079 { "NAME", "ImageMagick" }
cristy54a531d2009-10-21 17:58:01 +000080 };
cristy3ed852e2009-09-05 21:47:34 +000081
82static LinkedListInfo
83 *configure_list = (LinkedListInfo *) NULL;
84
85static SemaphoreInfo
86 *configure_semaphore = (SemaphoreInfo *) NULL;
87
88static volatile MagickBooleanType
89 instantiate_configure = MagickFalse;
90
91/*
92 Forward declarations.
93*/
94static MagickBooleanType
95 InitializeConfigureList(ExceptionInfo *),
96 LoadConfigureLists(const char *,ExceptionInfo *);
97
98/*
99%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100% %
101% %
102% %
cristyf34a1452009-10-24 22:29:27 +0000103+ 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 +0000104% %
105% %
106% %
107%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108%
cristyf34a1452009-10-24 22:29:27 +0000109% ConfigureComponentGenesis() instantiates the configure component.
cristy3ed852e2009-09-05 21:47:34 +0000110%
cristyf34a1452009-10-24 22:29:27 +0000111% The format of the ConfigureComponentGenesis method is:
cristy3ed852e2009-09-05 21:47:34 +0000112%
cristyf34a1452009-10-24 22:29:27 +0000113% MagickBooleanType ConfigureComponentGenesis(void)
114%
115*/
cristy5ff4eaf2011-09-03 01:38:02 +0000116MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +0000117{
cristy165b6092009-10-26 13:52:10 +0000118 AcquireSemaphoreInfo(&configure_semaphore);
cristyf34a1452009-10-24 22:29:27 +0000119 return(MagickTrue);
120}
121
122/*
123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124% %
125% %
126% %
127+ 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 %
128% %
129% %
130% %
131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132%
133% ConfigureComponentTerminus() destroys the configure component.
134%
135% The format of the ConfigureComponentTerminus method is:
136%
137% ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000138%
139*/
140
141static void *DestroyConfigureElement(void *configure_info)
142{
143 register ConfigureInfo
144 *p;
145
146 p=(ConfigureInfo *) configure_info;
cristy54a531d2009-10-21 17:58:01 +0000147 if (p->exempt == MagickFalse)
148 {
149 if (p->value != (char *) NULL)
150 p->value=DestroyString(p->value);
151 if (p->name != (char *) NULL)
152 p->name=DestroyString(p->name);
153 if (p->path != (char *) NULL)
154 p->path=DestroyString(p->path);
155 }
cristy3ed852e2009-09-05 21:47:34 +0000156 p=(ConfigureInfo *) RelinquishMagickMemory(p);
157 return((void *) NULL);
158}
159
cristy5ff4eaf2011-09-03 01:38:02 +0000160MagickPrivate void ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000161{
cristy18b17442009-10-25 18:36:48 +0000162 if (configure_semaphore == (SemaphoreInfo *) NULL)
163 AcquireSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000164 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000165 if (configure_list != (LinkedListInfo *) NULL)
166 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
167 configure_list=(LinkedListInfo *) NULL;
168 instantiate_configure=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000169 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000170 DestroySemaphoreInfo(&configure_semaphore);
171}
172
173/*
174%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175% %
176% %
177% %
178% D e s t r o y C o n f i g u r e O p t i o n s %
179% %
180% %
181% %
182%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183%
184% DestroyConfigureOptions() releases memory associated with an configure
185% options.
186%
187% The format of the DestroyProfiles method is:
188%
189% LinkedListInfo *DestroyConfigureOptions(Image *image)
190%
191% A description of each parameter follows:
192%
193% o image: the image.
194%
195*/
196
197static void *DestroyOptions(void *option)
198{
199 return(DestroyStringInfo((StringInfo *) option));
200}
201
202MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
203{
204 assert(options != (LinkedListInfo *) NULL);
205 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
206 return(DestroyLinkedList(options,DestroyOptions));
207}
208
209/*
210%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
211% %
212% %
213% %
214+ G e t C o n f i g u r e I n f o %
215% %
216% %
217% %
218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219%
220% GetConfigureInfo() searches the configure list for the specified name and if
221% found returns attributes for that element.
222%
223% The format of the GetConfigureInfo method is:
224%
225% const ConfigureInfo *GetConfigureInfo(const char *name,
226% ExceptionInfo *exception)
227%
228% A description of each parameter follows:
229%
230% o configure_info: GetConfigureInfo() searches the configure list for the
231% specified name and if found returns attributes for that element.
232%
233% o name: the configure name.
234%
235% o exception: return any errors or warnings in this structure.
236%
237*/
238MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
239 ExceptionInfo *exception)
240{
241 register const ConfigureInfo
242 *p;
243
244 assert(exception != (ExceptionInfo *) NULL);
245 if ((configure_list == (LinkedListInfo *) NULL) ||
246 (instantiate_configure == MagickFalse))
247 if (InitializeConfigureList(exception) == MagickFalse)
248 return((const ConfigureInfo *) NULL);
249 if ((configure_list == (LinkedListInfo *) NULL) ||
250 (IsLinkedListEmpty(configure_list) != MagickFalse))
251 return((const ConfigureInfo *) NULL);
252 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
253 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
254 /*
255 Search for configure tag.
256 */
cristyf84a1932010-01-03 18:00:18 +0000257 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000258 ResetLinkedListIterator(configure_list);
259 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
260 while (p != (const ConfigureInfo *) NULL)
261 {
262 if (LocaleCompare(name,p->name) == 0)
263 break;
264 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
265 }
266 if (p != (ConfigureInfo *) NULL)
267 (void) InsertValueInLinkedList(configure_list,0,
268 RemoveElementByValueFromLinkedList(configure_list,p));
cristyf84a1932010-01-03 18:00:18 +0000269 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000270 return(p);
271}
272
273/*
274%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275% %
276% %
277% %
278% G e t C o n f i g u r e I n f o L i s t %
279% %
280% %
281% %
282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283%
284% GetConfigureInfoList() returns any configure options that match the
285% specified pattern.
286%
287% The format of the GetConfigureInfoList function is:
288%
289% const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000290% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000291%
292% A description of each parameter follows:
293%
294% o pattern: Specifies a pointer to a text string containing a pattern.
295%
296% o number_options: This integer returns the number of configure options in
297% the list.
298%
299% o exception: return any errors or warnings in this structure.
300%
301*/
302
303#if defined(__cplusplus) || defined(c_plusplus)
304extern "C" {
305#endif
306
307static int ConfigureInfoCompare(const void *x,const void *y)
308{
309 const ConfigureInfo
310 **p,
311 **q;
312
313 p=(const ConfigureInfo **) x,
314 q=(const ConfigureInfo **) y;
315 if (LocaleCompare((*p)->path,(*q)->path) == 0)
316 return(LocaleCompare((*p)->name,(*q)->name));
317 return(LocaleCompare((*p)->path,(*q)->path));
318}
319
320#if defined(__cplusplus) || defined(c_plusplus)
321}
322#endif
323
324MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000325 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000326{
327 const ConfigureInfo
328 **options;
329
330 register const ConfigureInfo
331 *p;
332
cristybb503372010-05-27 20:51:26 +0000333 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000334 i;
335
336 /*
337 Allocate configure list.
338 */
339 assert(pattern != (char *) NULL);
340 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000341 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000342 *number_options=0;
343 p=GetConfigureInfo("*",exception);
344 if (p == (const ConfigureInfo *) NULL)
345 return((const ConfigureInfo **) NULL);
346 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
347 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
348 if (options == (const ConfigureInfo **) NULL)
349 return((const ConfigureInfo **) NULL);
350 /*
351 Generate configure list.
352 */
cristyf84a1932010-01-03 18:00:18 +0000353 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000354 ResetLinkedListIterator(configure_list);
355 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
356 for (i=0; p != (const ConfigureInfo *) NULL; )
357 {
358 if ((p->stealth == MagickFalse) &&
359 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
360 options[i++]=p;
361 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
362 }
cristyf84a1932010-01-03 18:00:18 +0000363 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000364 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
365 options[i]=(ConfigureInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000366 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000367 return(options);
368}
369
370/*
371%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372% %
373% %
374% %
375% G e t C o n f i g u r e L i s t %
376% %
377% %
378% %
379%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380%
381% GetConfigureList() returns any configure options that match the specified
382% pattern.
383%
384% The format of the GetConfigureList function is:
385%
386% char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000387% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000388%
389% A description of each parameter follows:
390%
391% o pattern: Specifies a pointer to a text string containing a pattern.
392%
393% o number_options: This integer returns the number of options in the list.
394%
395% o exception: return any errors or warnings in this structure.
396%
397*/
398
399#if defined(__cplusplus) || defined(c_plusplus)
400extern "C" {
401#endif
402
403static int ConfigureCompare(const void *x,const void *y)
404{
405 register char
406 **p,
407 **q;
408
409 p=(char **) x;
410 q=(char **) y;
411 return(LocaleCompare(*p,*q));
412}
413
414#if defined(__cplusplus) || defined(c_plusplus)
415}
416#endif
417
418MagickExport char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000419 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000420{
421 char
422 **options;
423
424 register const ConfigureInfo
425 *p;
426
cristybb503372010-05-27 20:51:26 +0000427 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000428 i;
429
430 /*
431 Allocate configure list.
432 */
433 assert(pattern != (char *) NULL);
434 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000435 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000436 *number_options=0;
437 p=GetConfigureInfo("*",exception);
438 if (p == (const ConfigureInfo *) NULL)
439 return((char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000440 options=(char **) AcquireQuantumMemory((size_t)
441 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
442 if (options == (char **) NULL)
443 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000444 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000445 ResetLinkedListIterator(configure_list);
446 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
447 for (i=0; p != (const ConfigureInfo *) NULL; )
448 {
449 if ((p->stealth == MagickFalse) &&
450 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
451 options[i++]=ConstantString(p->name);
452 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
453 }
cristyf84a1932010-01-03 18:00:18 +0000454 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000455 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
456 options[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000457 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000458 return(options);
459}
460
461/*
462%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
463% %
464% %
465% %
466% G e t C o n f i g u r e O p t i o n %
467% %
468% %
469% %
470%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
471%
472% GetConfigureOption() returns the value associated with the configure option.
473%
474% The format of the GetConfigureOption method is:
475%
476% char *GetConfigureOption(const char *option)
477%
478% A description of each parameter follows:
479%
480% o configure_info: The configure info.
481%
482*/
483MagickExport char *GetConfigureOption(const char *option)
484{
485 const char
486 *value;
487
488 const ConfigureInfo
489 *configure_info;
490
491 ExceptionInfo
492 *exception;
493
494 assert(option != (const char *) NULL);
495 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
496 exception=AcquireExceptionInfo();
497 configure_info=GetConfigureInfo(option,exception);
498 exception=DestroyExceptionInfo(exception);
499 if (configure_info == (ConfigureInfo *) NULL)
500 return((char *) NULL);
501 value=GetConfigureValue(configure_info);
502 if ((value == (const char *) NULL) || (*value == '\0'))
503 return((char *) NULL);
504 return(ConstantString(value));
505}
506
507/*
508%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
509% %
510% %
511% %
512% G e t C o n f i g u r e O p t i o n s %
513% %
514% %
515% %
516%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
517%
518% GetConfigureOptions() returns any Magick configuration options associated
519% with the specified filename.
520%
521% The format of the GetConfigureOptions method is:
522%
523% LinkedListInfo *GetConfigureOptions(const char *filename,
524% ExceptionInfo *exception)
525%
526% A description of each parameter follows:
527%
528% o filename: the configure file name.
529%
530% o exception: return any errors or warnings in this structure.
531%
532*/
533MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
534 ExceptionInfo *exception)
535{
536 char
537 path[MaxTextExtent];
538
539 const char
540 *element;
541
542 LinkedListInfo
543 *options,
544 *paths;
545
546 StringInfo
547 *xml;
548
549 assert(filename != (const char *) NULL);
550 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
551 assert(exception != (ExceptionInfo *) NULL);
552 (void) CopyMagickString(path,filename,MaxTextExtent);
553 /*
554 Load XML from configuration files to linked-list.
555 */
556 options=NewLinkedList(0);
557 paths=GetConfigurePaths(filename,exception);
558 if (paths != (LinkedListInfo *) NULL)
559 {
560 ResetLinkedListIterator(paths);
561 element=(const char *) GetNextValueInLinkedList(paths);
562 while (element != (const char *) NULL)
563 {
cristyb51dff52011-05-19 16:55:47 +0000564 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
cristy3ed852e2009-09-05 21:47:34 +0000565 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
566 "Searching for configure file: \"%s\"",path);
567 xml=ConfigureFileToStringInfo(path);
568 if (xml != (StringInfo *) NULL)
569 (void) AppendValueToLinkedList(options,xml);
570 element=(const char *) GetNextValueInLinkedList(paths);
571 }
572 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
573 }
cristy0157aea2010-04-24 21:12:18 +0000574#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000575 {
576 char
577 *blob;
578
579 blob=(char *) NTResourceToBlob(filename);
580 if (blob != (char *) NULL)
581 {
582 xml=StringToStringInfo(blob);
583 SetStringInfoPath(xml,filename);
584 (void) AppendValueToLinkedList(options,xml);
585 blob=DestroyString(blob);
586 }
587 }
588#endif
589 if (GetNumberOfElementsInLinkedList(options) == 0)
590 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
591 "UnableToOpenConfigureFile","`%s'",filename);
592 ResetLinkedListIterator(options);
593 return(options);
594}
595
596/*
597%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
598% %
599% %
600% %
601% G e t C o n f i g u r e P a t h s %
602% %
603% %
604% %
605%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
606%
607% GetConfigurePaths() returns any Magick configuration paths associated
608% with the specified filename.
609%
610% The format of the GetConfigurePaths method is:
611%
612% LinkedListInfo *GetConfigurePaths(const char *filename,
613% ExceptionInfo *exception)
614%
615% A description of each parameter follows:
616%
617% o filename: the configure file name.
618%
619% o exception: return any errors or warnings in this structure.
620%
621*/
622MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
623 ExceptionInfo *exception)
624{
625 char
626 path[MaxTextExtent];
627
628 LinkedListInfo
629 *paths;
630
631 assert(filename != (const char *) NULL);
632 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
633 assert(exception != (ExceptionInfo *) NULL);
634 (void) CopyMagickString(path,filename,MaxTextExtent);
635 paths=NewLinkedList(0);
636 {
637 char
638 *configure_path;
639
640 /*
641 Search $MAGICK_CONFIGURE_PATH.
642 */
643 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
644 if (configure_path != (char *) NULL)
645 {
646 register char
647 *p,
648 *q;
649
650 for (p=configure_path-1; p != (char *) NULL; )
651 {
652 (void) CopyMagickString(path,p+1,MaxTextExtent);
653 q=strchr(path,DirectoryListSeparator);
654 if (q != (char *) NULL)
655 *q='\0';
656 q=path+strlen(path)-1;
657 if ((q >= path) && (*q != *DirectorySeparator))
658 (void) ConcatenateMagickString(path,DirectorySeparator,
659 MaxTextExtent);
660 (void) AppendValueToLinkedList(paths,ConstantString(path));
661 p=strchr(p+1,DirectoryListSeparator);
662 }
663 configure_path=DestroyString(configure_path);
664 }
665 }
666#if defined(MAGICKCORE_INSTALLED_SUPPORT)
cristy4f820712011-04-01 12:35:43 +0000667#if defined(MAGICKCORE_SHARE_PATH)
cristy3ed852e2009-09-05 21:47:34 +0000668 (void) AppendValueToLinkedList(paths,ConstantString(
cristy4f820712011-04-01 12:35:43 +0000669 MAGICKCORE_SHARE_PATH));
cristy3ed852e2009-09-05 21:47:34 +0000670#endif
671#if defined(MAGICKCORE_CONFIGURE_PATH)
672 (void) AppendValueToLinkedList(paths,ConstantString(
673 MAGICKCORE_CONFIGURE_PATH));
674#endif
675#if defined(MAGICKCORE_DOCUMENTATION_PATH)
676 (void) AppendValueToLinkedList(paths,ConstantString(
677 MAGICKCORE_DOCUMENTATION_PATH));
678#endif
cristy4f820712011-04-01 12:35:43 +0000679#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
cristy3ed852e2009-09-05 21:47:34 +0000680 {
681 char
682 *registry_key;
683
684 unsigned char
685 *key_value;
686
687 /*
688 Locate file via registry key.
689 */
690 registry_key="ConfigurePath";
691 key_value=NTRegistryKeyLookup(registry_key);
692 if (key_value != (unsigned char *) NULL)
693 {
cristyb51dff52011-05-19 16:55:47 +0000694 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
cristy3ed852e2009-09-05 21:47:34 +0000695 DirectorySeparator);
696 (void) AppendValueToLinkedList(paths,ConstantString(path));
697 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
698 }
699 }
700#endif
701#else
702 {
703 char
704 *home;
705
706 /*
707 Search under MAGICK_HOME.
708 */
709 home=GetEnvironmentValue("MAGICK_HOME");
710 if (home != (char *) NULL)
711 {
712#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000713 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000714 DirectorySeparator);
715 (void) AppendValueToLinkedList(paths,ConstantString(path));
716#else
cristyb51dff52011-05-19 16:55:47 +0000717 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
cristy3ed852e2009-09-05 21:47:34 +0000718 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
719 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000720 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
cristy4f820712011-04-01 12:35:43 +0000721 MAGICKCORE_SHARE_RELATIVE_PATH);
cristy3ed852e2009-09-05 21:47:34 +0000722 (void) AppendValueToLinkedList(paths,ConstantString(path));
723#endif
724 home=DestroyString(home);
725 }
726 }
727 if (*GetClientPath() != '\0')
728 {
729#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000730 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +0000731 DirectorySeparator);
732 (void) AppendValueToLinkedList(paths,ConstantString(path));
733#else
734 char
735 prefix[MaxTextExtent];
736
737 /*
738 Search based on executable directory if directory is known.
739 */
740 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
741 ChopPathComponents(prefix,1);
cristyb51dff52011-05-19 16:55:47 +0000742 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
cristy3ed852e2009-09-05 21:47:34 +0000743 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
744 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000745 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
cristy4f820712011-04-01 12:35:43 +0000746 MAGICKCORE_SHARE_RELATIVE_PATH);
747 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristy3ed852e2009-09-05 21:47:34 +0000748#endif
749 }
cristy51b1ac52010-10-30 02:27:14 +0000750 /*
751 Search current directory.
752 */
753 (void) AppendValueToLinkedList(paths,ConstantString(""));
cristy3ed852e2009-09-05 21:47:34 +0000754#endif
755 {
756 char
757 *home;
758
759 home=GetEnvironmentValue("HOME");
760 if (home == (char *) NULL)
761 home=GetEnvironmentValue("USERPROFILE");
762 if (home != (char *) NULL)
763 {
764 /*
765 Search $HOME/.magick.
766 */
cristyb51dff52011-05-19 16:55:47 +0000767 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000768 DirectorySeparator,DirectorySeparator);
769 (void) AppendValueToLinkedList(paths,ConstantString(path));
770 home=DestroyString(home);
771 }
772 }
cristy0157aea2010-04-24 21:12:18 +0000773#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000774 {
775 char
776 module_path[MaxTextExtent];
777
778 if ((NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse) ||
779 (NTGetModulePath("CORE_DB_magick_.dll",module_path) != MagickFalse))
780 {
781 char
782 *element;
783
784 /*
785 Search module path.
786 */
cristyb51dff52011-05-19 16:55:47 +0000787 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000788 DirectorySeparator);
789 element=(char *) RemoveElementByValueFromLinkedList(paths,path);
790 if (element != (char *) NULL)
791 element=DestroyString(element);
792 (void) AppendValueToLinkedList(paths,ConstantString(path));
793 }
794 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
795 {
796 /*
797 Search PerlMagick module path.
798 */
cristyb51dff52011-05-19 16:55:47 +0000799 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000800 DirectorySeparator);
801 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000802 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000803 "\\inc\\lib\\auto\\Image\\Magick\\");
804 (void) AppendValueToLinkedList(paths,ConstantString(path));
805 }
806 }
807#endif
cristy3ed852e2009-09-05 21:47:34 +0000808 return(paths);
809}
810
811/*
812%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
813% %
814% %
815% %
816% G e t C o n f i g u r e V a l u e %
817% %
818% %
819% %
820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821%
822% GetConfigureValue() returns the value associated with the configure info.
823%
824% The format of the GetConfigureValue method is:
825%
826% const char *GetConfigureValue(const ConfigureInfo *configure_info)
827%
828% A description of each parameter follows:
829%
830% o configure_info: The configure info.
831%
832*/
833MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
834{
835 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
836 assert(configure_info != (ConfigureInfo *) NULL);
837 assert(configure_info->signature == MagickSignature);
838 return(configure_info->value);
839}
840
841/*
842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843% %
844% %
845% %
846+ I n i t i a l i z e C o n f i g u r e L i s t %
847% %
848% %
849% %
850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851%
852% InitializeConfigureList() initializes the configure list.
853%
854% The format of the InitializeConfigureList method is:
855%
856% MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
857%
858% A description of each parameter follows.
859%
860% o exception: return any errors or warnings in this structure.
861%
862*/
863static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
864{
865 if ((configure_list == (LinkedListInfo *) NULL) &&
866 (instantiate_configure == MagickFalse))
867 {
cristy4e1dff62009-10-25 20:36:03 +0000868 if (configure_semaphore == (SemaphoreInfo *) NULL)
869 AcquireSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000870 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000871 if ((configure_list == (LinkedListInfo *) NULL) &&
872 (instantiate_configure == MagickFalse))
873 {
874 (void) LoadConfigureLists(ConfigureFilename,exception);
875 instantiate_configure=MagickTrue;
876 }
cristyf84a1932010-01-03 18:00:18 +0000877 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000878 }
879 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
880}
881
882/*
883%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
884% %
885% %
886% %
cristy3ed852e2009-09-05 21:47:34 +0000887% L i s t C o n f i g u r e I n f o %
888% %
889% %
890% %
891%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892%
893% ListConfigureInfo() lists the configure info to a file.
894%
895% The format of the ListConfigureInfo method is:
896%
897% MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
898%
899% A description of each parameter follows.
900%
901% o file: An pointer to a FILE.
902%
903% o exception: return any errors or warnings in this structure.
904%
905*/
906MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
907 ExceptionInfo *exception)
908{
909 const char
910 *name,
911 *path,
912 *value;
913
914 const ConfigureInfo
915 **configure_info;
916
cristybb503372010-05-27 20:51:26 +0000917 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000918 i;
919
cristybb503372010-05-27 20:51:26 +0000920 size_t
cristy3ed852e2009-09-05 21:47:34 +0000921 number_options;
922
cristy9d314ff2011-03-09 01:30:28 +0000923 ssize_t
924 j;
925
cristy3ed852e2009-09-05 21:47:34 +0000926 if (file == (const FILE *) NULL)
927 file=stdout;
928 configure_info=GetConfigureInfoList("*",&number_options,exception);
929 if (configure_info == (const ConfigureInfo **) NULL)
930 return(MagickFalse);
931 path=(const char *) NULL;
cristybb503372010-05-27 20:51:26 +0000932 for (i=0; i < (ssize_t) number_options; i++)
cristy3ed852e2009-09-05 21:47:34 +0000933 {
934 if (configure_info[i]->stealth != MagickFalse)
935 continue;
936 if ((path == (const char *) NULL) ||
937 (LocaleCompare(path,configure_info[i]->path) != 0))
938 {
939 if (configure_info[i]->path != (char *) NULL)
cristy1e604812011-05-19 18:07:50 +0000940 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
941 configure_info[i]->path);
cristyb51dff52011-05-19 16:55:47 +0000942 (void) FormatLocaleFile(file,"Name Value\n");
cristy1e604812011-05-19 18:07:50 +0000943 (void) FormatLocaleFile(file,
944 "-------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000945 "------------------------------\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;
cristyb51dff52011-05-19 16:55:47 +0000951 (void) FormatLocaleFile(file,"%s",name);
cristybb503372010-05-27 20:51:26 +0000952 for (j=(ssize_t) strlen(name); j <= 12; j++)
cristyb51dff52011-05-19 16:55:47 +0000953 (void) FormatLocaleFile(file," ");
954 (void) FormatLocaleFile(file," ");
cristy3ed852e2009-09-05 21:47:34 +0000955 value="unknown";
956 if (configure_info[i]->value != (char *) NULL)
957 value=configure_info[i]->value;
cristyb51dff52011-05-19 16:55:47 +0000958 (void) FormatLocaleFile(file,"%s",value);
959 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +0000960 }
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}