2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
13 % MagickCore Image Configure Methods %
20 % Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/client.h"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/configure-private.h"
47 #include "MagickCore/exception.h"
48 #include "MagickCore/exception-private.h"
49 #include "MagickCore/hashmap.h"
50 #include "MagickCore/log.h"
51 #include "MagickCore/memory_.h"
52 #include "MagickCore/semaphore.h"
53 #include "MagickCore/string_.h"
54 #include "MagickCore/string-private.h"
55 #include "MagickCore/token.h"
56 #include "MagickCore/utility.h"
57 #include "MagickCore/utility-private.h"
58 #include "MagickCore/xml-tree.h"
63 #define ConfigureFilename "configure.xml"
66 #define MAGICKCORE_FEATURE_OPENMP_STR "OpenMP "
68 #define MAGICKCORE_FEATURE_OPENMP_STR ""
71 #define MAGICKCORE_FEATURE_OPENCL_STR "OpenCL "
73 #define MAGICKCORE_FEATURE_OPENCL_STR ""
75 #ifdef MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
76 #define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR "Zero-Configuration "
78 #define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR ""
81 #define MAGICKCORE_FEATURE_HDRI_STR "HDRI"
83 #define MAGICKCORE_FEATURE_HDRI_STR ""
86 #define MAGICKCORE_FEATURES_STR MAGICKCORE_FEATURE_OPENMP_STR MAGICKCORE_FEATURE_OPENCL_STR MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR MAGICKCORE_FEATURE_HDRI_STR
91 typedef struct _ConfigureMapInfo
101 static const ConfigureMapInfo
104 { "NAME", "ImageMagick" },
105 { "QuantumDepth", MAGICKCORE_STRING_XQUOTE(MAGICKCORE_QUANTUM_DEPTH) } ,
106 { "FEATURES", MAGICKCORE_FEATURES_STR }
109 static LinkedListInfo
110 *configure_list = (LinkedListInfo *) NULL;
113 *configure_semaphore = (SemaphoreInfo *) NULL;
115 static volatile MagickBooleanType
116 instantiate_configure = MagickFalse;
119 Forward declarations.
121 static MagickBooleanType
122 InitializeConfigureList(ExceptionInfo *),
123 LoadConfigureLists(const char *,ExceptionInfo *);
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 + 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 %
134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 % ConfigureComponentGenesis() instantiates the configure component.
138 % The format of the ConfigureComponentGenesis method is:
140 % MagickBooleanType ConfigureComponentGenesis(void)
143 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
145 AcquireSemaphoreInfo(&configure_semaphore);
150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 + 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 %
158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160 % ConfigureComponentTerminus() destroys the configure component.
162 % The format of the ConfigureComponentTerminus method is:
164 % ConfigureComponentTerminus(void)
168 static void *DestroyConfigureElement(void *configure_info)
170 register ConfigureInfo
173 p=(ConfigureInfo *) configure_info;
174 if (p->exempt == MagickFalse)
176 if (p->value != (char *) NULL)
177 p->value=DestroyString(p->value);
178 if (p->name != (char *) NULL)
179 p->name=DestroyString(p->name);
180 if (p->path != (char *) NULL)
181 p->path=DestroyString(p->path);
183 p=(ConfigureInfo *) RelinquishMagickMemory(p);
184 return((void *) NULL);
187 MagickPrivate void ConfigureComponentTerminus(void)
189 if (configure_semaphore == (SemaphoreInfo *) NULL)
190 AcquireSemaphoreInfo(&configure_semaphore);
191 LockSemaphoreInfo(configure_semaphore);
192 if (configure_list != (LinkedListInfo *) NULL)
193 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
194 configure_list=(LinkedListInfo *) NULL;
195 instantiate_configure=MagickFalse;
196 UnlockSemaphoreInfo(configure_semaphore);
197 DestroySemaphoreInfo(&configure_semaphore);
201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205 % D e s t r o y C o n f i g u r e O p t i o n s %
209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
211 % DestroyConfigureOptions() releases memory associated with an configure
214 % The format of the DestroyProfiles method is:
216 % LinkedListInfo *DestroyConfigureOptions(Image *image)
218 % A description of each parameter follows:
220 % o image: the image.
224 static void *DestroyOptions(void *option)
226 return(DestroyStringInfo((StringInfo *) option));
229 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
231 assert(options != (LinkedListInfo *) NULL);
232 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
233 return(DestroyLinkedList(options,DestroyOptions));
237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241 + G e t C o n f i g u r e I n f o %
245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
247 % GetConfigureInfo() searches the configure list for the specified name and if
248 % found returns attributes for that element.
250 % The format of the GetConfigureInfo method is:
252 % const ConfigureInfo *GetConfigureInfo(const char *name,
253 % ExceptionInfo *exception)
255 % A description of each parameter follows:
257 % o configure_info: GetConfigureInfo() searches the configure list for the
258 % specified name and if found returns attributes for that element.
260 % o name: the configure name.
262 % o exception: return any errors or warnings in this structure.
265 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
266 ExceptionInfo *exception)
268 register const ConfigureInfo
271 assert(exception != (ExceptionInfo *) NULL);
272 if ((configure_list == (LinkedListInfo *) NULL) ||
273 (instantiate_configure == MagickFalse))
274 if (InitializeConfigureList(exception) == MagickFalse)
275 return((const ConfigureInfo *) NULL);
276 if ((configure_list == (LinkedListInfo *) NULL) ||
277 (IsLinkedListEmpty(configure_list) != MagickFalse))
278 return((const ConfigureInfo *) NULL);
279 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
280 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
282 Search for configure tag.
284 LockSemaphoreInfo(configure_semaphore);
285 ResetLinkedListIterator(configure_list);
286 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
287 while (p != (const ConfigureInfo *) NULL)
289 if (LocaleCompare(name,p->name) == 0)
291 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
293 if (p != (ConfigureInfo *) NULL)
294 (void) InsertValueInLinkedList(configure_list,0,
295 RemoveElementByValueFromLinkedList(configure_list,p));
296 UnlockSemaphoreInfo(configure_semaphore);
301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 % G e t C o n f i g u r e I n f o L i s t %
309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 % GetConfigureInfoList() returns any configure options that match the
314 % The format of the GetConfigureInfoList function is:
316 % const ConfigureInfo **GetConfigureInfoList(const char *pattern,
317 % size_t *number_options,ExceptionInfo *exception)
319 % A description of each parameter follows:
321 % o pattern: Specifies a pointer to a text string containing a pattern.
323 % o number_options: This integer returns the number of configure options in
326 % o exception: return any errors or warnings in this structure.
330 #if defined(__cplusplus) || defined(c_plusplus)
334 static int ConfigureInfoCompare(const void *x,const void *y)
340 p=(const ConfigureInfo **) x,
341 q=(const ConfigureInfo **) y;
342 if (LocaleCompare((*p)->path,(*q)->path) == 0)
343 return(LocaleCompare((*p)->name,(*q)->name));
344 return(LocaleCompare((*p)->path,(*q)->path));
347 #if defined(__cplusplus) || defined(c_plusplus)
351 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
352 size_t *number_options,ExceptionInfo *exception)
357 register const ConfigureInfo
364 Allocate configure list.
366 assert(pattern != (char *) NULL);
367 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
368 assert(number_options != (size_t *) NULL);
370 p=GetConfigureInfo("*",exception);
371 if (p == (const ConfigureInfo *) NULL)
372 return((const ConfigureInfo **) NULL);
373 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
374 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
375 if (options == (const ConfigureInfo **) NULL)
376 return((const ConfigureInfo **) NULL);
378 Generate configure list.
380 LockSemaphoreInfo(configure_semaphore);
381 ResetLinkedListIterator(configure_list);
382 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
383 for (i=0; p != (const ConfigureInfo *) NULL; )
385 if ((p->stealth == MagickFalse) &&
386 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
388 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
390 UnlockSemaphoreInfo(configure_semaphore);
391 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
392 options[i]=(ConfigureInfo *) NULL;
393 *number_options=(size_t) i;
398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402 % G e t C o n f i g u r e L i s t %
406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 % GetConfigureList() returns any configure options that match the specified
411 % The format of the GetConfigureList function is:
413 % char **GetConfigureList(const char *pattern,
414 % size_t *number_options,ExceptionInfo *exception)
416 % A description of each parameter follows:
418 % o pattern: Specifies a pointer to a text string containing a pattern.
420 % o number_options: This integer returns the number of options in the list.
422 % o exception: return any errors or warnings in this structure.
426 #if defined(__cplusplus) || defined(c_plusplus)
430 static int ConfigureCompare(const void *x,const void *y)
438 return(LocaleCompare(*p,*q));
441 #if defined(__cplusplus) || defined(c_plusplus)
445 MagickExport char **GetConfigureList(const char *pattern,
446 size_t *number_options,ExceptionInfo *exception)
451 register const ConfigureInfo
458 Allocate configure list.
460 assert(pattern != (char *) NULL);
461 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
462 assert(number_options != (size_t *) NULL);
464 p=GetConfigureInfo("*",exception);
465 if (p == (const ConfigureInfo *) NULL)
466 return((char **) NULL);
467 options=(char **) AcquireQuantumMemory((size_t)
468 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
469 if (options == (char **) NULL)
470 return((char **) NULL);
471 LockSemaphoreInfo(configure_semaphore);
472 ResetLinkedListIterator(configure_list);
473 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
474 for (i=0; p != (const ConfigureInfo *) NULL; )
476 if ((p->stealth == MagickFalse) &&
477 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
478 options[i++]=ConstantString(p->name);
479 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
481 UnlockSemaphoreInfo(configure_semaphore);
482 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
483 options[i]=(char *) NULL;
484 *number_options=(size_t) i;
489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493 % G e t C o n f i g u r e O p t i o n %
497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 % GetConfigureOption() returns the value associated with the configure option.
501 % The format of the GetConfigureOption method is:
503 % char *GetConfigureOption(const char *option)
505 % A description of each parameter follows:
507 % o configure_info: The configure info.
510 MagickExport char *GetConfigureOption(const char *option)
521 assert(option != (const char *) NULL);
522 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
523 exception=AcquireExceptionInfo();
524 configure_info=GetConfigureInfo(option,exception);
525 exception=DestroyExceptionInfo(exception);
526 if (configure_info == (ConfigureInfo *) NULL)
527 return((char *) NULL);
528 value=GetConfigureValue(configure_info);
529 if ((value == (const char *) NULL) || (*value == '\0'))
530 return((char *) NULL);
531 return(ConstantString(value));
535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
539 % G e t C o n f i g u r e O p t i o n s %
543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545 % GetConfigureOptions() returns any Magick configuration options associated
546 % with the specified filename.
548 % The format of the GetConfigureOptions method is:
550 % LinkedListInfo *GetConfigureOptions(const char *filename,
551 % ExceptionInfo *exception)
553 % A description of each parameter follows:
555 % o filename: the configure file name.
557 % o exception: return any errors or warnings in this structure.
560 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
561 ExceptionInfo *exception)
576 assert(filename != (const char *) NULL);
577 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
578 assert(exception != (ExceptionInfo *) NULL);
579 (void) CopyMagickString(path,filename,MaxTextExtent);
581 Load XML from configuration files to linked-list.
583 options=NewLinkedList(0);
584 paths=GetConfigurePaths(filename,exception);
585 if (paths != (LinkedListInfo *) NULL)
587 ResetLinkedListIterator(paths);
588 element=(const char *) GetNextValueInLinkedList(paths);
589 while (element != (const char *) NULL)
591 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
592 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
593 "Searching for configure file: \"%s\"",path);
594 xml=ConfigureFileToStringInfo(path);
595 if (xml != (StringInfo *) NULL)
596 (void) AppendValueToLinkedList(options,xml);
597 element=(const char *) GetNextValueInLinkedList(paths);
599 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
601 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
602 if (GetNumberOfElementsInLinkedList(options) == 0)
607 blob=(char *) NTResourceToBlob(filename);
608 if (blob != (char *) NULL)
610 xml=AcquireStringInfo(0);
611 SetStringInfoLength(xml,strlen(blob)+1);
612 SetStringInfoDatum(xml,(unsigned char *) blob);
613 SetStringInfoPath(xml,filename);
614 (void) AppendValueToLinkedList(options,xml);
618 if (GetNumberOfElementsInLinkedList(options) == 0)
619 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
620 "UnableToOpenConfigureFile","`%s'",filename);
621 ResetLinkedListIterator(options);
626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
630 % G e t C o n f i g u r e P a t h s %
634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636 % GetConfigurePaths() returns any Magick configuration paths associated
637 % with the specified filename.
639 % The format of the GetConfigurePaths method is:
641 % LinkedListInfo *GetConfigurePaths(const char *filename,
642 % ExceptionInfo *exception)
644 % A description of each parameter follows:
646 % o filename: the configure file name.
648 % o exception: return any errors or warnings in this structure.
651 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
652 ExceptionInfo *exception)
654 #define RegistryKey "ConfigurePath"
655 #define MagickCoreDLL "CORE_RL_MagickCore_.dll"
656 #define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll"
664 assert(filename != (const char *) NULL);
665 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
666 assert(exception != (ExceptionInfo *) NULL);
667 (void) CopyMagickString(path,filename,MaxTextExtent);
668 paths=NewLinkedList(0);
674 Search $MAGICK_CONFIGURE_PATH.
676 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
677 if (configure_path != (char *) NULL)
683 for (p=configure_path-1; p != (char *) NULL; )
685 (void) CopyMagickString(path,p+1,MaxTextExtent);
686 q=strchr(path,DirectoryListSeparator);
687 if (q != (char *) NULL)
689 q=path+strlen(path)-1;
690 if ((q >= path) && (*q != *DirectorySeparator))
691 (void) ConcatenateMagickString(path,DirectorySeparator,
693 (void) AppendValueToLinkedList(paths,ConstantString(path));
694 p=strchr(p+1,DirectoryListSeparator);
696 configure_path=DestroyString(configure_path);
699 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
700 #if defined(MAGICKCORE_SHARE_PATH)
701 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
703 #if defined(MAGICKCORE_SHAREARCH_PATH)
704 (void) AppendValueToLinkedList(paths,ConstantString(
705 MAGICKCORE_SHAREARCH_PATH));
707 #if defined(MAGICKCORE_CONFIGURE_PATH)
708 (void) AppendValueToLinkedList(paths,ConstantString(
709 MAGICKCORE_CONFIGURE_PATH));
711 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
712 (void) AppendValueToLinkedList(paths,ConstantString(
713 MAGICKCORE_DOCUMENTATION_PATH));
715 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
721 Locate file via registry key.
723 key_value=NTRegistryKeyLookup(RegistryKey);
724 if (key_value != (unsigned char *) NULL)
726 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
728 (void) AppendValueToLinkedList(paths,ConstantString(path));
729 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
739 Search under MAGICK_HOME.
741 home=GetEnvironmentValue("MAGICK_HOME");
742 if (home != (char *) NULL)
744 #if !defined(MAGICKCORE_POSIX_SUPPORT)
745 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
747 (void) AppendValueToLinkedList(paths,ConstantString(path));
749 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
750 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
751 (void) AppendValueToLinkedList(paths,ConstantString(path));
752 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
753 MAGICKCORE_SHARE_RELATIVE_PATH);
754 (void) AppendValueToLinkedList(paths,ConstantString(path));
755 (void) FormatLocaleString(path,MaxTextExtent,"%s",
756 MAGICKCORE_SHAREARCH_PATH);
757 (void) AppendValueToLinkedList(paths,ConstantString(path));
759 home=DestroyString(home);
762 if (*GetClientPath() != '\0')
764 #if !defined(MAGICKCORE_POSIX_SUPPORT)
765 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
767 (void) AppendValueToLinkedList(paths,ConstantString(path));
770 prefix[MaxTextExtent];
773 Search based on executable directory if directory is known.
775 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
776 ChopPathComponents(prefix,1);
777 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
778 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
779 (void) AppendValueToLinkedList(paths,ConstantString(path));
780 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
781 MAGICKCORE_SHARE_RELATIVE_PATH);
782 (void) AppendValueToLinkedList(paths,ConstantString(path));
783 (void) FormatLocaleString(path,MaxTextExtent,"%s",
784 MAGICKCORE_SHAREARCH_PATH);
785 (void) AppendValueToLinkedList(paths,ConstantString(path));
789 Search current directory.
791 (void) AppendValueToLinkedList(paths,ConstantString(""));
797 home=GetEnvironmentValue("HOME");
798 if (home == (char *) NULL)
799 home=GetEnvironmentValue("USERPROFILE");
800 if (home != (char *) NULL)
803 Search $HOME/.magick.
805 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
806 DirectorySeparator,DirectorySeparator);
807 (void) AppendValueToLinkedList(paths,ConstantString(path));
808 home=DestroyString(home);
811 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
814 module_path[MaxTextExtent];
816 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
817 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
825 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
827 key_value=NTRegistryKeyLookup(RegistryKey);
828 if (key_value == (unsigned char *) NULL)
829 (void) AppendValueToLinkedList(paths,ConstantString(path));
831 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
833 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
836 Search PerlMagick module path.
838 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
840 (void) AppendValueToLinkedList(paths,ConstantString(path));
841 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
842 "\\inc\\lib\\auto\\Image\\Magick\\");
843 (void) AppendValueToLinkedList(paths,ConstantString(path));
851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
855 % G e t C o n f i g u r e V a l u e %
859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
861 % GetConfigureValue() returns the value associated with the configure info.
863 % The format of the GetConfigureValue method is:
865 % const char *GetConfigureValue(const ConfigureInfo *configure_info)
867 % A description of each parameter follows:
869 % o configure_info: The configure info.
872 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
874 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
875 assert(configure_info != (ConfigureInfo *) NULL);
876 assert(configure_info->signature == MagickSignature);
877 return(configure_info->value);
881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885 + I n i t i a l i z e C o n f i g u r e L i s t %
889 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
891 % InitializeConfigureList() initializes the configure list.
893 % The format of the InitializeConfigureList method is:
895 % MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
897 % A description of each parameter follows.
899 % o exception: return any errors or warnings in this structure.
902 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
904 if ((configure_list == (LinkedListInfo *) NULL) &&
905 (instantiate_configure == MagickFalse))
907 if (configure_semaphore == (SemaphoreInfo *) NULL)
908 AcquireSemaphoreInfo(&configure_semaphore);
909 LockSemaphoreInfo(configure_semaphore);
910 if ((configure_list == (LinkedListInfo *) NULL) &&
911 (instantiate_configure == MagickFalse))
913 (void) LoadConfigureLists(ConfigureFilename,exception);
914 instantiate_configure=MagickTrue;
916 UnlockSemaphoreInfo(configure_semaphore);
918 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926 % L i s t C o n f i g u r e I n f o %
930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932 % ListConfigureInfo() lists the configure info to a file.
934 % The format of the ListConfigureInfo method is:
936 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
938 % A description of each parameter follows.
940 % o file: An pointer to a FILE.
942 % o exception: return any errors or warnings in this structure.
945 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
946 ExceptionInfo *exception)
965 if (file == (const FILE *) NULL)
967 configure_info=GetConfigureInfoList("*",&number_options,exception);
968 if (configure_info == (const ConfigureInfo **) NULL)
970 path=(const char *) NULL;
971 for (i=0; i < (ssize_t) number_options; i++)
973 if (configure_info[i]->stealth != MagickFalse)
975 if ((path == (const char *) NULL) ||
976 (LocaleCompare(path,configure_info[i]->path) != 0))
978 if (configure_info[i]->path != (char *) NULL)
979 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
980 configure_info[i]->path);
981 (void) FormatLocaleFile(file,"Name Value\n");
982 (void) FormatLocaleFile(file,
983 "-------------------------------------------------"
984 "------------------------------\n");
986 path=configure_info[i]->path;
988 if (configure_info[i]->name != (char *) NULL)
989 name=configure_info[i]->name;
990 (void) FormatLocaleFile(file,"%s",name);
991 for (j=(ssize_t) strlen(name); j <= 13; j++)
992 (void) FormatLocaleFile(file," ");
993 (void) FormatLocaleFile(file," ");
995 if (configure_info[i]->value != (char *) NULL)
996 value=configure_info[i]->value;
997 (void) FormatLocaleFile(file,"%s",value);
998 (void) FormatLocaleFile(file,"\n");
1000 (void) fflush(file);
1001 configure_info=(const ConfigureInfo **)
1002 RelinquishMagickMemory((void *) configure_info);
1007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1011 + L o a d C o n f i g u r e L i s t %
1015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1017 % LoadConfigureList() loads the configure configuration file which provides a
1018 % mapping between configure attributes and a configure name.
1020 % The format of the LoadConfigureList method is:
1022 % MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
1023 % const size_t depth,ExceptionInfo *exception)
1025 % A description of each parameter follows:
1027 % o xml: The configure list in XML format.
1029 % o filename: The configure list filename.
1031 % o depth: depth of <include /> statements.
1033 % o exception: return any errors or warnings in this structure.
1036 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
1037 const size_t depth,ExceptionInfo *exception)
1040 keyword[MaxTextExtent],
1053 Load the configure map file.
1055 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1056 "Loading configure file \"%s\" ...",filename);
1057 if (configure_list == (LinkedListInfo *) NULL)
1059 configure_list=NewLinkedList(0);
1060 if (configure_list == (LinkedListInfo *) NULL)
1062 ThrowFileException(exception,ResourceLimitError,
1063 "MemoryAllocationFailed",filename);
1064 return(MagickFalse);
1068 configure_info=(ConfigureInfo *) NULL;
1069 token=AcquireString((char *) xml);
1070 for (q=(char *) xml; *q != '\0'; )
1075 GetMagickToken(q,&q,token);
1078 (void) CopyMagickString(keyword,token,MaxTextExtent);
1079 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1084 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1085 GetMagickToken(q,&q,token);
1088 if (LocaleNCompare(keyword,"<!--",4) == 0)
1093 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1094 GetMagickToken(q,&q,token);
1097 if (LocaleCompare(keyword,"<include") == 0)
1102 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1104 (void) CopyMagickString(keyword,token,MaxTextExtent);
1105 GetMagickToken(q,&q,token);
1108 GetMagickToken(q,&q,token);
1109 if (LocaleCompare(keyword,"file") == 0)
1112 (void) ThrowMagickException(exception,GetMagickModule(),
1113 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1117 path[MaxTextExtent],
1120 GetPathComponent(filename,HeadPath,path);
1122 (void) ConcatenateMagickString(path,DirectorySeparator,
1124 if (*token == *DirectorySeparator)
1125 (void) CopyMagickString(path,token,MaxTextExtent);
1127 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1128 xml=FileToString(path,~0UL,exception);
1129 if (xml != (char *) NULL)
1131 status=LoadConfigureList(xml,path,depth+1,exception);
1132 xml=(char *) RelinquishMagickMemory(xml);
1139 if (LocaleCompare(keyword,"<configure") == 0)
1144 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1145 sizeof(*configure_info));
1146 if (configure_info == (ConfigureInfo *) NULL)
1147 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1148 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1149 configure_info->path=ConstantString(filename);
1150 configure_info->exempt=MagickFalse;
1151 configure_info->signature=MagickSignature;
1154 if (configure_info == (ConfigureInfo *) NULL)
1156 if (LocaleCompare(keyword,"/>") == 0)
1158 status=AppendValueToLinkedList(configure_list,configure_info);
1159 if (status == MagickFalse)
1160 (void) ThrowMagickException(exception,GetMagickModule(),
1161 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1162 configure_info->name);
1163 configure_info=(ConfigureInfo *) NULL;
1167 Parse configure element.
1169 GetMagickToken(q,(const char **) NULL,token);
1172 GetMagickToken(q,&q,token);
1173 GetMagickToken(q,&q,token);
1179 if (LocaleCompare((char *) keyword,"name") == 0)
1181 configure_info->name=ConstantString(token);
1189 if (LocaleCompare((char *) keyword,"stealth") == 0)
1191 configure_info->stealth=IsStringTrue(token);
1199 if (LocaleCompare((char *) keyword,"value") == 0)
1201 configure_info->value=ConstantString(token);
1210 token=(char *) RelinquishMagickMemory(token);
1215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1219 % L o a d C o n f i g u r e L i s t s %
1223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1225 % LoadConfigureList() loads one or more configure configuration files which
1226 % provides a mapping between configure attributes and a configure name.
1228 % The format of the LoadConfigureLists method is:
1230 % MagickBooleanType LoadConfigureLists(const char *filename,
1231 % ExceptionInfo *exception)
1233 % A description of each parameter follows:
1235 % o filename: the font file name.
1237 % o exception: return any errors or warnings in this structure.
1240 static MagickBooleanType LoadConfigureLists(const char *filename,
1241 ExceptionInfo *exception)
1256 Load external configure map.
1258 if (configure_list == (LinkedListInfo *) NULL)
1260 configure_list=NewLinkedList(0);
1261 if (configure_list == (LinkedListInfo *) NULL)
1263 ThrowFileException(exception,ResourceLimitError,
1264 "MemoryAllocationFailed",filename);
1265 return(MagickFalse);
1269 options=GetConfigureOptions(filename,exception);
1270 option=(const StringInfo *) GetNextValueInLinkedList(options);
1271 while (option != (const StringInfo *) NULL)
1273 status&=LoadConfigureList((const char *) GetStringInfoDatum(option),
1274 GetStringInfoPath(option),0,exception);
1275 option=(const StringInfo *) GetNextValueInLinkedList(options);
1277 options=DestroyConfigureOptions(options);
1279 Load built-in configure map.
1281 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
1286 register const ConfigureMapInfo
1290 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1291 sizeof(*configure_info));
1292 if (configure_info == (ConfigureInfo *) NULL)
1294 (void) ThrowMagickException(exception,GetMagickModule(),
1295 ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
1298 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1299 configure_info->path=(char *) "[built-in]";
1300 configure_info->name=(char *) p->name;
1301 configure_info->value=(char *) p->value;
1302 configure_info->exempt=MagickTrue;
1303 configure_info->signature=MagickSignature;
1304 status&=AppendValueToLinkedList(configure_list,configure_info);
1305 if (status == MagickFalse)
1306 (void) ThrowMagickException(exception,GetMagickModule(),
1307 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1308 configure_info->name);
1310 return(status != 0 ? MagickTrue : MagickFalse);