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"
59 #include "MagickCore/xml-tree-private.h"
64 #define ConfigureFilename "configure.xml"
67 #define MAGICKCORE_FEATURE_OPENMP_STR "OpenMP "
69 #define MAGICKCORE_FEATURE_OPENMP_STR ""
72 #define MAGICKCORE_FEATURE_OPENCL_STR "OpenCL "
74 #define MAGICKCORE_FEATURE_OPENCL_STR ""
76 #ifdef MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
77 #define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR "Zero-Configuration "
79 #define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR ""
82 #define MAGICKCORE_FEATURE_HDRI_STR "HDRI"
84 #define MAGICKCORE_FEATURE_HDRI_STR ""
87 #define MAGICKCORE_FEATURES_STR MAGICKCORE_FEATURE_OPENMP_STR MAGICKCORE_FEATURE_OPENCL_STR MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR MAGICKCORE_FEATURE_HDRI_STR
92 typedef struct _ConfigureMapInfo
102 static const ConfigureMapInfo
105 { "NAME", "ImageMagick" },
106 { "QuantumDepth", MAGICKCORE_STRING_XQUOTE(MAGICKCORE_QUANTUM_DEPTH) } ,
107 { "FEATURES", MAGICKCORE_FEATURES_STR }
110 static LinkedListInfo
111 *configure_cache = (LinkedListInfo *) NULL;
114 *configure_semaphore = (SemaphoreInfo *) NULL;
117 Forward declarations.
119 static MagickBooleanType
120 IsConfigureCacheInstantiated(ExceptionInfo *),
121 LoadConfigureCache(LinkedListInfo *,const char *,const char *,const size_t,
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129 % A c q u i r e C o n f i g u r e C a c h e %
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 % AcquireConfigureCache() caches one or more configure configurations which
136 % provides a mapping between configure attributes and a configure name.
138 % The format of the AcquireConfigureCache method is:
140 % LinkedListInfo *AcquireConfigureCache(const char *filename,
141 % ExceptionInfo *exception)
143 % A description of each parameter follows:
145 % o filename: the font file name.
147 % o exception: return any errors or warnings in this structure.
150 static LinkedListInfo *AcquireConfigureCache(const char *filename,
151 ExceptionInfo *exception)
167 Load external configure map.
169 configure_cache=NewLinkedList(0);
170 if (configure_cache == (LinkedListInfo *) NULL)
171 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
173 options=GetConfigureOptions(filename,exception);
174 option=(const StringInfo *) GetNextValueInLinkedList(options);
175 while (option != (const StringInfo *) NULL)
177 status&=LoadConfigureCache(configure_cache,(const char *)
178 GetStringInfoDatum(option),GetStringInfoPath(option),0,exception);
179 option=(const StringInfo *) GetNextValueInLinkedList(options);
181 options=DestroyConfigureOptions(options);
183 Load built-in configure map.
185 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
190 register const ConfigureMapInfo
194 configure_info=(ConfigureInfo *) AcquireMagickMemory(
195 sizeof(*configure_info));
196 if (configure_info == (ConfigureInfo *) NULL)
198 (void) ThrowMagickException(exception,GetMagickModule(),
199 ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
202 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
203 configure_info->path=(char *) "[built-in]";
204 configure_info->name=(char *) p->name;
205 configure_info->value=(char *) p->value;
206 configure_info->exempt=MagickTrue;
207 configure_info->signature=MagickSignature;
208 status&=AppendValueToLinkedList(configure_cache,configure_info);
209 if (status == MagickFalse)
210 (void) ThrowMagickException(exception,GetMagickModule(),
211 ResourceLimitError,"MemoryAllocationFailed","`%s'",
212 configure_info->name);
214 return(configure_cache);
218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 + 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 %
226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228 % ConfigureComponentGenesis() instantiates the configure component.
230 % The format of the ConfigureComponentGenesis method is:
232 % MagickBooleanType ConfigureComponentGenesis(void)
235 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
237 if (configure_semaphore == (SemaphoreInfo *) NULL)
238 configure_semaphore=AcquireSemaphoreInfo();
243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
247 + 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 %
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253 % ConfigureComponentTerminus() destroys the configure component.
255 % The format of the ConfigureComponentTerminus method is:
257 % ConfigureComponentTerminus(void)
261 static void *DestroyConfigureElement(void *configure_info)
263 register ConfigureInfo
266 p=(ConfigureInfo *) configure_info;
267 if (p->exempt == MagickFalse)
269 if (p->value != (char *) NULL)
270 p->value=DestroyString(p->value);
271 if (p->name != (char *) NULL)
272 p->name=DestroyString(p->name);
273 if (p->path != (char *) NULL)
274 p->path=DestroyString(p->path);
276 p=(ConfigureInfo *) RelinquishMagickMemory(p);
277 return((void *) NULL);
280 MagickPrivate void ConfigureComponentTerminus(void)
282 if (configure_semaphore == (SemaphoreInfo *) NULL)
283 ActivateSemaphoreInfo(&configure_semaphore);
284 LockSemaphoreInfo(configure_semaphore);
285 if (configure_cache != (LinkedListInfo *) NULL)
286 configure_cache=DestroyLinkedList(configure_cache,DestroyConfigureElement);
287 configure_cache=(LinkedListInfo *) NULL;
288 UnlockSemaphoreInfo(configure_semaphore);
289 RelinquishSemaphoreInfo(&configure_semaphore);
293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297 % D e s t r o y C o n f i g u r e O p t i o n s %
301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303 % DestroyConfigureOptions() releases memory associated with an configure
306 % The format of the DestroyProfiles method is:
308 % LinkedListInfo *DestroyConfigureOptions(Image *image)
310 % A description of each parameter follows:
312 % o image: the image.
316 static void *DestroyOptions(void *option)
318 return(DestroyStringInfo((StringInfo *) option));
321 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
323 assert(options != (LinkedListInfo *) NULL);
324 return(DestroyLinkedList(options,DestroyOptions));
328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332 + G e t C o n f i g u r e I n f o %
336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 % GetConfigureInfo() searches the configure list for the specified name and if
339 % found returns attributes for that element.
341 % The format of the GetConfigureInfo method is:
343 % const ConfigureInfo *GetConfigureInfo(const char *name,
344 % ExceptionInfo *exception)
346 % A description of each parameter follows:
348 % o configure_info: GetConfigureInfo() searches the configure list for the
349 % specified name and if found returns attributes for that element.
351 % o name: the configure name.
353 % o exception: return any errors or warnings in this structure.
356 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
357 ExceptionInfo *exception)
359 register const ConfigureInfo
362 assert(exception != (ExceptionInfo *) NULL);
363 if (IsConfigureCacheInstantiated(exception) == MagickFalse)
364 return((const ConfigureInfo *) NULL);
366 Search for configure tag.
368 LockSemaphoreInfo(configure_semaphore);
369 ResetLinkedListIterator(configure_cache);
370 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
371 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
373 UnlockSemaphoreInfo(configure_semaphore);
376 while (p != (const ConfigureInfo *) NULL)
378 if (LocaleCompare(name,p->name) == 0)
380 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
382 if (p != (ConfigureInfo *) NULL)
383 (void) InsertValueInLinkedList(configure_cache,0,
384 RemoveElementByValueFromLinkedList(configure_cache,p));
385 UnlockSemaphoreInfo(configure_semaphore);
390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394 % G e t C o n f i g u r e I n f o L i s t %
398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400 % GetConfigureInfoList() returns any configure options that match the
403 % The format of the GetConfigureInfoList function is:
405 % const ConfigureInfo **GetConfigureInfoList(const char *pattern,
406 % size_t *number_options,ExceptionInfo *exception)
408 % A description of each parameter follows:
410 % o pattern: Specifies a pointer to a text string containing a pattern.
412 % o number_options: This integer returns the number of configure options in
415 % o exception: return any errors or warnings in this structure.
419 #if defined(__cplusplus) || defined(c_plusplus)
423 static int ConfigureInfoCompare(const void *x,const void *y)
429 p=(const ConfigureInfo **) x,
430 q=(const ConfigureInfo **) y;
431 if (LocaleCompare((*p)->path,(*q)->path) == 0)
432 return(LocaleCompare((*p)->name,(*q)->name));
433 return(LocaleCompare((*p)->path,(*q)->path));
436 #if defined(__cplusplus) || defined(c_plusplus)
440 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
441 size_t *number_options,ExceptionInfo *exception)
446 register const ConfigureInfo
453 Allocate configure list.
455 assert(pattern != (char *) NULL);
456 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
457 assert(number_options != (size_t *) NULL);
459 p=GetConfigureInfo("*",exception);
460 if (p == (const ConfigureInfo *) NULL)
461 return((const ConfigureInfo **) NULL);
462 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
463 GetNumberOfElementsInLinkedList(configure_cache)+1UL,sizeof(*options));
464 if (options == (const ConfigureInfo **) NULL)
465 return((const ConfigureInfo **) NULL);
467 Generate configure list.
469 LockSemaphoreInfo(configure_semaphore);
470 ResetLinkedListIterator(configure_cache);
471 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
472 for (i=0; p != (const ConfigureInfo *) NULL; )
474 if ((p->stealth == MagickFalse) &&
475 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
477 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
479 UnlockSemaphoreInfo(configure_semaphore);
480 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
481 options[i]=(ConfigureInfo *) NULL;
482 *number_options=(size_t) i;
487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
491 % G e t C o n f i g u r e L i s t %
495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497 % GetConfigureList() returns any configure options that match the specified
500 % The format of the GetConfigureList function is:
502 % char **GetConfigureList(const char *pattern,
503 % size_t *number_options,ExceptionInfo *exception)
505 % A description of each parameter follows:
507 % o pattern: Specifies a pointer to a text string containing a pattern.
509 % o number_options: This integer returns the number of options in the list.
511 % o exception: return any errors or warnings in this structure.
515 #if defined(__cplusplus) || defined(c_plusplus)
519 static int ConfigureCompare(const void *x,const void *y)
527 return(LocaleCompare(*p,*q));
530 #if defined(__cplusplus) || defined(c_plusplus)
534 MagickExport char **GetConfigureList(const char *pattern,
535 size_t *number_options,ExceptionInfo *exception)
540 register const ConfigureInfo
547 Allocate configure list.
549 assert(pattern != (char *) NULL);
550 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
551 assert(number_options != (size_t *) NULL);
553 p=GetConfigureInfo("*",exception);
554 if (p == (const ConfigureInfo *) NULL)
555 return((char **) NULL);
556 options=(char **) AcquireQuantumMemory((size_t)
557 GetNumberOfElementsInLinkedList(configure_cache)+1UL,sizeof(*options));
558 if (options == (char **) NULL)
559 return((char **) NULL);
560 LockSemaphoreInfo(configure_semaphore);
561 ResetLinkedListIterator(configure_cache);
562 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
563 for (i=0; p != (const ConfigureInfo *) NULL; )
565 if ((p->stealth == MagickFalse) &&
566 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
567 options[i++]=ConstantString(p->name);
568 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
570 UnlockSemaphoreInfo(configure_semaphore);
571 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
572 options[i]=(char *) NULL;
573 *number_options=(size_t) i;
578 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582 % G e t C o n f i g u r e O p t i o n %
586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588 % GetConfigureOption() returns the value associated with the configure option.
590 % The format of the GetConfigureOption method is:
592 % char *GetConfigureOption(const char *option)
594 % A description of each parameter follows:
596 % o configure_info: The configure info.
599 MagickExport char *GetConfigureOption(const char *option)
610 assert(option != (const char *) NULL);
611 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
612 exception=AcquireExceptionInfo();
613 configure_info=GetConfigureInfo(option,exception);
614 exception=DestroyExceptionInfo(exception);
615 if (configure_info == (ConfigureInfo *) NULL)
616 return((char *) NULL);
617 value=GetConfigureValue(configure_info);
618 if ((value == (const char *) NULL) || (*value == '\0'))
619 return((char *) NULL);
620 return(ConstantString(value));
624 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
628 % G e t C o n f i g u r e O p t i o n s %
632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
634 % GetConfigureOptions() returns any Magick configuration options associated
635 % with the specified filename.
637 % The format of the GetConfigureOptions method is:
639 % LinkedListInfo *GetConfigureOptions(const char *filename,
640 % ExceptionInfo *exception)
642 % A description of each parameter follows:
644 % o filename: the configure file name.
646 % o exception: return any errors or warnings in this structure.
649 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
650 ExceptionInfo *exception)
665 assert(filename != (const char *) NULL);
666 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
667 assert(exception != (ExceptionInfo *) NULL);
668 (void) CopyMagickString(path,filename,MaxTextExtent);
670 Load XML from configuration files to linked-list.
672 options=NewLinkedList(0);
673 paths=GetConfigurePaths(filename,exception);
674 if (paths != (LinkedListInfo *) NULL)
676 ResetLinkedListIterator(paths);
677 element=(const char *) GetNextValueInLinkedList(paths);
678 while (element != (const char *) NULL)
680 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
681 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
682 "Searching for configure file: \"%s\"",path);
683 xml=ConfigureFileToStringInfo(path);
684 if (xml != (StringInfo *) NULL)
685 (void) AppendValueToLinkedList(options,xml);
686 element=(const char *) GetNextValueInLinkedList(paths);
688 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
690 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
691 if (GetNumberOfElementsInLinkedList(options) == 0)
696 blob=(char *) NTResourceToBlob(filename);
697 if (blob != (char *) NULL)
699 xml=AcquireStringInfo(0);
700 SetStringInfoLength(xml,strlen(blob)+1);
701 SetStringInfoDatum(xml,(unsigned char *) blob);
702 SetStringInfoPath(xml,filename);
703 (void) AppendValueToLinkedList(options,xml);
707 if (GetNumberOfElementsInLinkedList(options) == 0)
708 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
709 "UnableToOpenConfigureFile","`%s'",filename);
710 ResetLinkedListIterator(options);
715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
719 % G e t C o n f i g u r e P a t h s %
723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
725 % GetConfigurePaths() returns any Magick configuration paths associated
726 % with the specified filename.
728 % The format of the GetConfigurePaths method is:
730 % LinkedListInfo *GetConfigurePaths(const char *filename,
731 % ExceptionInfo *exception)
733 % A description of each parameter follows:
735 % o filename: the configure file name.
737 % o exception: return any errors or warnings in this structure.
740 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
741 ExceptionInfo *exception)
743 #define RegistryKey "ConfigurePath"
744 #define MagickCoreDLL "CORE_RL_MagickCore_.dll"
745 #define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll"
753 assert(filename != (const char *) NULL);
754 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
755 assert(exception != (ExceptionInfo *) NULL);
756 (void) CopyMagickString(path,filename,MaxTextExtent);
757 paths=NewLinkedList(0);
763 Search $MAGICK_CONFIGURE_PATH.
765 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
766 if (configure_path != (char *) NULL)
772 for (p=configure_path-1; p != (char *) NULL; )
774 (void) CopyMagickString(path,p+1,MaxTextExtent);
775 q=strchr(path,DirectoryListSeparator);
776 if (q != (char *) NULL)
778 q=path+strlen(path)-1;
779 if ((q >= path) && (*q != *DirectorySeparator))
780 (void) ConcatenateMagickString(path,DirectorySeparator,
782 (void) AppendValueToLinkedList(paths,ConstantString(path));
783 p=strchr(p+1,DirectoryListSeparator);
785 configure_path=DestroyString(configure_path);
788 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
789 #if defined(MAGICKCORE_SHARE_PATH)
790 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
792 #if defined(MAGICKCORE_SHAREARCH_PATH)
793 (void) AppendValueToLinkedList(paths,ConstantString(
794 MAGICKCORE_SHAREARCH_PATH));
796 #if defined(MAGICKCORE_CONFIGURE_PATH)
797 (void) AppendValueToLinkedList(paths,ConstantString(
798 MAGICKCORE_CONFIGURE_PATH));
800 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
801 (void) AppendValueToLinkedList(paths,ConstantString(
802 MAGICKCORE_DOCUMENTATION_PATH));
804 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
810 Locate file via registry key.
812 key_value=NTRegistryKeyLookup(RegistryKey);
813 if (key_value != (unsigned char *) NULL)
815 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
817 (void) AppendValueToLinkedList(paths,ConstantString(path));
818 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
828 Search under MAGICK_HOME.
830 home=GetEnvironmentValue("MAGICK_HOME");
831 if (home != (char *) NULL)
833 #if !defined(MAGICKCORE_POSIX_SUPPORT)
834 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
836 (void) AppendValueToLinkedList(paths,ConstantString(path));
838 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
839 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
840 (void) AppendValueToLinkedList(paths,ConstantString(path));
841 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
842 MAGICKCORE_SHARE_RELATIVE_PATH);
843 (void) AppendValueToLinkedList(paths,ConstantString(path));
844 (void) FormatLocaleString(path,MaxTextExtent,"%s",
845 MAGICKCORE_SHAREARCH_PATH);
846 (void) AppendValueToLinkedList(paths,ConstantString(path));
848 home=DestroyString(home);
851 if (*GetClientPath() != '\0')
853 #if !defined(MAGICKCORE_POSIX_SUPPORT)
854 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
856 (void) AppendValueToLinkedList(paths,ConstantString(path));
859 prefix[MaxTextExtent];
862 Search based on executable directory if directory is known.
864 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
865 ChopPathComponents(prefix,1);
866 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
867 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
868 (void) AppendValueToLinkedList(paths,ConstantString(path));
869 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
870 MAGICKCORE_SHARE_RELATIVE_PATH);
871 (void) AppendValueToLinkedList(paths,ConstantString(path));
872 (void) FormatLocaleString(path,MaxTextExtent,"%s",
873 MAGICKCORE_SHAREARCH_PATH);
874 (void) AppendValueToLinkedList(paths,ConstantString(path));
878 Search current directory.
880 (void) AppendValueToLinkedList(paths,ConstantString(""));
886 home=GetEnvironmentValue("HOME");
887 if (home == (char *) NULL)
888 home=GetEnvironmentValue("USERPROFILE");
889 if (home != (char *) NULL)
892 Search $HOME/.config/ImageMagick.
894 (void) FormatLocaleString(path,MaxTextExtent,
895 "%s%s.config%sImageMagick%s",home,DirectorySeparator,
896 DirectorySeparator,DirectorySeparator);
897 (void) AppendValueToLinkedList(paths,ConstantString(path));
898 home=DestroyString(home);
901 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
904 module_path[MaxTextExtent];
906 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
907 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
915 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
917 key_value=NTRegistryKeyLookup(RegistryKey);
918 if (key_value == (unsigned char *) NULL)
919 (void) AppendValueToLinkedList(paths,ConstantString(path));
921 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
923 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
926 Search PerlMagick module path.
928 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
930 (void) AppendValueToLinkedList(paths,ConstantString(path));
931 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
932 "\\inc\\lib\\auto\\Image\\Magick\\");
933 (void) AppendValueToLinkedList(paths,ConstantString(path));
941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 % G e t C o n f i g u r e V a l u e %
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951 % GetConfigureValue() returns the value associated with the configure info.
953 % The format of the GetConfigureValue method is:
955 % const char *GetConfigureValue(const ConfigureInfo *configure_info)
957 % A description of each parameter follows:
959 % o configure_info: The configure info.
962 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
964 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
965 assert(configure_info != (ConfigureInfo *) NULL);
966 assert(configure_info->signature == MagickSignature);
967 return(configure_info->value);
971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975 + I s C o n f i g u r e C a c h e I n s t a n t i a t e d %
979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981 % IsConfigureCacheInstantiated() determines if the configure list is
982 % instantiated. If not, it instantiates the list and returns it.
984 % The format of the IsConfigureInstantiated method is:
986 % MagickBooleanType IsConfigureCacheInstantiated(ExceptionInfo *exception)
988 % A description of each parameter follows.
990 % o exception: return any errors or warnings in this structure.
993 static MagickBooleanType IsConfigureCacheInstantiated(ExceptionInfo *exception)
995 if (configure_cache == (LinkedListInfo *) NULL)
997 if (configure_semaphore == (SemaphoreInfo *) NULL)
998 ActivateSemaphoreInfo(&configure_semaphore);
999 LockSemaphoreInfo(configure_semaphore);
1000 if (configure_cache == (LinkedListInfo *) NULL)
1001 configure_cache=AcquireConfigureCache(ConfigureFilename,exception);
1002 UnlockSemaphoreInfo(configure_semaphore);
1004 return(configure_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
1008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1012 % L i s t C o n f i g u r e I n f o %
1016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1018 % ListConfigureInfo() lists the configure info to a file.
1020 % The format of the ListConfigureInfo method is:
1022 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
1024 % A description of each parameter follows.
1026 % o file: An pointer to a FILE.
1028 % o exception: return any errors or warnings in this structure.
1031 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
1032 ExceptionInfo *exception)
1051 if (file == (const FILE *) NULL)
1053 configure_info=GetConfigureInfoList("*",&number_options,exception);
1054 if (configure_info == (const ConfigureInfo **) NULL)
1055 return(MagickFalse);
1056 path=(const char *) NULL;
1057 for (i=0; i < (ssize_t) number_options; i++)
1059 if (configure_info[i]->stealth != MagickFalse)
1061 if ((path == (const char *) NULL) ||
1062 (LocaleCompare(path,configure_info[i]->path) != 0))
1064 if (configure_info[i]->path != (char *) NULL)
1065 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
1066 configure_info[i]->path);
1067 (void) FormatLocaleFile(file,"Name Value\n");
1068 (void) FormatLocaleFile(file,
1069 "-------------------------------------------------"
1070 "------------------------------\n");
1072 path=configure_info[i]->path;
1074 if (configure_info[i]->name != (char *) NULL)
1075 name=configure_info[i]->name;
1076 (void) FormatLocaleFile(file,"%s",name);
1077 for (j=(ssize_t) strlen(name); j <= 13; j++)
1078 (void) FormatLocaleFile(file," ");
1079 (void) FormatLocaleFile(file," ");
1081 if (configure_info[i]->value != (char *) NULL)
1082 value=configure_info[i]->value;
1083 (void) FormatLocaleFile(file,"%s",value);
1084 (void) FormatLocaleFile(file,"\n");
1086 (void) fflush(file);
1087 configure_info=(const ConfigureInfo **) RelinquishMagickMemory((void *)
1093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1097 + L o a d C o n f i g u r e L i s t %
1101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1103 % LoadConfigureCache() loads the configure configurations which provides a
1104 % mapping between configure attributes and a configure name.
1106 % The format of the LoadConfigureCache method is:
1108 % MagickBooleanType LoadConfigureCache(LinkedListInfo *configure_cache,
1109 % const char *xml,const char *filename,const size_t depth,
1110 % ExceptionInfo *exception)
1112 % A description of each parameter follows:
1114 % o xml: The configure list in XML format.
1116 % o filename: The configure list filename.
1118 % o depth: depth of <include /> statements.
1120 % o exception: return any errors or warnings in this structure.
1123 static MagickBooleanType LoadConfigureCache(LinkedListInfo *configure_cache,
1124 const char *xml,const char *filename,const size_t depth,
1125 ExceptionInfo *exception)
1128 keyword[MaxTextExtent],
1141 Load the configure map file.
1143 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1144 "Loading configure file \"%s\" ...",filename);
1146 configure_info=(ConfigureInfo *) NULL;
1147 token=AcquireString((char *) xml);
1148 for (q=(char *) xml; *q != '\0'; )
1153 GetMagickToken(q,&q,token);
1156 (void) CopyMagickString(keyword,token,MaxTextExtent);
1157 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1162 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1163 GetMagickToken(q,&q,token);
1166 if (LocaleNCompare(keyword,"<!--",4) == 0)
1171 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1172 GetMagickToken(q,&q,token);
1175 if (LocaleCompare(keyword,"<include") == 0)
1180 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1182 (void) CopyMagickString(keyword,token,MaxTextExtent);
1183 GetMagickToken(q,&q,token);
1186 GetMagickToken(q,&q,token);
1187 if (LocaleCompare(keyword,"file") == 0)
1190 (void) ThrowMagickException(exception,GetMagickModule(),
1191 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1195 path[MaxTextExtent],
1198 GetPathComponent(filename,HeadPath,path);
1200 (void) ConcatenateMagickString(path,DirectorySeparator,
1202 if (*token == *DirectorySeparator)
1203 (void) CopyMagickString(path,token,MaxTextExtent);
1205 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1206 xml=FileToXML(path,~0UL);
1207 if (xml != (char *) NULL)
1209 status&=LoadConfigureCache(configure_cache,xml,path,
1211 xml=(char *) RelinquishMagickMemory(xml);
1218 if (LocaleCompare(keyword,"<configure") == 0)
1223 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1224 sizeof(*configure_info));
1225 if (configure_info == (ConfigureInfo *) NULL)
1226 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1227 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1228 configure_info->path=ConstantString(filename);
1229 configure_info->exempt=MagickFalse;
1230 configure_info->signature=MagickSignature;
1233 if (configure_info == (ConfigureInfo *) NULL)
1235 if (LocaleCompare(keyword,"/>") == 0)
1237 status=AppendValueToLinkedList(configure_cache,configure_info);
1238 if (status == MagickFalse)
1239 (void) ThrowMagickException(exception,GetMagickModule(),
1240 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1241 configure_info->name);
1242 configure_info=(ConfigureInfo *) NULL;
1246 Parse configure element.
1248 GetMagickToken(q,(const char **) NULL,token);
1251 GetMagickToken(q,&q,token);
1252 GetMagickToken(q,&q,token);
1258 if (LocaleCompare((char *) keyword,"name") == 0)
1260 configure_info->name=ConstantString(token);
1268 if (LocaleCompare((char *) keyword,"stealth") == 0)
1270 configure_info->stealth=IsStringTrue(token);
1278 if (LocaleCompare((char *) keyword,"value") == 0)
1280 configure_info->value=ConstantString(token);
1289 token=(char *) RelinquishMagickMemory(token);