]> granicus.if.org Git - imagemagick/blob - magick/configure.c
(no commit message)
[imagemagick] / magick / configure.c
1 /*
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 %                                                                             %
20 %  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
21 %  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 \f
39 /*
40   Include declarations.
41 */
42 #include "magick/studio.h"
43 #include "magick/blob.h"
44 #include "magick/client.h"
45 #include "magick/configure.h"
46 #include "magick/exception.h"
47 #include "magick/exception-private.h"
48 #include "magick/hashmap.h"
49 #include "magick/log.h"
50 #include "magick/memory_.h"
51 #include "magick/semaphore.h"
52 #include "magick/string_.h"
53 #include "magick/token.h"
54 #include "magick/utility.h"
55 #include "magick/xml-tree.h"
56 \f
57 /*
58   Define declarations.
59 */
60 #define ConfigureFilename  "configure.xml"
61 \f
62 /*
63   Static declarations.
64 */
65 static const char
66   *ConfigureMap = (char *)
67     "<?xml version=\"1.0\"?>"
68     "<configuremap>"
69     "  <configure stealth=\"True\" />"
70     "</configuremap>";
71
72 static LinkedListInfo
73   *configure_list = (LinkedListInfo *) NULL;
74
75 static SemaphoreInfo
76   *configure_semaphore = (SemaphoreInfo *) NULL;
77
78 static volatile MagickBooleanType
79   instantiate_configure = MagickFalse;
80 \f
81 /*
82   Forward declarations.
83 */
84 static MagickBooleanType
85   InitializeConfigureList(ExceptionInfo *),
86   LoadConfigureLists(const char *,ExceptionInfo *);
87 \f
88 /*
89 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90 %                                                                             %
91 %                                                                             %
92 %                                                                             %
93 +   D e s t r o y C o n f i g u r e F a c i l i t y                           %
94 %                                                                             %
95 %                                                                             %
96 %                                                                             %
97 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98 %
99 %  DestroyConfigureFacility() destroys the configure facility.
100 %
101 %  The format of the DestroyConfigureFacility method is:
102 %
103 %      DestroyConfigureFacility(void)
104 %
105 */
106
107 static void *DestroyConfigureElement(void *configure_info)
108 {
109   register ConfigureInfo
110     *p;
111
112   p=(ConfigureInfo *) configure_info;
113   if (p->path != (char *) NULL)
114     p->path=DestroyString(p->path);
115   if (p->name != (char *) NULL)
116     p->name=DestroyString(p->name);
117   if (p->value != (char *) NULL)
118     p->value=DestroyString(p->value);
119   p=(ConfigureInfo *) RelinquishMagickMemory(p);
120   return((void *) NULL);
121 }
122
123 MagickExport void DestroyConfigureFacility(void)
124 {
125   AcquireSemaphoreInfo(&configure_semaphore);
126   if (configure_list != (LinkedListInfo *) NULL)
127     configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
128   configure_list=(LinkedListInfo *) NULL;
129   instantiate_configure=MagickFalse;
130   RelinquishSemaphoreInfo(configure_semaphore);
131   DestroySemaphoreInfo(&configure_semaphore);
132 }
133 \f
134 /*
135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 %                                                                             %
137 %                                                                             %
138 %                                                                             %
139 %   D e s t r o y C o n f i g u r e O p t i o n s                             %
140 %                                                                             %
141 %                                                                             %
142 %                                                                             %
143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144 %
145 %  DestroyConfigureOptions() releases memory associated with an configure
146 %  options.
147 %
148 %  The format of the DestroyProfiles method is:
149 %
150 %      LinkedListInfo *DestroyConfigureOptions(Image *image)
151 %
152 %  A description of each parameter follows:
153 %
154 %    o image: the image.
155 %
156 */
157
158 static void *DestroyOptions(void *option)
159 {
160   return(DestroyStringInfo((StringInfo *) option));
161 }
162
163 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
164 {
165   assert(options != (LinkedListInfo *) NULL);
166   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
167   return(DestroyLinkedList(options,DestroyOptions));
168 }
169 \f
170 /*
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 %                                                                             %
173 %                                                                             %
174 %                                                                             %
175 +   G e t C o n f i g u r e I n f o                                           %
176 %                                                                             %
177 %                                                                             %
178 %                                                                             %
179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 %
181 %  GetConfigureInfo() searches the configure list for the specified name and if
182 %  found returns attributes for that element.
183 %
184 %  The format of the GetConfigureInfo method is:
185 %
186 %      const ConfigureInfo *GetConfigureInfo(const char *name,
187 %        ExceptionInfo *exception)
188 %
189 %  A description of each parameter follows:
190 %
191 %    o configure_info: GetConfigureInfo() searches the configure list for the
192 %      specified name and if found returns attributes for that element.
193 %
194 %    o name: the configure name.
195 %
196 %    o exception: return any errors or warnings in this structure.
197 %
198 */
199 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
200   ExceptionInfo *exception)
201 {
202   register const ConfigureInfo
203     *p;
204
205   assert(exception != (ExceptionInfo *) NULL);
206   if ((configure_list == (LinkedListInfo *) NULL) ||
207       (instantiate_configure == MagickFalse))
208     if (InitializeConfigureList(exception) == MagickFalse)
209       return((const ConfigureInfo *) NULL);
210   if ((configure_list == (LinkedListInfo *) NULL) ||
211       (IsLinkedListEmpty(configure_list) != MagickFalse))
212     return((const ConfigureInfo *) NULL);
213   if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
214     return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
215   /*
216     Search for configure tag.
217   */
218   AcquireSemaphoreInfo(&configure_semaphore);
219   ResetLinkedListIterator(configure_list);
220   p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
221   while (p != (const ConfigureInfo *) NULL)
222   {
223     if (LocaleCompare(name,p->name) == 0)
224       break;
225     p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
226   }
227   if (p != (ConfigureInfo *) NULL)
228     (void) InsertValueInLinkedList(configure_list,0,
229       RemoveElementByValueFromLinkedList(configure_list,p));
230   RelinquishSemaphoreInfo(configure_semaphore);
231   return(p);
232 }
233 \f
234 /*
235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236 %                                                                             %
237 %                                                                             %
238 %                                                                             %
239 %   G e t C o n f i g u r e I n f o L i s t                                   %
240 %                                                                             %
241 %                                                                             %
242 %                                                                             %
243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244 %
245 %  GetConfigureInfoList() returns any configure options that match the
246 %  specified pattern.
247 %
248 %  The format of the GetConfigureInfoList function is:
249 %
250 %      const ConfigureInfo **GetConfigureInfoList(const char *pattern,
251 %        unsigned long *number_options,ExceptionInfo *exception)
252 %
253 %  A description of each parameter follows:
254 %
255 %    o pattern: Specifies a pointer to a text string containing a pattern.
256 %
257 %    o number_options:  This integer returns the number of configure options in
258 %    the list.
259 %
260 %    o exception: return any errors or warnings in this structure.
261 %
262 */
263
264 #if defined(__cplusplus) || defined(c_plusplus)
265 extern "C" {
266 #endif
267
268 static int ConfigureInfoCompare(const void *x,const void *y)
269 {
270   const ConfigureInfo
271     **p,
272     **q;
273
274   p=(const ConfigureInfo **) x,
275   q=(const ConfigureInfo **) y;
276   if (LocaleCompare((*p)->path,(*q)->path) == 0)
277     return(LocaleCompare((*p)->name,(*q)->name));
278   return(LocaleCompare((*p)->path,(*q)->path));
279 }
280
281 #if defined(__cplusplus) || defined(c_plusplus)
282 }
283 #endif
284
285 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
286   unsigned long *number_options,ExceptionInfo *exception)
287 {
288   const ConfigureInfo
289     **options;
290
291   register const ConfigureInfo
292     *p;
293
294   register long
295     i;
296
297   /*
298     Allocate configure list.
299   */
300   assert(pattern != (char *) NULL);
301   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
302   assert(number_options != (unsigned long *) NULL);
303   *number_options=0;
304   p=GetConfigureInfo("*",exception);
305   if (p == (const ConfigureInfo *) NULL)
306     return((const ConfigureInfo **) NULL);
307   options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
308     GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
309   if (options == (const ConfigureInfo **) NULL)
310     return((const ConfigureInfo **) NULL);
311   /*
312     Generate configure list.
313   */
314   AcquireSemaphoreInfo(&configure_semaphore);
315   ResetLinkedListIterator(configure_list);
316   p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
317   for (i=0; p != (const ConfigureInfo *) NULL; )
318   {
319     if ((p->stealth == MagickFalse) &&
320         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
321       options[i++]=p;
322     p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
323   }
324   RelinquishSemaphoreInfo(configure_semaphore);
325   qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
326   options[i]=(ConfigureInfo *) NULL;
327   *number_options=(unsigned long) i;
328   return(options);
329 }
330 \f
331 /*
332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
333 %                                                                             %
334 %                                                                             %
335 %                                                                             %
336 %   G e t C o n f i g u r e L i s t                                           %
337 %                                                                             %
338 %                                                                             %
339 %                                                                             %
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341 %
342 %  GetConfigureList() returns any configure options that match the specified
343 %  pattern.
344 %
345 %  The format of the GetConfigureList function is:
346 %
347 %      char **GetConfigureList(const char *pattern,
348 %        unsigned long *number_options,ExceptionInfo *exception)
349 %
350 %  A description of each parameter follows:
351 %
352 %    o pattern: Specifies a pointer to a text string containing a pattern.
353 %
354 %    o number_options:  This integer returns the number of options in the list.
355 %
356 %    o exception: return any errors or warnings in this structure.
357 %
358 */
359
360 #if defined(__cplusplus) || defined(c_plusplus)
361 extern "C" {
362 #endif
363
364 static int ConfigureCompare(const void *x,const void *y)
365 {
366   register char
367     **p,
368     **q;
369
370   p=(char **) x;
371   q=(char **) y;
372   return(LocaleCompare(*p,*q));
373 }
374
375 #if defined(__cplusplus) || defined(c_plusplus)
376 }
377 #endif
378
379 MagickExport char **GetConfigureList(const char *pattern,
380   unsigned long *number_options,ExceptionInfo *exception)
381 {
382   char
383     **options;
384
385   register const ConfigureInfo
386     *p;
387
388   register long
389     i;
390
391   /*
392     Allocate configure list.
393   */
394   assert(pattern != (char *) NULL);
395   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
396   assert(number_options != (unsigned long *) NULL);
397   *number_options=0;
398   p=GetConfigureInfo("*",exception);
399   if (p == (const ConfigureInfo *) NULL)
400     return((char **) NULL);
401   AcquireSemaphoreInfo(&configure_semaphore);
402   RelinquishSemaphoreInfo(configure_semaphore);
403   options=(char **) AcquireQuantumMemory((size_t)
404     GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
405   if (options == (char **) NULL)
406     return((char **) NULL);
407   AcquireSemaphoreInfo(&configure_semaphore);
408   ResetLinkedListIterator(configure_list);
409   p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
410   for (i=0; p != (const ConfigureInfo *) NULL; )
411   {
412     if ((p->stealth == MagickFalse) &&
413         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
414       options[i++]=ConstantString(p->name);
415     p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
416   }
417   RelinquishSemaphoreInfo(configure_semaphore);
418   qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
419   options[i]=(char *) NULL;
420   *number_options=(unsigned long) i;
421   return(options);
422 }
423 \f
424 /*
425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426 %                                                                             %
427 %                                                                             %
428 %                                                                             %
429 %   G e t C o n f i g u r e O p t i o n                                       %
430 %                                                                             %
431 %                                                                             %
432 %                                                                             %
433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434 %
435 %  GetConfigureOption() returns the value associated with the configure option.
436 %
437 %  The format of the GetConfigureOption method is:
438 %
439 %      char *GetConfigureOption(const char *option)
440 %
441 %  A description of each parameter follows:
442 %
443 %    o configure_info:  The configure info.
444 %
445 */
446 MagickExport char *GetConfigureOption(const char *option)
447 {
448   const char
449     *value;
450
451   const ConfigureInfo
452     *configure_info;
453
454   ExceptionInfo
455     *exception;
456
457   assert(option != (const char *) NULL);
458   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
459   exception=AcquireExceptionInfo();
460   configure_info=GetConfigureInfo(option,exception);
461   exception=DestroyExceptionInfo(exception);
462   if (configure_info == (ConfigureInfo *) NULL)
463     return((char *) NULL);
464   value=GetConfigureValue(configure_info);
465   if ((value == (const char *) NULL) || (*value == '\0'))
466     return((char *) NULL);
467   return(ConstantString(value));
468 }
469 \f
470 /*
471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
472 %                                                                             %
473 %                                                                             %
474 %                                                                             %
475 %  G e t C o n f i g u r e O p t i o n s                                      %
476 %                                                                             %
477 %                                                                             %
478 %                                                                             %
479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480 %
481 %  GetConfigureOptions() returns any Magick configuration options associated
482 %  with the specified filename.
483 %
484 %  The format of the GetConfigureOptions method is:
485 %
486 %      LinkedListInfo *GetConfigureOptions(const char *filename,
487 %        ExceptionInfo *exception)
488 %
489 %  A description of each parameter follows:
490 %
491 %    o filename: the configure file name.
492 %
493 %    o exception: return any errors or warnings in this structure.
494 %
495 */
496 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
497   ExceptionInfo *exception)
498 {
499   char
500     path[MaxTextExtent];
501
502   const char
503     *element;
504
505   LinkedListInfo
506     *options,
507     *paths;
508
509   StringInfo
510     *xml;
511
512   assert(filename != (const char *) NULL);
513   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
514   assert(exception != (ExceptionInfo *) NULL);
515   (void) CopyMagickString(path,filename,MaxTextExtent);
516   /*
517     Load XML from configuration files to linked-list.
518   */
519   options=NewLinkedList(0);
520   paths=GetConfigurePaths(filename,exception);
521   if (paths != (LinkedListInfo *) NULL)
522     {
523       ResetLinkedListIterator(paths);
524       element=(const char *) GetNextValueInLinkedList(paths);
525       while (element != (const char *) NULL)
526       {
527         (void) FormatMagickString(path,MaxTextExtent,"%s%s",element,filename);
528         (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
529           "Searching for configure file: \"%s\"",path);
530         xml=ConfigureFileToStringInfo(path);
531         if (xml != (StringInfo *) NULL)
532           (void) AppendValueToLinkedList(options,xml);
533         element=(const char *) GetNextValueInLinkedList(paths);
534       }
535       paths=DestroyLinkedList(paths,RelinquishMagickMemory);
536     }
537 #if defined(__WINDOWS__)
538   {
539     char
540       *blob;
541
542     blob=(char *) NTResourceToBlob(filename);
543     if (blob != (char *) NULL)
544       {
545         xml=StringToStringInfo(blob);
546         SetStringInfoPath(xml,filename);
547         (void) AppendValueToLinkedList(options,xml);
548         blob=DestroyString(blob);
549       }
550   }
551 #endif
552   if (GetNumberOfElementsInLinkedList(options) == 0)
553     (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
554       "UnableToOpenConfigureFile","`%s'",filename);
555   ResetLinkedListIterator(options);
556   return(options);
557 }
558 \f
559 /*
560 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561 %                                                                             %
562 %                                                                             %
563 %                                                                             %
564 %  G e t C o n f i g u r e P a t h s                                          %
565 %                                                                             %
566 %                                                                             %
567 %                                                                             %
568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
569 %
570 %  GetConfigurePaths() returns any Magick configuration paths associated
571 %  with the specified filename.
572 %
573 %  The format of the GetConfigurePaths method is:
574 %
575 %      LinkedListInfo *GetConfigurePaths(const char *filename,
576 %        ExceptionInfo *exception)
577 %
578 %  A description of each parameter follows:
579 %
580 %    o filename: the configure file name.
581 %
582 %    o exception: return any errors or warnings in this structure.
583 %
584 */
585 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
586   ExceptionInfo *exception)
587 {
588   char
589     path[MaxTextExtent];
590
591   LinkedListInfo
592     *paths;
593
594   assert(filename != (const char *) NULL);
595   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
596   assert(exception != (ExceptionInfo *) NULL);
597   (void) CopyMagickString(path,filename,MaxTextExtent);
598   paths=NewLinkedList(0);
599   {
600     char
601       *configure_path;
602
603     /*
604       Search $MAGICK_CONFIGURE_PATH.
605     */
606     configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
607     if (configure_path != (char *) NULL)
608       {
609         register char
610           *p,
611           *q;
612
613         for (p=configure_path-1; p != (char *) NULL; )
614         {
615           (void) CopyMagickString(path,p+1,MaxTextExtent);
616           q=strchr(path,DirectoryListSeparator);
617           if (q != (char *) NULL)
618             *q='\0';
619           q=path+strlen(path)-1;
620           if ((q >= path) && (*q != *DirectorySeparator))
621             (void) ConcatenateMagickString(path,DirectorySeparator,
622               MaxTextExtent);
623           (void) AppendValueToLinkedList(paths,ConstantString(path));
624           p=strchr(p+1,DirectoryListSeparator);
625         }
626         configure_path=DestroyString(configure_path);
627       }
628   }
629 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
630 #if defined(MAGICKCORE_SHARE_CONFIGURE_PATH)
631   (void) AppendValueToLinkedList(paths,ConstantString(
632     MAGICKCORE_SHARE_CONFIGURE_PATH));
633 #endif
634 #if defined(MAGICKCORE_CONFIGURE_PATH)
635   (void) AppendValueToLinkedList(paths,ConstantString(
636     MAGICKCORE_CONFIGURE_PATH));
637 #endif
638 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
639   (void) AppendValueToLinkedList(paths,ConstantString(
640     MAGICKCORE_DOCUMENTATION_PATH));
641 #endif
642 #if defined(MAGICKCORE_SHARE_PATH)
643   (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
644 #endif
645 #if defined(__WINDOWS__) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_CONFIGURE_PATH))
646   {
647     char
648       *registry_key;
649
650     unsigned char
651       *key_value;
652
653     /*
654       Locate file via registry key.
655     */
656     registry_key="ConfigurePath";
657     key_value=NTRegistryKeyLookup(registry_key);
658     if (key_value != (unsigned char *) NULL)
659       {
660         (void) FormatMagickString(path,MaxTextExtent,"%s%s",(char *) key_value,
661           DirectorySeparator);
662         (void) AppendValueToLinkedList(paths,ConstantString(path));
663         key_value=(unsigned char *) RelinquishMagickMemory(key_value);
664       }
665   }
666 #endif
667 #else
668   {
669     char
670       *home;
671
672     /*
673       Search under MAGICK_HOME.
674     */
675     home=GetEnvironmentValue("MAGICK_HOME");
676     if (home != (char *) NULL)
677       {
678 #if !defined(MAGICKCORE_POSIX_SUPPORT)
679         (void) FormatMagickString(path,MaxTextExtent,"%s%s",home,
680           DirectorySeparator);
681         (void) AppendValueToLinkedList(paths,ConstantString(path));
682 #else
683         (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/",home,
684           MAGICKCORE_CONFIGURE_RELATIVE_PATH);
685         (void) AppendValueToLinkedList(paths,ConstantString(path));
686         (void) FormatMagickString(path,MaxTextExtent,"%s/share/%s/",home,
687           MAGICKCORE_SHARE_CONFIGURE_RELATIVE_PATH);
688         (void) AppendValueToLinkedList(paths,ConstantString(path));
689 #endif
690         home=DestroyString(home);
691       }
692     }
693   if (*GetClientPath() != '\0')
694     {
695 #if !defined(MAGICKCORE_POSIX_SUPPORT)
696       (void) FormatMagickString(path,MaxTextExtent,"%s%s",GetClientPath(),
697         DirectorySeparator);
698       (void) AppendValueToLinkedList(paths,ConstantString(path));
699 #else
700       char
701         prefix[MaxTextExtent];
702
703       /*
704         Search based on executable directory if directory is known.
705       */
706       (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
707       ChopPathComponents(prefix,1);
708       (void) FormatMagickString(path,MaxTextExtent,"%s/share/%s/",prefix,
709         MAGICKCORE_SHARE_CONFIGURE_RELATIVE_PATH);
710       (void) AppendValueToLinkedList(paths,ConstantString(path));
711       (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/",prefix,
712         MAGICKCORE_CONFIGURE_RELATIVE_PATH);
713       (void) AppendValueToLinkedList(paths,ConstantString(path));
714 #endif
715     }
716 #endif
717   {
718     char
719       *home;
720
721     home=GetEnvironmentValue("HOME");
722     if (home == (char *) NULL)
723       home=GetEnvironmentValue("USERPROFILE");
724     if (home != (char *) NULL)
725       {
726         /*
727           Search $HOME/.magick.
728         */
729         (void) FormatMagickString(path,MaxTextExtent,"%s%s.magick%s",home,
730           DirectorySeparator,DirectorySeparator);
731         (void) AppendValueToLinkedList(paths,ConstantString(path));
732         home=DestroyString(home);
733       }
734   }
735 #if defined(__WINDOWS__)
736   {
737     char
738       module_path[MaxTextExtent];
739
740     if ((NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse) ||
741         (NTGetModulePath("CORE_DB_magick_.dll",module_path) != MagickFalse))
742       {
743         char
744           *element;
745
746         /*
747           Search module path.
748         */
749         (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
750           DirectorySeparator);
751         element=(char *) RemoveElementByValueFromLinkedList(paths,path);
752         if (element != (char *) NULL)
753           element=DestroyString(element);
754         (void) AppendValueToLinkedList(paths,ConstantString(path));
755       }
756     if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
757       {
758         /*
759           Search PerlMagick module path.
760         */
761         (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
762           DirectorySeparator);
763         (void) AppendValueToLinkedList(paths,ConstantString(path));
764         (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
765           "\\inc\\lib\\auto\\Image\\Magick\\");
766         (void) AppendValueToLinkedList(paths,ConstantString(path));
767       }
768   }
769 #endif
770   /*
771     Search current directory.
772   */
773   (void) AppendValueToLinkedList(paths,ConstantString(""));
774   return(paths);
775 }
776 \f
777 /*
778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
779 %                                                                             %
780 %                                                                             %
781 %                                                                             %
782 %   G e t C o n f i g u r e V a l u e                                         %
783 %                                                                             %
784 %                                                                             %
785 %                                                                             %
786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
787 %
788 %  GetConfigureValue() returns the value associated with the configure info.
789 %
790 %  The format of the GetConfigureValue method is:
791 %
792 %      const char *GetConfigureValue(const ConfigureInfo *configure_info)
793 %
794 %  A description of each parameter follows:
795 %
796 %    o configure_info:  The configure info.
797 %
798 */
799 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
800 {
801   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
802   assert(configure_info != (ConfigureInfo *) NULL);
803   assert(configure_info->signature == MagickSignature);
804   return(configure_info->value);
805 }
806 \f
807 /*
808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
809 %                                                                             %
810 %                                                                             %
811 %                                                                             %
812 +   I n i t i a l i z e C o n f i g u r e L i s t                             %
813 %                                                                             %
814 %                                                                             %
815 %                                                                             %
816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817 %
818 %  InitializeConfigureList() initializes the configure list.
819 %
820 %  The format of the InitializeConfigureList method is:
821 %
822 %      MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
823 %
824 %  A description of each parameter follows.
825 %
826 %    o exception: return any errors or warnings in this structure.
827 %
828 */
829 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
830 {
831   if ((configure_list == (LinkedListInfo *) NULL) &&
832       (instantiate_configure == MagickFalse))
833     {
834       AcquireSemaphoreInfo(&configure_semaphore);
835       if ((configure_list == (LinkedListInfo *) NULL) &&
836           (instantiate_configure == MagickFalse))
837         {
838           (void) LoadConfigureLists(ConfigureFilename,exception);
839           instantiate_configure=MagickTrue;
840         }
841       RelinquishSemaphoreInfo(configure_semaphore);
842     }
843   return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
844 }
845 \f
846 /*
847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
848 %                                                                             %
849 %                                                                             %
850 %                                                                             %
851 +   I n s t a n t i a t e C o n f i g u r e F a c i l i t y                   %
852 %                                                                             %
853 %                                                                             %
854 %                                                                             %
855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856 %
857 %  InstantiateConfigureFacility() instantiates the configure facility.
858 %
859 %  The format of the InstantiateConfigureFacility method is:
860 %
861 %      MagickBooleanType InstantiateConfigureFacility(void)
862 %
863 */
864 MagickExport MagickBooleanType InstantiateConfigureFacility(void)
865 {
866   AcquireSemaphoreInfo(&configure_semaphore);
867   RelinquishSemaphoreInfo(configure_semaphore);
868   return(MagickTrue);
869 }
870 \f
871 /*
872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
873 %                                                                             %
874 %                                                                             %
875 %                                                                             %
876 %  L i s t C o n f i g u r e I n f o                                          %
877 %                                                                             %
878 %                                                                             %
879 %                                                                             %
880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881 %
882 %  ListConfigureInfo() lists the configure info to a file.
883 %
884 %  The format of the ListConfigureInfo method is:
885 %
886 %      MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
887 %
888 %  A description of each parameter follows.
889 %
890 %    o file:  An pointer to a FILE.
891 %
892 %    o exception: return any errors or warnings in this structure.
893 %
894 */
895 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
896   ExceptionInfo *exception)
897 {
898   const char
899     *name,
900     *path,
901     *value;
902
903   const ConfigureInfo
904     **configure_info;
905
906   long
907     j;
908
909   register long
910     i;
911
912   unsigned long
913     number_options;
914
915   if (file == (const FILE *) NULL)
916     file=stdout;
917   configure_info=GetConfigureInfoList("*",&number_options,exception);
918   if (configure_info == (const ConfigureInfo **) NULL)
919     return(MagickFalse);
920   path=(const char *) NULL;
921   for (i=0; i < (long) number_options; i++)
922   {
923     if (configure_info[i]->stealth != MagickFalse)
924       continue;
925     if ((path == (const char *) NULL) ||
926         (LocaleCompare(path,configure_info[i]->path) != 0))
927       {
928         if (configure_info[i]->path != (char *) NULL)
929           (void) fprintf(file,"\nPath: %s\n\n",configure_info[i]->path);
930         (void) fprintf(file,"Name          Value\n");
931         (void) fprintf(file,"-------------------------------------------------"
932           "------------------------------\n");
933       }
934     path=configure_info[i]->path;
935     name="unknown";
936     if (configure_info[i]->name != (char *) NULL)
937       name=configure_info[i]->name;
938     (void) fprintf(file,"%s",name);
939     for (j=(long) strlen(name); j <= 12; j++)
940       (void) fprintf(file," ");
941     (void) fprintf(file," ");
942     value="unknown";
943     if (configure_info[i]->value != (char *) NULL)
944       value=configure_info[i]->value;
945     (void) fprintf(file,"%s",value);
946     (void) fprintf(file,"\n");
947   }
948   (void) fflush(file);
949   configure_info=(const ConfigureInfo **)
950     RelinquishMagickMemory((void *) configure_info);
951   return(MagickTrue);
952 }
953 \f
954 /*
955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956 %                                                                             %
957 %                                                                             %
958 %                                                                             %
959 +   L o a d C o n f i g u r e L i s t                                         %
960 %                                                                             %
961 %                                                                             %
962 %                                                                             %
963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
964 %
965 %  LoadConfigureList() loads the configure configuration file which provides a
966 %  mapping between configure attributes and a configure name.
967 %
968 %  The format of the LoadConfigureList method is:
969 %
970 %      MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
971 %        const unsigned long depth,ExceptionInfo *exception)
972 %
973 %  A description of each parameter follows:
974 %
975 %    o xml:  The configure list in XML format.
976 %
977 %    o filename:  The configure list filename.
978 %
979 %    o depth: depth of <include /> statements.
980 %
981 %    o exception: return any errors or warnings in this structure.
982 %
983 */
984 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
985   const unsigned long depth,ExceptionInfo *exception)
986 {
987   char
988     keyword[MaxTextExtent],
989     *token;
990
991   ConfigureInfo
992     *configure_info;
993
994   const char
995     *q;
996
997   MagickBooleanType
998     status;
999
1000   /*
1001     Load the configure map file.
1002   */
1003   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1004     "Loading configure file \"%s\" ...",filename);
1005   if (configure_list == (LinkedListInfo *) NULL)
1006     {
1007       configure_list=NewLinkedList(0);
1008       if (configure_list == (LinkedListInfo *) NULL)
1009         {
1010           ThrowFileException(exception,ResourceLimitError,
1011             "MemoryAllocationFailed",filename);
1012           return(MagickFalse);
1013         }
1014     }
1015   status=MagickTrue;
1016   configure_info=(ConfigureInfo *) NULL;
1017   if (xml == (char *) NULL)
1018     token=AcquireString(ConfigureMap);
1019   else
1020     token=AcquireString((char *) xml);
1021   for (q=(char *) xml; *q != '\0'; )
1022   {
1023     /*
1024       Interpret XML.
1025     */
1026     GetMagickToken(q,&q,token);
1027     if (*token == '\0')
1028       break;
1029     (void) CopyMagickString(keyword,token,MaxTextExtent);
1030     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1031       {
1032         /*
1033           Doctype element.
1034         */
1035         while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1036           GetMagickToken(q,&q,token);
1037         continue;
1038       }
1039     if (LocaleNCompare(keyword,"<!--",4) == 0)
1040       {
1041         /*
1042           Comment element.
1043         */
1044         while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1045           GetMagickToken(q,&q,token);
1046         continue;
1047       }
1048     if (LocaleCompare(keyword,"<include") == 0)
1049       {
1050         /*
1051           Include element.
1052         */
1053         while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1054         {
1055           (void) CopyMagickString(keyword,token,MaxTextExtent);
1056           GetMagickToken(q,&q,token);
1057           if (*token != '=')
1058             continue;
1059           GetMagickToken(q,&q,token);
1060           if (LocaleCompare(keyword,"file") == 0)
1061             {
1062               if (depth > 200)
1063                 (void) ThrowMagickException(exception,GetMagickModule(),
1064                   ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1065               else
1066                 {
1067                   char
1068                     path[MaxTextExtent],
1069                     *xml;
1070
1071                   GetPathComponent(filename,HeadPath,path);
1072                   if (*path != '\0')
1073                     (void) ConcatenateMagickString(path,DirectorySeparator,
1074                       MaxTextExtent);
1075                   if (*token == *DirectorySeparator)
1076                     (void) CopyMagickString(path,token,MaxTextExtent);
1077                   else
1078                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
1079                   xml=FileToString(path,~0,exception);
1080                   if (xml != (char *) NULL)
1081                     {
1082                       status=LoadConfigureList(xml,path,depth+1,exception);
1083                       xml=(char *) RelinquishMagickMemory(xml);
1084                     }
1085                 }
1086             }
1087         }
1088         continue;
1089       }
1090     if (LocaleCompare(keyword,"<configure") == 0)
1091       {
1092         /*
1093           Configure element.
1094         */
1095         configure_info=(ConfigureInfo *) AcquireMagickMemory(
1096           sizeof(*configure_info));
1097         if (configure_info == (ConfigureInfo *) NULL)
1098           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1099         (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1100         configure_info->path=ConstantString(filename);
1101         configure_info->signature=MagickSignature;
1102         continue;
1103       }
1104     if (configure_info == (ConfigureInfo *) NULL)
1105       continue;
1106     if (LocaleCompare(keyword,"/>") == 0)
1107       {
1108         status=AppendValueToLinkedList(configure_list,configure_info);
1109         if (status == MagickFalse)
1110           (void) ThrowMagickException(exception,GetMagickModule(),
1111             ResourceLimitError,"MemoryAllocationFailed","`%s'",
1112             configure_info->name);
1113         configure_info=(ConfigureInfo *) NULL;
1114       }
1115     /*
1116       Parse configure element.
1117     */
1118     GetMagickToken(q,(const char **) NULL,token);
1119     if (*token != '=')
1120       continue;
1121     GetMagickToken(q,&q,token);
1122     GetMagickToken(q,&q,token);
1123     switch (*keyword)
1124     {
1125       case 'N':
1126       case 'n':
1127       {
1128         if (LocaleCompare((char *) keyword,"name") == 0)
1129           {
1130             configure_info->name=ConstantString(token);
1131             break;
1132           }
1133         break;
1134       }
1135       case 'S':
1136       case 's':
1137       {
1138         if (LocaleCompare((char *) keyword,"stealth") == 0)
1139           {
1140             configure_info->stealth=IsMagickTrue(token);
1141             break;
1142           }
1143         break;
1144       }
1145       case 'V':
1146       case 'v':
1147       {
1148         if (LocaleCompare((char *) keyword,"value") == 0)
1149           {
1150             configure_info->value=ConstantString(token);
1151             break;
1152           }
1153         break;
1154       }
1155       default:
1156         break;
1157     }
1158   }
1159   token=(char *) RelinquishMagickMemory(token);
1160   return(status);
1161 }
1162 \f
1163 /*
1164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1165 %                                                                             %
1166 %                                                                             %
1167 %                                                                             %
1168 %  L o a d C o n f i g u r e L i s t s                                        %
1169 %                                                                             %
1170 %                                                                             %
1171 %                                                                             %
1172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1173 %
1174 %  LoadConfigureList() loads one or more configure configuration files which
1175 %  provides a mapping between configure attributes and a configure name.
1176 %
1177 %  The format of the LoadConfigureLists method is:
1178 %
1179 %      MagickBooleanType LoadConfigureLists(const char *filename,
1180 %        ExceptionInfo *exception)
1181 %
1182 %  A description of each parameter follows:
1183 %
1184 %    o filename: the font file name.
1185 %
1186 %    o exception: return any errors or warnings in this structure.
1187 %
1188 */
1189 static MagickBooleanType LoadConfigureLists(const char *filename,
1190   ExceptionInfo *exception)
1191 {
1192 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
1193   return(LoadConfigureList(ConfigureMap,"built-in",0,exception));
1194 #else
1195   const StringInfo
1196     *option;
1197
1198   LinkedListInfo
1199     *options;
1200
1201   MagickStatusType
1202     status;
1203
1204   status=MagickFalse;
1205   options=GetConfigureOptions(filename,exception);
1206   option=(const StringInfo *) GetNextValueInLinkedList(options);
1207   while (option != (const StringInfo *) NULL)
1208   {
1209     status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1210       GetStringInfoPath(option),0,exception);
1211     option=(const StringInfo *) GetNextValueInLinkedList(options);
1212   }
1213   options=DestroyConfigureOptions(options);
1214   if ((configure_list == (LinkedListInfo *) NULL) ||
1215       (IsLinkedListEmpty(configure_list) != MagickFalse))
1216     status|=LoadConfigureList(ConfigureMap,"built-in",0,exception);
1217   return(status != 0 ? MagickTrue : MagickFalse);
1218 #endif
1219 }