blob: 4fa904e80fb14f3fadc63f5d2e00c6c9104f823b [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"
cristy7832dc22011-09-05 01:21:53 +000054#include "MagickCore/string-private.h"
cristy4c08aed2011-07-01 19:47:50 +000055#include "MagickCore/token.h"
56#include "MagickCore/utility.h"
cristyd1dd6e42011-09-04 01:46:08 +000057#include "MagickCore/utility-private.h"
cristy4c08aed2011-07-01 19:47:50 +000058#include "MagickCore/xml-tree.h"
cristy3ed852e2009-09-05 21:47:34 +000059
60/*
61 Define declarations.
62*/
63#define ConfigureFilename "configure.xml"
64
65/*
cristy54a531d2009-10-21 17:58:01 +000066 Typedef declarations.
67*/
68typedef struct _ConfigureMapInfo
69{
70 const char
71 *name,
72 *value;
73} ConfigureMapInfo;
74
75/*
cristy3ed852e2009-09-05 21:47:34 +000076 Static declarations.
77*/
cristy54a531d2009-10-21 17:58:01 +000078static const ConfigureMapInfo
79 ConfigureMap[] =
80 {
cristyc03a1b52009-10-23 15:43:36 +000081 { "NAME", "ImageMagick" }
cristy54a531d2009-10-21 17:58:01 +000082 };
cristy3ed852e2009-09-05 21:47:34 +000083
84static LinkedListInfo
85 *configure_list = (LinkedListInfo *) NULL;
86
87static SemaphoreInfo
88 *configure_semaphore = (SemaphoreInfo *) NULL;
89
90static volatile MagickBooleanType
91 instantiate_configure = MagickFalse;
92
93/*
94 Forward declarations.
95*/
96static MagickBooleanType
97 InitializeConfigureList(ExceptionInfo *),
98 LoadConfigureLists(const char *,ExceptionInfo *);
99
100/*
101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102% %
103% %
104% %
cristyf34a1452009-10-24 22:29:27 +0000105+ 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 +0000106% %
107% %
108% %
109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110%
cristyf34a1452009-10-24 22:29:27 +0000111% ConfigureComponentGenesis() instantiates the configure component.
cristy3ed852e2009-09-05 21:47:34 +0000112%
cristyf34a1452009-10-24 22:29:27 +0000113% The format of the ConfigureComponentGenesis method is:
cristy3ed852e2009-09-05 21:47:34 +0000114%
cristyf34a1452009-10-24 22:29:27 +0000115% MagickBooleanType ConfigureComponentGenesis(void)
116%
117*/
cristy5ff4eaf2011-09-03 01:38:02 +0000118MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +0000119{
cristy165b6092009-10-26 13:52:10 +0000120 AcquireSemaphoreInfo(&configure_semaphore);
cristyf34a1452009-10-24 22:29:27 +0000121 return(MagickTrue);
122}
123
124/*
125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126% %
127% %
128% %
129+ 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 %
130% %
131% %
132% %
133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134%
135% ConfigureComponentTerminus() destroys the configure component.
136%
137% The format of the ConfigureComponentTerminus method is:
138%
139% ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000140%
141*/
142
143static void *DestroyConfigureElement(void *configure_info)
144{
145 register ConfigureInfo
146 *p;
147
148 p=(ConfigureInfo *) configure_info;
cristy54a531d2009-10-21 17:58:01 +0000149 if (p->exempt == MagickFalse)
150 {
151 if (p->value != (char *) NULL)
152 p->value=DestroyString(p->value);
153 if (p->name != (char *) NULL)
154 p->name=DestroyString(p->name);
155 if (p->path != (char *) NULL)
156 p->path=DestroyString(p->path);
157 }
cristy3ed852e2009-09-05 21:47:34 +0000158 p=(ConfigureInfo *) RelinquishMagickMemory(p);
159 return((void *) NULL);
160}
161
cristy5ff4eaf2011-09-03 01:38:02 +0000162MagickPrivate void ConfigureComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000163{
cristy18b17442009-10-25 18:36:48 +0000164 if (configure_semaphore == (SemaphoreInfo *) NULL)
165 AcquireSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000166 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000167 if (configure_list != (LinkedListInfo *) NULL)
168 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
169 configure_list=(LinkedListInfo *) NULL;
170 instantiate_configure=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000171 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000172 DestroySemaphoreInfo(&configure_semaphore);
173}
174
175/*
176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177% %
178% %
179% %
180% D e s t r o y C o n f i g u r e O p t i o n s %
181% %
182% %
183% %
184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185%
186% DestroyConfigureOptions() releases memory associated with an configure
187% options.
188%
189% The format of the DestroyProfiles method is:
190%
191% LinkedListInfo *DestroyConfigureOptions(Image *image)
192%
193% A description of each parameter follows:
194%
195% o image: the image.
196%
197*/
198
199static void *DestroyOptions(void *option)
200{
201 return(DestroyStringInfo((StringInfo *) option));
202}
203
204MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
205{
206 assert(options != (LinkedListInfo *) NULL);
207 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
208 return(DestroyLinkedList(options,DestroyOptions));
209}
210
211/*
212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213% %
214% %
215% %
216+ G e t C o n f i g u r e I n f o %
217% %
218% %
219% %
220%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221%
222% GetConfigureInfo() searches the configure list for the specified name and if
223% found returns attributes for that element.
224%
225% The format of the GetConfigureInfo method is:
226%
227% const ConfigureInfo *GetConfigureInfo(const char *name,
228% ExceptionInfo *exception)
229%
230% A description of each parameter follows:
231%
232% o configure_info: GetConfigureInfo() searches the configure list for the
233% specified name and if found returns attributes for that element.
234%
235% o name: the configure name.
236%
237% o exception: return any errors or warnings in this structure.
238%
239*/
240MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
241 ExceptionInfo *exception)
242{
243 register const ConfigureInfo
244 *p;
245
246 assert(exception != (ExceptionInfo *) NULL);
247 if ((configure_list == (LinkedListInfo *) NULL) ||
248 (instantiate_configure == MagickFalse))
249 if (InitializeConfigureList(exception) == MagickFalse)
250 return((const ConfigureInfo *) NULL);
251 if ((configure_list == (LinkedListInfo *) NULL) ||
252 (IsLinkedListEmpty(configure_list) != MagickFalse))
253 return((const ConfigureInfo *) NULL);
254 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
255 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
256 /*
257 Search for configure tag.
258 */
cristyf84a1932010-01-03 18:00:18 +0000259 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000260 ResetLinkedListIterator(configure_list);
261 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
262 while (p != (const ConfigureInfo *) NULL)
263 {
264 if (LocaleCompare(name,p->name) == 0)
265 break;
266 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
267 }
268 if (p != (ConfigureInfo *) NULL)
269 (void) InsertValueInLinkedList(configure_list,0,
270 RemoveElementByValueFromLinkedList(configure_list,p));
cristyf84a1932010-01-03 18:00:18 +0000271 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000272 return(p);
273}
274
275/*
276%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277% %
278% %
279% %
280% G e t C o n f i g u r e I n f o L i s t %
281% %
282% %
283% %
284%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285%
286% GetConfigureInfoList() returns any configure options that match the
287% specified pattern.
288%
289% The format of the GetConfigureInfoList function is:
290%
291% const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000292% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000293%
294% A description of each parameter follows:
295%
296% o pattern: Specifies a pointer to a text string containing a pattern.
297%
298% o number_options: This integer returns the number of configure options in
299% the list.
300%
301% o exception: return any errors or warnings in this structure.
302%
303*/
304
305#if defined(__cplusplus) || defined(c_plusplus)
306extern "C" {
307#endif
308
309static int ConfigureInfoCompare(const void *x,const void *y)
310{
311 const ConfigureInfo
312 **p,
313 **q;
314
315 p=(const ConfigureInfo **) x,
316 q=(const ConfigureInfo **) y;
317 if (LocaleCompare((*p)->path,(*q)->path) == 0)
318 return(LocaleCompare((*p)->name,(*q)->name));
319 return(LocaleCompare((*p)->path,(*q)->path));
320}
321
322#if defined(__cplusplus) || defined(c_plusplus)
323}
324#endif
325
326MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000327 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000328{
329 const ConfigureInfo
330 **options;
331
332 register const ConfigureInfo
333 *p;
334
cristybb503372010-05-27 20:51:26 +0000335 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000336 i;
337
338 /*
339 Allocate configure list.
340 */
341 assert(pattern != (char *) NULL);
342 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000343 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000344 *number_options=0;
345 p=GetConfigureInfo("*",exception);
346 if (p == (const ConfigureInfo *) NULL)
347 return((const ConfigureInfo **) NULL);
348 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
349 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
350 if (options == (const ConfigureInfo **) NULL)
351 return((const ConfigureInfo **) NULL);
352 /*
353 Generate configure list.
354 */
cristyf84a1932010-01-03 18:00:18 +0000355 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000356 ResetLinkedListIterator(configure_list);
357 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
358 for (i=0; p != (const ConfigureInfo *) NULL; )
359 {
360 if ((p->stealth == MagickFalse) &&
361 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
362 options[i++]=p;
363 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
364 }
cristyf84a1932010-01-03 18:00:18 +0000365 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000366 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
367 options[i]=(ConfigureInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000368 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000369 return(options);
370}
371
372/*
373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374% %
375% %
376% %
377% G e t C o n f i g u r e L i s t %
378% %
379% %
380% %
381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382%
383% GetConfigureList() returns any configure options that match the specified
384% pattern.
385%
386% The format of the GetConfigureList function is:
387%
388% char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000389% size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000390%
391% A description of each parameter follows:
392%
393% o pattern: Specifies a pointer to a text string containing a pattern.
394%
395% o number_options: This integer returns the number of options in the list.
396%
397% o exception: return any errors or warnings in this structure.
398%
399*/
400
401#if defined(__cplusplus) || defined(c_plusplus)
402extern "C" {
403#endif
404
405static int ConfigureCompare(const void *x,const void *y)
406{
407 register char
408 **p,
409 **q;
410
411 p=(char **) x;
412 q=(char **) y;
413 return(LocaleCompare(*p,*q));
414}
415
416#if defined(__cplusplus) || defined(c_plusplus)
417}
418#endif
419
420MagickExport char **GetConfigureList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000421 size_t *number_options,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000422{
423 char
424 **options;
425
426 register const ConfigureInfo
427 *p;
428
cristybb503372010-05-27 20:51:26 +0000429 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000430 i;
431
432 /*
433 Allocate configure list.
434 */
435 assert(pattern != (char *) NULL);
436 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000437 assert(number_options != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000438 *number_options=0;
439 p=GetConfigureInfo("*",exception);
440 if (p == (const ConfigureInfo *) NULL)
441 return((char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000442 options=(char **) AcquireQuantumMemory((size_t)
443 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
444 if (options == (char **) NULL)
445 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000446 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000447 ResetLinkedListIterator(configure_list);
448 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
449 for (i=0; p != (const ConfigureInfo *) NULL; )
450 {
451 if ((p->stealth == MagickFalse) &&
452 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
453 options[i++]=ConstantString(p->name);
454 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
455 }
cristyf84a1932010-01-03 18:00:18 +0000456 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000457 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
458 options[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000459 *number_options=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000460 return(options);
461}
462
463/*
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465% %
466% %
467% %
468% G e t C o n f i g u r e O p t i o n %
469% %
470% %
471% %
472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473%
474% GetConfigureOption() returns the value associated with the configure option.
475%
476% The format of the GetConfigureOption method is:
477%
478% char *GetConfigureOption(const char *option)
479%
480% A description of each parameter follows:
481%
482% o configure_info: The configure info.
483%
484*/
485MagickExport char *GetConfigureOption(const char *option)
486{
487 const char
488 *value;
489
490 const ConfigureInfo
491 *configure_info;
492
493 ExceptionInfo
494 *exception;
495
496 assert(option != (const char *) NULL);
497 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
498 exception=AcquireExceptionInfo();
499 configure_info=GetConfigureInfo(option,exception);
500 exception=DestroyExceptionInfo(exception);
501 if (configure_info == (ConfigureInfo *) NULL)
502 return((char *) NULL);
503 value=GetConfigureValue(configure_info);
504 if ((value == (const char *) NULL) || (*value == '\0'))
505 return((char *) NULL);
506 return(ConstantString(value));
507}
508
509/*
510%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511% %
512% %
513% %
514% G e t C o n f i g u r e O p t i o n s %
515% %
516% %
517% %
518%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519%
520% GetConfigureOptions() returns any Magick configuration options associated
521% with the specified filename.
522%
523% The format of the GetConfigureOptions method is:
524%
525% LinkedListInfo *GetConfigureOptions(const char *filename,
526% ExceptionInfo *exception)
527%
528% A description of each parameter follows:
529%
530% o filename: the configure file name.
531%
532% o exception: return any errors or warnings in this structure.
533%
534*/
535MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
536 ExceptionInfo *exception)
537{
538 char
539 path[MaxTextExtent];
540
541 const char
542 *element;
543
544 LinkedListInfo
545 *options,
546 *paths;
547
548 StringInfo
549 *xml;
550
551 assert(filename != (const char *) NULL);
552 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
553 assert(exception != (ExceptionInfo *) NULL);
554 (void) CopyMagickString(path,filename,MaxTextExtent);
555 /*
556 Load XML from configuration files to linked-list.
557 */
558 options=NewLinkedList(0);
559 paths=GetConfigurePaths(filename,exception);
560 if (paths != (LinkedListInfo *) NULL)
561 {
562 ResetLinkedListIterator(paths);
563 element=(const char *) GetNextValueInLinkedList(paths);
564 while (element != (const char *) NULL)
565 {
cristyb51dff52011-05-19 16:55:47 +0000566 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
cristy3ed852e2009-09-05 21:47:34 +0000567 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
568 "Searching for configure file: \"%s\"",path);
569 xml=ConfigureFileToStringInfo(path);
570 if (xml != (StringInfo *) NULL)
571 (void) AppendValueToLinkedList(options,xml);
572 element=(const char *) GetNextValueInLinkedList(paths);
573 }
574 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
575 }
cristy0157aea2010-04-24 21:12:18 +0000576#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000577 {
578 char
579 *blob;
580
581 blob=(char *) NTResourceToBlob(filename);
582 if (blob != (char *) NULL)
583 {
584 xml=StringToStringInfo(blob);
585 SetStringInfoPath(xml,filename);
586 (void) AppendValueToLinkedList(options,xml);
587 blob=DestroyString(blob);
588 }
589 }
590#endif
591 if (GetNumberOfElementsInLinkedList(options) == 0)
592 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
593 "UnableToOpenConfigureFile","`%s'",filename);
594 ResetLinkedListIterator(options);
595 return(options);
596}
597
598/*
599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
600% %
601% %
602% %
603% G e t C o n f i g u r e P a t h s %
604% %
605% %
606% %
607%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
608%
609% GetConfigurePaths() returns any Magick configuration paths associated
610% with the specified filename.
611%
612% The format of the GetConfigurePaths method is:
613%
614% LinkedListInfo *GetConfigurePaths(const char *filename,
615% ExceptionInfo *exception)
616%
617% A description of each parameter follows:
618%
619% o filename: the configure file name.
620%
621% o exception: return any errors or warnings in this structure.
622%
623*/
624MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
625 ExceptionInfo *exception)
626{
627 char
628 path[MaxTextExtent];
629
630 LinkedListInfo
631 *paths;
632
633 assert(filename != (const char *) NULL);
634 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
635 assert(exception != (ExceptionInfo *) NULL);
636 (void) CopyMagickString(path,filename,MaxTextExtent);
637 paths=NewLinkedList(0);
638 {
639 char
640 *configure_path;
641
642 /*
643 Search $MAGICK_CONFIGURE_PATH.
644 */
645 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
646 if (configure_path != (char *) NULL)
647 {
648 register char
649 *p,
650 *q;
651
652 for (p=configure_path-1; p != (char *) NULL; )
653 {
654 (void) CopyMagickString(path,p+1,MaxTextExtent);
655 q=strchr(path,DirectoryListSeparator);
656 if (q != (char *) NULL)
657 *q='\0';
658 q=path+strlen(path)-1;
659 if ((q >= path) && (*q != *DirectorySeparator))
660 (void) ConcatenateMagickString(path,DirectorySeparator,
661 MaxTextExtent);
662 (void) AppendValueToLinkedList(paths,ConstantString(path));
663 p=strchr(p+1,DirectoryListSeparator);
664 }
665 configure_path=DestroyString(configure_path);
666 }
667 }
668#if defined(MAGICKCORE_INSTALLED_SUPPORT)
cristy4f820712011-04-01 12:35:43 +0000669#if defined(MAGICKCORE_SHARE_PATH)
cristy3ed852e2009-09-05 21:47:34 +0000670 (void) AppendValueToLinkedList(paths,ConstantString(
cristy4f820712011-04-01 12:35:43 +0000671 MAGICKCORE_SHARE_PATH));
cristy3ed852e2009-09-05 21:47:34 +0000672#endif
673#if defined(MAGICKCORE_CONFIGURE_PATH)
674 (void) AppendValueToLinkedList(paths,ConstantString(
675 MAGICKCORE_CONFIGURE_PATH));
676#endif
677#if defined(MAGICKCORE_DOCUMENTATION_PATH)
678 (void) AppendValueToLinkedList(paths,ConstantString(
679 MAGICKCORE_DOCUMENTATION_PATH));
680#endif
cristy4f820712011-04-01 12:35:43 +0000681#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_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 {
cristyb51dff52011-05-19 16:55:47 +0000696 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
cristy3ed852e2009-09-05 21:47:34 +0000697 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)
cristyb51dff52011-05-19 16:55:47 +0000715 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000716 DirectorySeparator);
717 (void) AppendValueToLinkedList(paths,ConstantString(path));
718#else
cristyb51dff52011-05-19 16:55:47 +0000719 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
cristy3ed852e2009-09-05 21:47:34 +0000720 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
721 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000722 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
cristy4f820712011-04-01 12:35:43 +0000723 MAGICKCORE_SHARE_RELATIVE_PATH);
cristy3ed852e2009-09-05 21:47:34 +0000724 (void) AppendValueToLinkedList(paths,ConstantString(path));
725#endif
726 home=DestroyString(home);
727 }
728 }
729 if (*GetClientPath() != '\0')
730 {
731#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000732 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +0000733 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);
cristyb51dff52011-05-19 16:55:47 +0000744 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
cristy3ed852e2009-09-05 21:47:34 +0000745 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
746 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000747 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
cristy4f820712011-04-01 12:35:43 +0000748 MAGICKCORE_SHARE_RELATIVE_PATH);
749 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristy3ed852e2009-09-05 21:47:34 +0000750#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 */
cristyb51dff52011-05-19 16:55:47 +0000769 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000770 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 */
cristyb51dff52011-05-19 16:55:47 +0000789 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000790 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 */
cristyb51dff52011-05-19 16:55:47 +0000801 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000802 DirectorySeparator);
803 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000804 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000805 "\\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)
cristy1e604812011-05-19 18:07:50 +0000942 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
943 configure_info[i]->path);
cristyb51dff52011-05-19 16:55:47 +0000944 (void) FormatLocaleFile(file,"Name Value\n");
cristy1e604812011-05-19 18:07:50 +0000945 (void) FormatLocaleFile(file,
946 "-------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000947 "------------------------------\n");
948 }
949 path=configure_info[i]->path;
950 name="unknown";
951 if (configure_info[i]->name != (char *) NULL)
952 name=configure_info[i]->name;
cristyb51dff52011-05-19 16:55:47 +0000953 (void) FormatLocaleFile(file,"%s",name);
cristybb503372010-05-27 20:51:26 +0000954 for (j=(ssize_t) strlen(name); j <= 12; j++)
cristyb51dff52011-05-19 16:55:47 +0000955 (void) FormatLocaleFile(file," ");
956 (void) FormatLocaleFile(file," ");
cristy3ed852e2009-09-05 21:47:34 +0000957 value="unknown";
958 if (configure_info[i]->value != (char *) NULL)
959 value=configure_info[i]->value;
cristyb51dff52011-05-19 16:55:47 +0000960 (void) FormatLocaleFile(file,"%s",value);
961 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +0000962 }
963 (void) fflush(file);
964 configure_info=(const ConfigureInfo **)
965 RelinquishMagickMemory((void *) configure_info);
966 return(MagickTrue);
967}
968
969/*
970%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
971% %
972% %
973% %
974+ L o a d C o n f i g u r e L i s t %
975% %
976% %
977% %
978%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
979%
980% LoadConfigureList() loads the configure configuration file which provides a
981% mapping between configure attributes and a configure name.
982%
983% The format of the LoadConfigureList method is:
984%
985% MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000986% const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000987%
988% A description of each parameter follows:
989%
990% o xml: The configure list in XML format.
991%
992% o filename: The configure list filename.
993%
994% o depth: depth of <include /> statements.
995%
996% o exception: return any errors or warnings in this structure.
997%
998*/
999static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +00001000 const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001001{
1002 char
1003 keyword[MaxTextExtent],
1004 *token;
1005
1006 ConfigureInfo
1007 *configure_info;
1008
1009 const char
1010 *q;
1011
1012 MagickBooleanType
1013 status;
1014
1015 /*
1016 Load the configure map file.
1017 */
1018 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1019 "Loading configure file \"%s\" ...",filename);
1020 if (configure_list == (LinkedListInfo *) NULL)
1021 {
1022 configure_list=NewLinkedList(0);
1023 if (configure_list == (LinkedListInfo *) NULL)
1024 {
1025 ThrowFileException(exception,ResourceLimitError,
1026 "MemoryAllocationFailed",filename);
1027 return(MagickFalse);
1028 }
1029 }
1030 status=MagickTrue;
1031 configure_info=(ConfigureInfo *) NULL;
cristy54a531d2009-10-21 17:58:01 +00001032 token=AcquireString((char *) xml);
cristy3ed852e2009-09-05 21:47:34 +00001033 for (q=(char *) xml; *q != '\0'; )
1034 {
1035 /*
1036 Interpret XML.
1037 */
1038 GetMagickToken(q,&q,token);
1039 if (*token == '\0')
1040 break;
1041 (void) CopyMagickString(keyword,token,MaxTextExtent);
1042 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1043 {
1044 /*
1045 Doctype element.
1046 */
1047 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1048 GetMagickToken(q,&q,token);
1049 continue;
1050 }
1051 if (LocaleNCompare(keyword,"<!--",4) == 0)
1052 {
1053 /*
1054 Comment element.
1055 */
1056 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1057 GetMagickToken(q,&q,token);
1058 continue;
1059 }
1060 if (LocaleCompare(keyword,"<include") == 0)
1061 {
1062 /*
1063 Include element.
1064 */
1065 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1066 {
1067 (void) CopyMagickString(keyword,token,MaxTextExtent);
1068 GetMagickToken(q,&q,token);
1069 if (*token != '=')
1070 continue;
1071 GetMagickToken(q,&q,token);
1072 if (LocaleCompare(keyword,"file") == 0)
1073 {
1074 if (depth > 200)
1075 (void) ThrowMagickException(exception,GetMagickModule(),
1076 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1077 else
1078 {
1079 char
1080 path[MaxTextExtent],
1081 *xml;
1082
1083 GetPathComponent(filename,HeadPath,path);
1084 if (*path != '\0')
1085 (void) ConcatenateMagickString(path,DirectorySeparator,
1086 MaxTextExtent);
1087 if (*token == *DirectorySeparator)
1088 (void) CopyMagickString(path,token,MaxTextExtent);
1089 else
1090 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1091 xml=FileToString(path,~0,exception);
1092 if (xml != (char *) NULL)
1093 {
1094 status=LoadConfigureList(xml,path,depth+1,exception);
1095 xml=(char *) RelinquishMagickMemory(xml);
1096 }
1097 }
1098 }
1099 }
1100 continue;
1101 }
1102 if (LocaleCompare(keyword,"<configure") == 0)
1103 {
1104 /*
1105 Configure element.
1106 */
1107 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1108 sizeof(*configure_info));
1109 if (configure_info == (ConfigureInfo *) NULL)
1110 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1111 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1112 configure_info->path=ConstantString(filename);
cristy54a531d2009-10-21 17:58:01 +00001113 configure_info->exempt=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +00001114 configure_info->signature=MagickSignature;
1115 continue;
1116 }
1117 if (configure_info == (ConfigureInfo *) NULL)
1118 continue;
1119 if (LocaleCompare(keyword,"/>") == 0)
1120 {
1121 status=AppendValueToLinkedList(configure_list,configure_info);
1122 if (status == MagickFalse)
1123 (void) ThrowMagickException(exception,GetMagickModule(),
1124 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1125 configure_info->name);
1126 configure_info=(ConfigureInfo *) NULL;
1127 }
1128 /*
1129 Parse configure element.
1130 */
1131 GetMagickToken(q,(const char **) NULL,token);
1132 if (*token != '=')
1133 continue;
1134 GetMagickToken(q,&q,token);
1135 GetMagickToken(q,&q,token);
1136 switch (*keyword)
1137 {
1138 case 'N':
1139 case 'n':
1140 {
1141 if (LocaleCompare((char *) keyword,"name") == 0)
1142 {
1143 configure_info->name=ConstantString(token);
1144 break;
1145 }
1146 break;
1147 }
1148 case 'S':
1149 case 's':
1150 {
1151 if (LocaleCompare((char *) keyword,"stealth") == 0)
1152 {
1153 configure_info->stealth=IsMagickTrue(token);
1154 break;
1155 }
1156 break;
1157 }
1158 case 'V':
1159 case 'v':
1160 {
1161 if (LocaleCompare((char *) keyword,"value") == 0)
1162 {
1163 configure_info->value=ConstantString(token);
1164 break;
1165 }
1166 break;
1167 }
1168 default:
1169 break;
1170 }
1171 }
1172 token=(char *) RelinquishMagickMemory(token);
1173 return(status);
1174}
1175
1176/*
1177%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1178% %
1179% %
1180% %
1181% L o a d C o n f i g u r e L i s t s %
1182% %
1183% %
1184% %
1185%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1186%
1187% LoadConfigureList() loads one or more configure configuration files which
1188% provides a mapping between configure attributes and a configure name.
1189%
1190% The format of the LoadConfigureLists method is:
1191%
1192% MagickBooleanType LoadConfigureLists(const char *filename,
1193% ExceptionInfo *exception)
1194%
1195% A description of each parameter follows:
1196%
1197% o filename: the font file name.
1198%
1199% o exception: return any errors or warnings in this structure.
1200%
1201*/
1202static MagickBooleanType LoadConfigureLists(const char *filename,
1203 ExceptionInfo *exception)
1204{
cristy3ed852e2009-09-05 21:47:34 +00001205 const StringInfo
1206 *option;
1207
1208 LinkedListInfo
1209 *options;
1210
1211 MagickStatusType
1212 status;
1213
cristybb503372010-05-27 20:51:26 +00001214 register ssize_t
cristy54a531d2009-10-21 17:58:01 +00001215 i;
1216
1217 /*
1218 Load built-in configure map.
1219 */
cristy3ed852e2009-09-05 21:47:34 +00001220 status=MagickFalse;
cristy54a531d2009-10-21 17:58:01 +00001221 if (configure_list == (LinkedListInfo *) NULL)
1222 {
1223 configure_list=NewLinkedList(0);
1224 if (configure_list == (LinkedListInfo *) NULL)
1225 {
1226 ThrowFileException(exception,ResourceLimitError,
1227 "MemoryAllocationFailed",filename);
1228 return(MagickFalse);
1229 }
1230 }
cristybb503372010-05-27 20:51:26 +00001231 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
cristy54a531d2009-10-21 17:58:01 +00001232 {
1233 ConfigureInfo
1234 *configure_info;
1235
1236 register const ConfigureMapInfo
1237 *p;
1238
1239 p=ConfigureMap+i;
1240 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1241 sizeof(*configure_info));
1242 if (configure_info == (ConfigureInfo *) NULL)
1243 {
1244 (void) ThrowMagickException(exception,GetMagickModule(),
1245 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1246 configure_info->name);
1247 continue;
1248 }
1249 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1250 configure_info->path=(char *) "[built-in]";
1251 configure_info->name=(char *) p->name;
1252 configure_info->value=(char *) p->value;
1253 configure_info->exempt=MagickTrue;
1254 configure_info->signature=MagickSignature;
1255 status=AppendValueToLinkedList(configure_list,configure_info);
1256 if (status == MagickFalse)
1257 (void) ThrowMagickException(exception,GetMagickModule(),
1258 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1259 configure_info->name);
1260 }
1261 /*
1262 Load external configure map.
1263 */
cristy3ed852e2009-09-05 21:47:34 +00001264 options=GetConfigureOptions(filename,exception);
1265 option=(const StringInfo *) GetNextValueInLinkedList(options);
1266 while (option != (const StringInfo *) NULL)
1267 {
1268 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1269 GetStringInfoPath(option),0,exception);
1270 option=(const StringInfo *) GetNextValueInLinkedList(options);
1271 }
1272 options=DestroyConfigureOptions(options);
cristy3ed852e2009-09-05 21:47:34 +00001273 return(status != 0 ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +00001274}