blob: 75ca67acd691354eaaf642dfd9ec6d6ce775c66c [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% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 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)
cristy7e247522011-11-29 14:59:23 +0000577 if (GetNumberOfElementsInLinkedList(options) == 0)
578 {
579 char
580 *blob;
cristy3ed852e2009-09-05 21:47:34 +0000581
cristy7e247522011-11-29 14:59:23 +0000582 blob=(char *) NTResourceToBlob(filename);
583 if (blob != (char *) NULL)
584 {
585 xml=AcquireStringInfo(0);
586 SetStringInfoLength(xml,strlen(blob)+1);
cristy52070b42012-02-19 22:03:21 +0000587 SetStringInfoDatum(xml,(unsigned char *) blob);
cristy7e247522011-11-29 14:59:23 +0000588 SetStringInfoPath(xml,filename);
589 (void) AppendValueToLinkedList(options,xml);
590 }
591 }
cristy3ed852e2009-09-05 21:47:34 +0000592#endif
593 if (GetNumberOfElementsInLinkedList(options) == 0)
594 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
anthonye5b39652012-04-21 05:37:29 +0000595 "UnableToOpenConfigureFile","'%s'",filename);
cristy3ed852e2009-09-05 21:47:34 +0000596 ResetLinkedListIterator(options);
597 return(options);
598}
599
600/*
601%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602% %
603% %
604% %
605% G e t C o n f i g u r e P a t h s %
606% %
607% %
608% %
609%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610%
611% GetConfigurePaths() returns any Magick configuration paths associated
612% with the specified filename.
613%
614% The format of the GetConfigurePaths method is:
615%
616% LinkedListInfo *GetConfigurePaths(const char *filename,
617% ExceptionInfo *exception)
618%
619% A description of each parameter follows:
620%
621% o filename: the configure file name.
622%
623% o exception: return any errors or warnings in this structure.
624%
625*/
626MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
627 ExceptionInfo *exception)
628{
cristy7e247522011-11-29 14:59:23 +0000629#define RegistryKey "ConfigurePath"
cristy6c28ec02011-10-28 11:37:57 +0000630#define MagickCoreDLL "CORE_RL_MagickCore_.dll"
631#define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll"
632
cristy3ed852e2009-09-05 21:47:34 +0000633 char
634 path[MaxTextExtent];
635
636 LinkedListInfo
637 *paths;
638
639 assert(filename != (const char *) NULL);
640 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
641 assert(exception != (ExceptionInfo *) NULL);
642 (void) CopyMagickString(path,filename,MaxTextExtent);
643 paths=NewLinkedList(0);
644 {
645 char
646 *configure_path;
647
648 /*
649 Search $MAGICK_CONFIGURE_PATH.
650 */
651 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
652 if (configure_path != (char *) NULL)
653 {
654 register char
655 *p,
656 *q;
657
658 for (p=configure_path-1; p != (char *) NULL; )
659 {
660 (void) CopyMagickString(path,p+1,MaxTextExtent);
661 q=strchr(path,DirectoryListSeparator);
662 if (q != (char *) NULL)
663 *q='\0';
664 q=path+strlen(path)-1;
665 if ((q >= path) && (*q != *DirectorySeparator))
666 (void) ConcatenateMagickString(path,DirectorySeparator,
667 MaxTextExtent);
668 (void) AppendValueToLinkedList(paths,ConstantString(path));
669 p=strchr(p+1,DirectoryListSeparator);
670 }
671 configure_path=DestroyString(configure_path);
672 }
673 }
674#if defined(MAGICKCORE_INSTALLED_SUPPORT)
cristy4f820712011-04-01 12:35:43 +0000675#if defined(MAGICKCORE_SHARE_PATH)
cristy6c28ec02011-10-28 11:37:57 +0000676 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
cristy3ed852e2009-09-05 21:47:34 +0000677#endif
cristy670aa3c2011-11-03 00:54:00 +0000678#if defined(MAGICKCORE_SHAREARCH_PATH)
679 (void) AppendValueToLinkedList(paths,ConstantString(
680 MAGICKCORE_SHAREARCH_PATH));
681#endif
cristy3ed852e2009-09-05 21:47:34 +0000682#if defined(MAGICKCORE_CONFIGURE_PATH)
683 (void) AppendValueToLinkedList(paths,ConstantString(
684 MAGICKCORE_CONFIGURE_PATH));
685#endif
686#if defined(MAGICKCORE_DOCUMENTATION_PATH)
687 (void) AppendValueToLinkedList(paths,ConstantString(
688 MAGICKCORE_DOCUMENTATION_PATH));
689#endif
cristy4f820712011-04-01 12:35:43 +0000690#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
cristy3ed852e2009-09-05 21:47:34 +0000691 {
cristy3ed852e2009-09-05 21:47:34 +0000692 unsigned char
693 *key_value;
694
695 /*
696 Locate file via registry key.
697 */
cristy7e247522011-11-29 14:59:23 +0000698 key_value=NTRegistryKeyLookup(RegistryKey);
cristy3ed852e2009-09-05 21:47:34 +0000699 if (key_value != (unsigned char *) NULL)
700 {
cristyb51dff52011-05-19 16:55:47 +0000701 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
cristy3ed852e2009-09-05 21:47:34 +0000702 DirectorySeparator);
703 (void) AppendValueToLinkedList(paths,ConstantString(path));
704 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
705 }
706 }
707#endif
708#else
709 {
710 char
711 *home;
712
713 /*
714 Search under MAGICK_HOME.
715 */
716 home=GetEnvironmentValue("MAGICK_HOME");
717 if (home != (char *) NULL)
718 {
719#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000720 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000721 DirectorySeparator);
722 (void) AppendValueToLinkedList(paths,ConstantString(path));
723#else
cristyb51dff52011-05-19 16:55:47 +0000724 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
cristy3ed852e2009-09-05 21:47:34 +0000725 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
726 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000727 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
cristy4f820712011-04-01 12:35:43 +0000728 MAGICKCORE_SHARE_RELATIVE_PATH);
cristy3ed852e2009-09-05 21:47:34 +0000729 (void) AppendValueToLinkedList(paths,ConstantString(path));
730#endif
731 home=DestroyString(home);
732 }
733 }
734 if (*GetClientPath() != '\0')
735 {
736#if !defined(MAGICKCORE_POSIX_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000737 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +0000738 DirectorySeparator);
739 (void) AppendValueToLinkedList(paths,ConstantString(path));
740#else
741 char
742 prefix[MaxTextExtent];
743
744 /*
745 Search based on executable directory if directory is known.
746 */
747 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
748 ChopPathComponents(prefix,1);
cristyb51dff52011-05-19 16:55:47 +0000749 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
cristy3ed852e2009-09-05 21:47:34 +0000750 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
751 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000752 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
cristy4f820712011-04-01 12:35:43 +0000753 MAGICKCORE_SHARE_RELATIVE_PATH);
754 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristy3ed852e2009-09-05 21:47:34 +0000755#endif
756 }
cristy51b1ac52010-10-30 02:27:14 +0000757 /*
758 Search current directory.
759 */
760 (void) AppendValueToLinkedList(paths,ConstantString(""));
cristy3ed852e2009-09-05 21:47:34 +0000761#endif
762 {
763 char
764 *home;
765
766 home=GetEnvironmentValue("HOME");
767 if (home == (char *) NULL)
768 home=GetEnvironmentValue("USERPROFILE");
769 if (home != (char *) NULL)
770 {
771 /*
772 Search $HOME/.magick.
773 */
cristyb51dff52011-05-19 16:55:47 +0000774 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
cristy3ed852e2009-09-05 21:47:34 +0000775 DirectorySeparator,DirectorySeparator);
776 (void) AppendValueToLinkedList(paths,ConstantString(path));
777 home=DestroyString(home);
778 }
779 }
cristy0157aea2010-04-24 21:12:18 +0000780#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000781 {
782 char
783 module_path[MaxTextExtent];
784
cristy6c28ec02011-10-28 11:37:57 +0000785 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
786 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +0000787 {
cristy7e247522011-11-29 14:59:23 +0000788 unsigned char
789 *key_value;
cristy3ed852e2009-09-05 21:47:34 +0000790
791 /*
792 Search module path.
793 */
cristyb51dff52011-05-19 16:55:47 +0000794 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000795 DirectorySeparator);
cristy7e247522011-11-29 14:59:23 +0000796 key_value=NTRegistryKeyLookup(RegistryKey);
797 if (key_value == (unsigned char *) NULL)
798 (void) AppendValueToLinkedList(paths,ConstantString(path));
799 else
800 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
cristy3ed852e2009-09-05 21:47:34 +0000801 }
802 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
803 {
804 /*
805 Search PerlMagick module path.
806 */
cristyb51dff52011-05-19 16:55:47 +0000807 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000808 DirectorySeparator);
809 (void) AppendValueToLinkedList(paths,ConstantString(path));
cristyb51dff52011-05-19 16:55:47 +0000810 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
cristy3ed852e2009-09-05 21:47:34 +0000811 "\\inc\\lib\\auto\\Image\\Magick\\");
812 (void) AppendValueToLinkedList(paths,ConstantString(path));
813 }
814 }
815#endif
cristy3ed852e2009-09-05 21:47:34 +0000816 return(paths);
817}
818
819/*
820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821% %
822% %
823% %
824% G e t C o n f i g u r e V a l u e %
825% %
826% %
827% %
828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829%
830% GetConfigureValue() returns the value associated with the configure info.
831%
832% The format of the GetConfigureValue method is:
833%
834% const char *GetConfigureValue(const ConfigureInfo *configure_info)
835%
836% A description of each parameter follows:
837%
838% o configure_info: The configure info.
839%
840*/
841MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
842{
843 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
844 assert(configure_info != (ConfigureInfo *) NULL);
845 assert(configure_info->signature == MagickSignature);
846 return(configure_info->value);
847}
848
849/*
850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851% %
852% %
853% %
854+ I n i t i a l i z e C o n f i g u r e L i s t %
855% %
856% %
857% %
858%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
859%
860% InitializeConfigureList() initializes the configure list.
861%
862% The format of the InitializeConfigureList method is:
863%
864% MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
865%
866% A description of each parameter follows.
867%
868% o exception: return any errors or warnings in this structure.
869%
870*/
871static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
872{
873 if ((configure_list == (LinkedListInfo *) NULL) &&
874 (instantiate_configure == MagickFalse))
875 {
cristy4e1dff62009-10-25 20:36:03 +0000876 if (configure_semaphore == (SemaphoreInfo *) NULL)
877 AcquireSemaphoreInfo(&configure_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000878 LockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000879 if ((configure_list == (LinkedListInfo *) NULL) &&
880 (instantiate_configure == MagickFalse))
881 {
882 (void) LoadConfigureLists(ConfigureFilename,exception);
883 instantiate_configure=MagickTrue;
884 }
cristyf84a1932010-01-03 18:00:18 +0000885 UnlockSemaphoreInfo(configure_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000886 }
887 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
888}
889
890/*
891%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892% %
893% %
894% %
cristy3ed852e2009-09-05 21:47:34 +0000895% L i s t C o n f i g u r e I n f o %
896% %
897% %
898% %
899%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
900%
901% ListConfigureInfo() lists the configure info to a file.
902%
903% The format of the ListConfigureInfo method is:
904%
905% MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
906%
907% A description of each parameter follows.
908%
909% o file: An pointer to a FILE.
910%
911% o exception: return any errors or warnings in this structure.
912%
913*/
914MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
915 ExceptionInfo *exception)
916{
917 const char
918 *name,
919 *path,
920 *value;
921
922 const ConfigureInfo
923 **configure_info;
924
cristybb503372010-05-27 20:51:26 +0000925 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000926 i;
927
cristybb503372010-05-27 20:51:26 +0000928 size_t
cristy3ed852e2009-09-05 21:47:34 +0000929 number_options;
930
cristy9d314ff2011-03-09 01:30:28 +0000931 ssize_t
932 j;
933
cristy3ed852e2009-09-05 21:47:34 +0000934 if (file == (const FILE *) NULL)
935 file=stdout;
936 configure_info=GetConfigureInfoList("*",&number_options,exception);
937 if (configure_info == (const ConfigureInfo **) NULL)
938 return(MagickFalse);
939 path=(const char *) NULL;
cristybb503372010-05-27 20:51:26 +0000940 for (i=0; i < (ssize_t) number_options; i++)
cristy3ed852e2009-09-05 21:47:34 +0000941 {
942 if (configure_info[i]->stealth != MagickFalse)
943 continue;
944 if ((path == (const char *) NULL) ||
945 (LocaleCompare(path,configure_info[i]->path) != 0))
946 {
947 if (configure_info[i]->path != (char *) NULL)
cristy1e604812011-05-19 18:07:50 +0000948 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
949 configure_info[i]->path);
cristyb51dff52011-05-19 16:55:47 +0000950 (void) FormatLocaleFile(file,"Name Value\n");
cristy1e604812011-05-19 18:07:50 +0000951 (void) FormatLocaleFile(file,
952 "-------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000953 "------------------------------\n");
954 }
955 path=configure_info[i]->path;
956 name="unknown";
957 if (configure_info[i]->name != (char *) NULL)
958 name=configure_info[i]->name;
cristyb51dff52011-05-19 16:55:47 +0000959 (void) FormatLocaleFile(file,"%s",name);
cristybb503372010-05-27 20:51:26 +0000960 for (j=(ssize_t) strlen(name); j <= 12; j++)
cristyb51dff52011-05-19 16:55:47 +0000961 (void) FormatLocaleFile(file," ");
962 (void) FormatLocaleFile(file," ");
cristy3ed852e2009-09-05 21:47:34 +0000963 value="unknown";
964 if (configure_info[i]->value != (char *) NULL)
965 value=configure_info[i]->value;
cristyb51dff52011-05-19 16:55:47 +0000966 (void) FormatLocaleFile(file,"%s",value);
967 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +0000968 }
969 (void) fflush(file);
970 configure_info=(const ConfigureInfo **)
971 RelinquishMagickMemory((void *) configure_info);
972 return(MagickTrue);
973}
974
975/*
976%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977% %
978% %
979% %
980+ L o a d C o n f i g u r e L i s t %
981% %
982% %
983% %
984%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
985%
986% LoadConfigureList() loads the configure configuration file which provides a
987% mapping between configure attributes and a configure name.
988%
989% The format of the LoadConfigureList method is:
990%
991% MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +0000992% const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000993%
994% A description of each parameter follows:
995%
996% o xml: The configure list in XML format.
997%
998% o filename: The configure list filename.
999%
1000% o depth: depth of <include /> statements.
1001%
1002% o exception: return any errors or warnings in this structure.
1003%
1004*/
1005static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
cristybb503372010-05-27 20:51:26 +00001006 const size_t depth,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001007{
1008 char
1009 keyword[MaxTextExtent],
1010 *token;
1011
1012 ConfigureInfo
1013 *configure_info;
1014
1015 const char
1016 *q;
1017
1018 MagickBooleanType
1019 status;
1020
1021 /*
1022 Load the configure map file.
1023 */
1024 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1025 "Loading configure file \"%s\" ...",filename);
1026 if (configure_list == (LinkedListInfo *) NULL)
1027 {
1028 configure_list=NewLinkedList(0);
1029 if (configure_list == (LinkedListInfo *) NULL)
1030 {
1031 ThrowFileException(exception,ResourceLimitError,
1032 "MemoryAllocationFailed",filename);
1033 return(MagickFalse);
1034 }
1035 }
1036 status=MagickTrue;
1037 configure_info=(ConfigureInfo *) NULL;
cristy54a531d2009-10-21 17:58:01 +00001038 token=AcquireString((char *) xml);
cristy3ed852e2009-09-05 21:47:34 +00001039 for (q=(char *) xml; *q != '\0'; )
1040 {
1041 /*
1042 Interpret XML.
1043 */
1044 GetMagickToken(q,&q,token);
1045 if (*token == '\0')
1046 break;
1047 (void) CopyMagickString(keyword,token,MaxTextExtent);
1048 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1049 {
1050 /*
1051 Doctype element.
1052 */
1053 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1054 GetMagickToken(q,&q,token);
1055 continue;
1056 }
1057 if (LocaleNCompare(keyword,"<!--",4) == 0)
1058 {
1059 /*
1060 Comment element.
1061 */
1062 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1063 GetMagickToken(q,&q,token);
1064 continue;
1065 }
1066 if (LocaleCompare(keyword,"<include") == 0)
1067 {
1068 /*
1069 Include element.
1070 */
1071 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1072 {
1073 (void) CopyMagickString(keyword,token,MaxTextExtent);
1074 GetMagickToken(q,&q,token);
1075 if (*token != '=')
1076 continue;
1077 GetMagickToken(q,&q,token);
1078 if (LocaleCompare(keyword,"file") == 0)
1079 {
1080 if (depth > 200)
1081 (void) ThrowMagickException(exception,GetMagickModule(),
anthonye5b39652012-04-21 05:37:29 +00001082 ConfigureError,"IncludeElementNestedTooDeeply","'%s'",token);
cristy3ed852e2009-09-05 21:47:34 +00001083 else
1084 {
1085 char
1086 path[MaxTextExtent],
1087 *xml;
1088
1089 GetPathComponent(filename,HeadPath,path);
1090 if (*path != '\0')
1091 (void) ConcatenateMagickString(path,DirectorySeparator,
1092 MaxTextExtent);
1093 if (*token == *DirectorySeparator)
1094 (void) CopyMagickString(path,token,MaxTextExtent);
1095 else
1096 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1097 xml=FileToString(path,~0,exception);
1098 if (xml != (char *) NULL)
1099 {
1100 status=LoadConfigureList(xml,path,depth+1,exception);
1101 xml=(char *) RelinquishMagickMemory(xml);
1102 }
1103 }
1104 }
1105 }
1106 continue;
1107 }
1108 if (LocaleCompare(keyword,"<configure") == 0)
1109 {
1110 /*
1111 Configure element.
1112 */
1113 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1114 sizeof(*configure_info));
1115 if (configure_info == (ConfigureInfo *) NULL)
1116 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1117 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1118 configure_info->path=ConstantString(filename);
cristy54a531d2009-10-21 17:58:01 +00001119 configure_info->exempt=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +00001120 configure_info->signature=MagickSignature;
1121 continue;
1122 }
1123 if (configure_info == (ConfigureInfo *) NULL)
1124 continue;
1125 if (LocaleCompare(keyword,"/>") == 0)
1126 {
1127 status=AppendValueToLinkedList(configure_list,configure_info);
1128 if (status == MagickFalse)
1129 (void) ThrowMagickException(exception,GetMagickModule(),
anthonye5b39652012-04-21 05:37:29 +00001130 ResourceLimitError,"MemoryAllocationFailed","'%s'",
cristy3ed852e2009-09-05 21:47:34 +00001131 configure_info->name);
1132 configure_info=(ConfigureInfo *) NULL;
1133 }
1134 /*
1135 Parse configure element.
1136 */
1137 GetMagickToken(q,(const char **) NULL,token);
1138 if (*token != '=')
1139 continue;
1140 GetMagickToken(q,&q,token);
1141 GetMagickToken(q,&q,token);
1142 switch (*keyword)
1143 {
1144 case 'N':
1145 case 'n':
1146 {
1147 if (LocaleCompare((char *) keyword,"name") == 0)
1148 {
1149 configure_info->name=ConstantString(token);
1150 break;
1151 }
1152 break;
1153 }
1154 case 'S':
1155 case 's':
1156 {
1157 if (LocaleCompare((char *) keyword,"stealth") == 0)
1158 {
anthony6f201312012-03-30 04:08:15 +00001159 configure_info->stealth=IsStringTrue(token);
cristy3ed852e2009-09-05 21:47:34 +00001160 break;
1161 }
1162 break;
1163 }
1164 case 'V':
1165 case 'v':
1166 {
1167 if (LocaleCompare((char *) keyword,"value") == 0)
1168 {
1169 configure_info->value=ConstantString(token);
1170 break;
1171 }
1172 break;
1173 }
1174 default:
1175 break;
1176 }
1177 }
1178 token=(char *) RelinquishMagickMemory(token);
1179 return(status);
1180}
1181
1182/*
1183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1184% %
1185% %
1186% %
1187% L o a d C o n f i g u r e L i s t s %
1188% %
1189% %
1190% %
1191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1192%
1193% LoadConfigureList() loads one or more configure configuration files which
1194% provides a mapping between configure attributes and a configure name.
1195%
1196% The format of the LoadConfigureLists method is:
1197%
1198% MagickBooleanType LoadConfigureLists(const char *filename,
1199% ExceptionInfo *exception)
1200%
1201% A description of each parameter follows:
1202%
1203% o filename: the font file name.
1204%
1205% o exception: return any errors or warnings in this structure.
1206%
1207*/
1208static MagickBooleanType LoadConfigureLists(const char *filename,
1209 ExceptionInfo *exception)
1210{
cristy3ed852e2009-09-05 21:47:34 +00001211 const StringInfo
1212 *option;
1213
1214 LinkedListInfo
1215 *options;
1216
1217 MagickStatusType
1218 status;
1219
cristybb503372010-05-27 20:51:26 +00001220 register ssize_t
cristy54a531d2009-10-21 17:58:01 +00001221 i;
1222
1223 /*
1224 Load built-in configure map.
1225 */
cristy3ed852e2009-09-05 21:47:34 +00001226 status=MagickFalse;
cristy54a531d2009-10-21 17:58:01 +00001227 if (configure_list == (LinkedListInfo *) NULL)
1228 {
1229 configure_list=NewLinkedList(0);
1230 if (configure_list == (LinkedListInfo *) NULL)
1231 {
1232 ThrowFileException(exception,ResourceLimitError,
1233 "MemoryAllocationFailed",filename);
1234 return(MagickFalse);
1235 }
1236 }
cristybb503372010-05-27 20:51:26 +00001237 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
cristy54a531d2009-10-21 17:58:01 +00001238 {
1239 ConfigureInfo
1240 *configure_info;
1241
1242 register const ConfigureMapInfo
1243 *p;
1244
1245 p=ConfigureMap+i;
1246 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1247 sizeof(*configure_info));
1248 if (configure_info == (ConfigureInfo *) NULL)
1249 {
1250 (void) ThrowMagickException(exception,GetMagickModule(),
anthonye5b39652012-04-21 05:37:29 +00001251 ResourceLimitError,"MemoryAllocationFailed","'%s'",
cristy54a531d2009-10-21 17:58:01 +00001252 configure_info->name);
1253 continue;
1254 }
1255 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1256 configure_info->path=(char *) "[built-in]";
1257 configure_info->name=(char *) p->name;
1258 configure_info->value=(char *) p->value;
1259 configure_info->exempt=MagickTrue;
1260 configure_info->signature=MagickSignature;
1261 status=AppendValueToLinkedList(configure_list,configure_info);
1262 if (status == MagickFalse)
1263 (void) ThrowMagickException(exception,GetMagickModule(),
anthonye5b39652012-04-21 05:37:29 +00001264 ResourceLimitError,"MemoryAllocationFailed","'%s'",
cristy54a531d2009-10-21 17:58:01 +00001265 configure_info->name);
1266 }
1267 /*
1268 Load external configure map.
1269 */
cristy3ed852e2009-09-05 21:47:34 +00001270 options=GetConfigureOptions(filename,exception);
1271 option=(const StringInfo *) GetNextValueInLinkedList(options);
1272 while (option != (const StringInfo *) NULL)
1273 {
1274 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1275 GetStringInfoPath(option),0,exception);
1276 option=(const StringInfo *) GetNextValueInLinkedList(options);
1277 }
1278 options=DestroyConfigureOptions(options);
cristy3ed852e2009-09-05 21:47:34 +00001279 return(status != 0 ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +00001280}