root / ImageMagick / branches / ImageMagick-6.3.5 / magick / configure.c

Revision 7894, 37.0 kB (checked in by cristy, 15 months ago)
Line 
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%                     ImageMagick Image Configure Methods                     %
14%                                                                             %
15%                              Software Design                                %
16%                                John Cristy                                  %
17%                                 July 2003                                   %
18%                                                                             %
19%                                                                             %
20%  Copyright 1999-2007 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
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
57/*
58  Define declarations.
59*/
60#define ConfigureFilename  "configure.xml"
61
62/*
63  Static declarations.
64*/
65static const char
66  *ConfigureMap = (char *)
67    "<?xml version=\"1.0\"?>"
68    "<configuremap>"
69    "  <configure stealth=\"True\" />"
70    "</configuremap>";
71
72static LinkedListInfo
73  *configure_list = (LinkedListInfo *) NULL;
74
75static SemaphoreInfo
76  *configure_semaphore = (SemaphoreInfo *) NULL;
77
78static volatile MagickBooleanType
79  instantiate_configure = MagickFalse;
80
81/*
82  Forward declarations.
83*/
84static MagickBooleanType
85  InitializeConfigureList(ExceptionInfo *),
86  LoadConfigureLists(const char *,ExceptionInfo *);
87
88/*
89%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90%                                                                             %
91%                                                                             %
92%                                                                             %
93+   D e s t r o y C o n f i g u r e L i s t                                   %
94%                                                                             %
95%                                                                             %
96%                                                                             %
97%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98%
99%  DestroyConfigureList() deallocates memory associated with the configure list.
100%
101%  The format of the DestroyConfigureList method is:
102%
103%      DestroyConfigureList(void)
104%
105*/
106
107static 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
123MagickExport void DestroyConfigureList(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  configure_semaphore=DestroySemaphoreInfo(configure_semaphore);
132}
133
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
158static void *DestroyOptions(void *option)
159{
160  return(DestroyStringInfo((StringInfo *) option));
161}
162
163MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
164{
165  assert(options != (LinkedListInfo *) NULL);
166  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
167  return(DestroyLinkedList(options,DestroyOptions));
168}
169
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*/
199MagickExport 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 named configure.
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) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
229      "NoSuchElement","`%s'",name);
230  RelinquishSemaphoreInfo(configure_semaphore);
231  return(p);
232}
233
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)
265extern "C" {
266#endif
267
268static 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
285MagickExport 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
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)
361extern "C" {
362#endif
363
364static 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
379MagickExport 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
424/*
425%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426%                                                                             %
427%                                                                             %
428%                                                                             %
429%  G e t C o n f i g u r e O p t i o n s                                      %
430%                                                                             %
431%                                                                             %
432%                                                                             %
433%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434%
435%  GetConfigureOptions() returns any Magick configuration options associated
436%  with the specified filename.
437%
438%  The format of the GetConfigureOptions method is:
439%
440%      LinkedListInfo *GetConfigureOptions(const char *filename,
441%        ExceptionInfo *exception)
442%
443%  A description of each parameter follows:
444%
445%    o filename: The configure file name.
446%
447%    o exception: Return any errors or warnings in this structure.
448%
449*/
450MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
451  ExceptionInfo *exception)
452{
453  char
454    path[MaxTextExtent];
455
456  const char
457    *element;
458
459  LinkedListInfo
460    *options,
461    *paths;
462
463  StringInfo
464    *xml;
465
466  assert(filename != (const char *) NULL);
467  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
468  assert(exception != (ExceptionInfo *) NULL);
469  (void) CopyMagickString(path,filename,MaxTextExtent);
470  /*
471    Load XML from configuration files to linked-list.
472  */
473  options=NewLinkedList(0);
474  paths=GetConfigurePaths(filename,exception);
475  if (paths != (LinkedListInfo *) NULL)
476    {
477      ResetLinkedListIterator(paths);
478      element=(const char *) GetNextValueInLinkedList(paths);
479      while (element != (const char *) NULL)
480      {
481        (void) FormatMagickString(path,MaxTextExtent,"%s%s",element,filename);
482        (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
483          "Searching for configure file: \"%s\"",path);
484        xml=ConfigureFileToStringInfo(path);
485        if (xml != (StringInfo *) NULL)
486          (void) AppendValueToLinkedList(options,xml);
487        element=(const char *) GetNextValueInLinkedList(paths);
488      }
489      paths=DestroyLinkedList(paths,RelinquishMagickMemory);
490    }
491#if defined(__WINDOWS__)
492  {
493    char
494      *blob;
495
496    blob=(char *) NTResourceToBlob(filename);
497    if (blob != (char *) NULL)
498      {
499        xml=StringToStringInfo(blob);
500        SetStringInfoPath(xml,filename);
501        (void) AppendValueToLinkedList(options,xml);
502        blob=DestroyString(blob);
503      }
504  }
505#endif
506  if (GetNumberOfElementsInLinkedList(options) == 0)
507    (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
508      "UnableToOpenConfigureFile","`%s'",filename);
509  ResetLinkedListIterator(options);
510  return(options);
511}
512
513/*
514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
515%                                                                             %
516%                                                                             %
517%                                                                             %
518%  G e t C o n f i g u r e P a t h s                                          %
519%                                                                             %
520%                                                                             %
521%                                                                             %
522%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
523%
524%  GetConfigurePaths() returns any Magick configuration paths associated
525%  with the specified filename.
526%
527%  The format of the GetConfigurePaths method is:
528%
529%      LinkedListInfo *GetConfigurePaths(const char *filename,
530%        ExceptionInfo *exception)
531%
532%  A description of each parameter follows:
533%
534%    o filename: The configure file name.
535%
536%    o exception: Return any errors or warnings in this structure.
537%
538*/
539MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
540  ExceptionInfo *exception)
541{
542  char
543    path[MaxTextExtent];
544
545  LinkedListInfo
546    *paths;
547
548  assert(filename != (const char *) NULL);
549  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
550  assert(exception != (ExceptionInfo *) NULL);
551  (void) CopyMagickString(path,filename,MaxTextExtent);
552  paths=NewLinkedList(0);
553  {
554    char
555      *configure_path;
556
557    /*
558      Search $MAGICK_CONFIGURE_PATH.
559    */
560    configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
561    if (configure_path != (char *) NULL)
562      {
563        register char
564          *p,
565          *q;
566
567        for (p=configure_path-1; p != (char *) NULL; )
568        {
569          (void) CopyMagickString(path,p+1,MaxTextExtent);
570          q=strchr(path,DirectoryListSeparator);
571          if (q != (char *) NULL)
572            *q='\0';
573          q=path+strlen(path)-1;
574          if ((q >= path) && (*q != *DirectorySeparator))
575            (void) ConcatenateMagickString(path,DirectorySeparator,
576              MaxTextExtent);
577          (void) AppendValueToLinkedList(paths,ConstantString(path));
578          p=strchr(p+1,DirectoryListSeparator);
579        }
580        configure_path=DestroyString(configure_path);
581      }
582  }
583#if defined(UseInstalledMagick)
584#if defined(MagickLibConfigPath)
585  (void) AppendValueToLinkedList(paths,ConstantString(MagickLibConfigPath));
586#endif
587#if defined(MagickShareConfigPath)
588  (void) AppendValueToLinkedList(paths,ConstantString(MagickShareConfigPath));
589#endif
590#if defined(MagickDocumentPath)
591  (void) AppendValueToLinkedList(paths,ConstantString(MagickDocumentPath));
592#endif
593#if defined(MagickSharePath)
594  (void) AppendValueToLinkedList(paths,ConstantString(MagickSharePath));
595#endif
596#if defined(__WINDOWS__) && !(defined(MagickLibConfigPath) || defined(MagickShareConfigPath))
597  {
598    char
599      *registry_key,
600      *key_value;
601
602    /*
603      Locate file via registry key.
604    */
605    registry_key="ConfigurePath";
606    key_value=NTRegistryKeyLookup(registry_key);
607    if (key_value != (char *) NULL)
608      {
609        (void) FormatMagickString(path,MaxTextExtent,"%s%s",key_value,
610          DirectorySeparator);
611        (void) AppendValueToLinkedList(paths,ConstantString(path));
612      }
613  }
614#endif
615#else
616  {
617    char
618      *home;
619
620    /*
621      Search under MAGICK_HOME.
622    */
623    home=GetEnvironmentValue("MAGICK_HOME");
624    if (home != (char *) NULL)
625      {
626#if !defined(POSIX)
627        (void) FormatMagickString(path,MaxTextExtent,"%s%s",home,
628          DirectorySeparator);
629        (void) AppendValueToLinkedList(paths,ConstantString(path));
630#else
631        (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/",home,
632          MagickLibConfigSubDir);
633        (void) AppendValueToLinkedList(paths,ConstantString(path));
634        (void) FormatMagickString(path,MaxTextExtent,"%s/share/%s/",home,
635          MagickShareConfigSubDir);
636        (void) AppendValueToLinkedList(paths,ConstantString(path));
637#endif
638        home=DestroyString(home);
639      }
640    }
641  if (*GetClientPath() != '\0')
642    {
643#if !defined(POSIX)
644      (void) FormatMagickString(path,MaxTextExtent,"%s%s",GetClientPath(),
645        DirectorySeparator);
646      (void) AppendValueToLinkedList(paths,ConstantString(path));
647#else
648      char
649        prefix[MaxTextExtent];
650
651      /*
652        Search based on executable directory if directory is known.
653      */
654      (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
655      ChopPathComponents(prefix,1);
656      (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/",prefix,
657        MagickLibConfigSubDir);
658      (void) AppendValueToLinkedList(paths,ConstantString(path));
659      (void) FormatMagickString(path,MaxTextExtent,"%s/share/%s/",prefix,
660        MagickShareConfigSubDir);
661      (void) AppendValueToLinkedList(paths,ConstantString(path));
662#endif
663    }
664#endif
665  {
666    char
667      *home;
668
669    home=GetEnvironmentValue("HOME");
670    if (home == (char *) NULL)
671      home=GetEnvironmentValue("USERPROFILE");
672    if (home != (char *) NULL)
673      {
674        /*
675          Search $HOME/.magick.
676        */
677        (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",home,
678          *home == '/' ? "/.magick" : "",DirectorySeparator);
679        (void) AppendValueToLinkedList(paths,ConstantString(path));
680        home=DestroyString(home);
681      }
682  }
683#if defined(__WINDOWS__)
684  {
685    char
686      module_path[MaxTextExtent];
687
688    if (NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse)
689      {
690        char
691          *element;
692
693        /*
694          Search module path.
695        */
696        (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
697          DirectorySeparator);
698        element=(char *) RemoveElementByValueFromLinkedList(paths,path);
699        if (element != (char *) NULL)
700          element=DestroyString(element);
701        (void) AppendValueToLinkedList(paths,ConstantString(path));
702      }
703    if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
704      {
705        /*
706          Search PerlMagick module path.
707        */
708        (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
709          DirectorySeparator);
710        (void) AppendValueToLinkedList(paths,ConstantString(path));
711        (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
712          "\\inc\\lib\\auto\\Image\\Magick\\");
713        (void) AppendValueToLinkedList(paths,ConstantString(path));
714      }
715  }
716#endif
717  /*
718    Search current directory.
719  */
720  (void) AppendValueToLinkedList(paths,ConstantString(""));
721  return(paths);
722}
723
724/*
725%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
726%                                                                             %
727%                                                                             %
728%                                                                             %
729%   G e t C o n f i g u r e V a l u e                                         %
730%                                                                             %
731%                                                                             %
732%                                                                             %
733%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
734%
735%  GetConfigureValue() returns the value associated with the configure info.
736%
737%  The format of the GetConfigureValue method is:
738%
739%      const char *GetConfigureValue(const ConfigureInfo *configure_info)
740%
741%  A description of each parameter follows:
742%
743%    o configure_info:  The configure info.
744%
745*/
746MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
747{
748  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
749  assert(configure_info != (ConfigureInfo *) NULL);
750  assert(configure_info->signature == MagickSignature);
751  return(configure_info->value);
752}
753
754/*
755%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
756%                                                                             %
757%                                                                             %
758%                                                                             %
759+   I n i t i a l i z e C o n f i g u r e L i s t                             %
760%                                                                             %
761%                                                                             %
762%                                                                             %
763%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
764%
765%  InitializeConfigureList() initializes the configure list.
766%
767%  The format of the InitializeConfigureList method is:
768%
769%      MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
770%
771%  A description of each parameter follows.
772%
773%    o exception: Return any errors or warnings in this structure.
774%
775*/
776static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
777{
778  if ((configure_list == (LinkedListInfo *) NULL) &&
779      (instantiate_configure == MagickFalse))
780    {
781      AcquireSemaphoreInfo(&configure_semaphore);
782      if ((configure_list == (LinkedListInfo *) NULL) &&
783          (instantiate_configure == MagickFalse))
784        {
785          (void) LoadConfigureLists(ConfigureFilename,exception);
786          instantiate_configure=MagickTrue;
787        }
788      RelinquishSemaphoreInfo(configure_semaphore);
789    }
790  return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
791}
792
793/*
794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795%                                                                             %
796%                                                                             %
797%                                                                             %
798%  L i s t C o n f i g u r e I n f o                                          %
799%                                                                             %
800%                                                                             %
801%                                                                             %
802%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803%
804%  ListConfigureInfo() lists the configure info to a file.
805%
806%  The format of the ListConfigureInfo method is:
807%
808%      MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
809%
810%  A description of each parameter follows.
811%
812%    o file:  An pointer to a FILE.
813%
814%    o exception: Return any errors or warnings in this structure.
815%
816*/
817MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
818  ExceptionInfo *exception)
819{
820  const char
821    *name,
822    *path,
823    *value;
824
825  const ConfigureInfo
826    **configure_info;
827
828  long
829    j;
830
831  register long
832    i;
833
834  unsigned long
835    number_options;
836
837  if (file == (const FILE *) NULL)
838    file=stdout;
839  configure_info=GetConfigureInfoList("*",&number_options,exception);
840  if (configure_info == (const ConfigureInfo **) NULL)
841    return(MagickFalse);
842  path=(const char *) NULL;
843  for (i=0; i < (long) number_options; i++)
844  {
845    if (configure_info[i]->stealth != MagickFalse)
846      continue;
847    if ((path == (const char *) NULL) ||
848        (LocaleCompare(path,configure_info[i]->path) != 0))
849      {
850        if (configure_info[i]->path != (char *) NULL)
851          (void) fprintf(file,"\nPath: %s\n\n",configure_info[i]->path);
852        (void) fprintf(file,"Name          Value\n");
853        (void) fprintf(file,"-------------------------------------------------"
854          "------------------------------\n");
855      }
856    path=configure_info[i]->path;
857    name="unknown";
858    if (configure_info[i]->name != (char *) NULL)
859      name=configure_info[i]->name;
860    (void) fprintf(file,"%s",name);
861    for (j=(long) strlen(name); j <= 12; j++)
862      (void) fprintf(file," ");
863    (void) fprintf(file," ");
864    value="unknown";
865    if (configure_info[i]->value != (char *) NULL)
866      value=configure_info[i]->value;
867    (void) fprintf(file,"%s",value);
868    (void) fprintf(file,"\n");
869  }
870  (void) fflush(file);
871  configure_info=(const ConfigureInfo **)
872    RelinquishMagickMemory((void *) configure_info);
873  return(MagickTrue);
874}
875
876/*
877%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
878%                                                                             %
879%                                                                             %
880%                                                                             %
881+   L o a d C o n f i g u r e L i s t                                         %
882%                                                                             %
883%                                                                             %
884%                                                                             %
885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886%
887%  LoadConfigureList() loads the configure configuration file which provides a
888%  mapping between configure attributes and a configure name.
889%
890%  The format of the LoadConfigureList method is:
891%
892%      MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
893%        const unsigned long depth,ExceptionInfo *exception)
894%
895%  A description of each parameter follows:
896%
897%    o xml:  The configure list in XML format.
898%
899%    o filename:  The configure list filename.
900%
901%    o depth: depth of <include /> statements.
902%
903%    o exception: Return any errors or warnings in this structure.
904%
905*/
906static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
907  const unsigned long depth,ExceptionInfo *exception)
908{
909  const char
910    *attribute;
911
912  ConfigureInfo
913    *configure_info = (ConfigureInfo *) NULL;
914
915  MagickBooleanType
916    status;
917<