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-2017 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 % https://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/linked-list.h"
50 #include "MagickCore/log.h"
51 #include "MagickCore/memory_.h"
52 #include "MagickCore/memory-private.h"
53 #include "MagickCore/semaphore.h"
54 #include "MagickCore/string_.h"
55 #include "MagickCore/string-private.h"
56 #include "MagickCore/token.h"
57 #include "MagickCore/utility.h"
58 #include "MagickCore/utility-private.h"
59 #include "MagickCore/xml-tree.h"
60 #include "MagickCore/xml-tree-private.h"
65 #define ConfigureFilename "configure.xml"
68 #define MAGICKCORE_FEATURE_OPENMP_STR "OpenMP "
70 #define MAGICKCORE_FEATURE_OPENMP_STR ""
73 #define MAGICKCORE_FEATURE_OPENCL_STR "OpenCL "
75 #define MAGICKCORE_FEATURE_OPENCL_STR ""
77 #ifdef MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
78 #define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR "Zero-Configuration "
80 #define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR ""
83 #define MAGICKCORE_FEATURE_HDRI_STR "HDRI"
85 #define MAGICKCORE_FEATURE_HDRI_STR ""
88 #define MAGICKCORE_FEATURES_STR MAGICKCORE_FEATURE_OPENMP_STR MAGICKCORE_FEATURE_OPENCL_STR MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR MAGICKCORE_FEATURE_HDRI_STR
93 typedef struct _ConfigureMapInfo
103 static const ConfigureMapInfo
106 { "NAME", "ImageMagick" },
107 { "QuantumDepth", MAGICKCORE_STRING_XQUOTE(MAGICKCORE_QUANTUM_DEPTH) } ,
108 { "FEATURES", MAGICKCORE_FEATURES_STR }
111 static LinkedListInfo
112 *configure_cache = (LinkedListInfo *) NULL;
115 *configure_semaphore = (SemaphoreInfo *) NULL;
118 Forward declarations.
120 static MagickBooleanType
121 IsConfigureCacheInstantiated(ExceptionInfo *),
122 LoadConfigureCache(LinkedListInfo *,const char *,const char *,const size_t,
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 % A c q u i r e C o n f i g u r e C a c h e %
134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 % AcquireConfigureCache() caches one or more configure configurations which
137 % provides a mapping between configure attributes and a configure name.
139 % The format of the AcquireConfigureCache method is:
141 % LinkedListInfo *AcquireConfigureCache(const char *filename,
142 % ExceptionInfo *exception)
144 % A description of each parameter follows:
146 % o filename: the font file name.
148 % o exception: return any errors or warnings in this structure.
151 static LinkedListInfo *AcquireConfigureCache(const char *filename,
152 ExceptionInfo *exception)
164 Load external configure map.
166 cache=NewLinkedList(0);
168 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
176 options=GetConfigureOptions(filename,exception);
177 option=(const StringInfo *) GetNextValueInLinkedList(options);
178 while (option != (const StringInfo *) NULL)
180 status&=LoadConfigureCache(cache,(const char *)
181 GetStringInfoDatum(option),GetStringInfoPath(option),0,exception);
182 option=(const StringInfo *) GetNextValueInLinkedList(options);
184 options=DestroyConfigureOptions(options);
188 Load built-in configure map.
190 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
195 register const ConfigureMapInfo
199 configure_info=(ConfigureInfo *) AcquireMagickMemory(
200 sizeof(*configure_info));
201 if (configure_info == (ConfigureInfo *) NULL)
203 (void) ThrowMagickException(exception,GetMagickModule(),
204 ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
207 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
208 configure_info->path=(char *) "[built-in]";
209 configure_info->name=(char *) p->name;
210 configure_info->value=(char *) p->value;
211 configure_info->exempt=MagickTrue;
212 configure_info->signature=MagickCoreSignature;
213 status&=AppendValueToLinkedList(cache,configure_info);
214 if (status == MagickFalse)
215 (void) ThrowMagickException(exception,GetMagickModule(),
216 ResourceLimitError,"MemoryAllocationFailed","`%s'",
217 configure_info->name);
223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227 + 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 %
231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
233 % ConfigureComponentGenesis() instantiates the configure component.
235 % The format of the ConfigureComponentGenesis method is:
237 % MagickBooleanType ConfigureComponentGenesis(void)
240 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
242 if (configure_semaphore == (SemaphoreInfo *) NULL)
243 configure_semaphore=AcquireSemaphoreInfo();
248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 + 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 %
256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 % ConfigureComponentTerminus() destroys the configure component.
260 % The format of the ConfigureComponentTerminus method is:
262 % ConfigureComponentTerminus(void)
266 static void *DestroyConfigureElement(void *configure_info)
268 register ConfigureInfo
271 p=(ConfigureInfo *) configure_info;
272 if (p->exempt == MagickFalse)
274 if (p->value != (char *) NULL)
275 p->value=DestroyString(p->value);
276 if (p->name != (char *) NULL)
277 p->name=DestroyString(p->name);
278 if (p->path != (char *) NULL)
279 p->path=DestroyString(p->path);
281 p=(ConfigureInfo *) RelinquishMagickMemory(p);
282 return((void *) NULL);
285 MagickPrivate void ConfigureComponentTerminus(void)
287 if (configure_semaphore == (SemaphoreInfo *) NULL)
288 ActivateSemaphoreInfo(&configure_semaphore);
289 LockSemaphoreInfo(configure_semaphore);
290 if (configure_cache != (LinkedListInfo *) NULL)
291 configure_cache=DestroyLinkedList(configure_cache,DestroyConfigureElement);
292 configure_cache=(LinkedListInfo *) NULL;
293 UnlockSemaphoreInfo(configure_semaphore);
294 RelinquishSemaphoreInfo(&configure_semaphore);
298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302 % D e s t r o y C o n f i g u r e O p t i o n s %
306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308 % DestroyConfigureOptions() releases memory associated with an configure
311 % The format of the DestroyProfiles method is:
313 % LinkedListInfo *DestroyConfigureOptions(Image *image)
315 % A description of each parameter follows:
317 % o image: the image.
321 static void *DestroyOptions(void *option)
323 return(DestroyStringInfo((StringInfo *) option));
326 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
328 assert(options != (LinkedListInfo *) NULL);
329 return(DestroyLinkedList(options,DestroyOptions));
333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337 + G e t C o n f i g u r e I n f o %
341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 % GetConfigureInfo() searches the configure list for the specified name and if
344 % found returns attributes for that element.
346 % The format of the GetConfigureInfo method is:
348 % const ConfigureInfo *GetConfigureInfo(const char *name,
349 % ExceptionInfo *exception)
351 % A description of each parameter follows:
353 % o configure_info: GetConfigureInfo() searches the configure list for the
354 % specified name and if found returns attributes for that element.
356 % o name: the configure name.
358 % o exception: return any errors or warnings in this structure.
361 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
362 ExceptionInfo *exception)
364 register const ConfigureInfo
367 assert(exception != (ExceptionInfo *) NULL);
368 if (IsConfigureCacheInstantiated(exception) == MagickFalse)
369 return((const ConfigureInfo *) NULL);
371 Search for configure tag.
373 LockSemaphoreInfo(configure_semaphore);
374 ResetLinkedListIterator(configure_cache);
375 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
376 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
378 UnlockSemaphoreInfo(configure_semaphore);
381 while (p != (const ConfigureInfo *) NULL)
383 if (LocaleCompare(name,p->name) == 0)
385 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
387 if (p != (ConfigureInfo *) NULL)
388 (void) InsertValueInLinkedList(configure_cache,0,
389 RemoveElementByValueFromLinkedList(configure_cache,p));
390 UnlockSemaphoreInfo(configure_semaphore);
395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399 % G e t C o n f i g u r e I n f o L i s t %
403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
405 % GetConfigureInfoList() returns any configure options that match the
408 % The format of the GetConfigureInfoList function is:
410 % const ConfigureInfo **GetConfigureInfoList(const char *pattern,
411 % size_t *number_options,ExceptionInfo *exception)
413 % A description of each parameter follows:
415 % o pattern: Specifies a pointer to a text string containing a pattern.
417 % o number_options: This integer returns the number of configure options in
420 % o exception: return any errors or warnings in this structure.
424 #if defined(__cplusplus) || defined(c_plusplus)
428 static int ConfigureInfoCompare(const void *x,const void *y)
434 p=(const ConfigureInfo **) x,
435 q=(const ConfigureInfo **) y;
436 if (LocaleCompare((*p)->path,(*q)->path) == 0)
437 return(LocaleCompare((*p)->name,(*q)->name));
438 return(LocaleCompare((*p)->path,(*q)->path));
441 #if defined(__cplusplus) || defined(c_plusplus)
445 MagickExport const ConfigureInfo **GetConfigureInfoList(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((const ConfigureInfo **) NULL);
467 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
468 GetNumberOfElementsInLinkedList(configure_cache)+1UL,sizeof(*options));
469 if (options == (const ConfigureInfo **) NULL)
470 return((const ConfigureInfo **) NULL);
472 Generate configure list.
474 LockSemaphoreInfo(configure_semaphore);
475 ResetLinkedListIterator(configure_cache);
476 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
477 for (i=0; p != (const ConfigureInfo *) NULL; )
479 if ((p->stealth == MagickFalse) &&
480 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
482 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
484 UnlockSemaphoreInfo(configure_semaphore);
485 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
486 options[i]=(ConfigureInfo *) NULL;
487 *number_options=(size_t) i;
492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496 % G e t C o n f i g u r e L i s t %
500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502 % GetConfigureList() returns any configure options that match the specified
505 % The format of the GetConfigureList function is:
507 % char **GetConfigureList(const char *pattern,
508 % size_t *number_options,ExceptionInfo *exception)
510 % A description of each parameter follows:
512 % o pattern: Specifies a pointer to a text string containing a pattern.
514 % o number_options: This integer returns the number of options in the list.
516 % o exception: return any errors or warnings in this structure.
520 #if defined(__cplusplus) || defined(c_plusplus)
524 static int ConfigureCompare(const void *x,const void *y)
532 return(LocaleCompare(*p,*q));
535 #if defined(__cplusplus) || defined(c_plusplus)
539 MagickExport char **GetConfigureList(const char *pattern,
540 size_t *number_options,ExceptionInfo *exception)
545 register const ConfigureInfo
552 Allocate configure list.
554 assert(pattern != (char *) NULL);
555 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
556 assert(number_options != (size_t *) NULL);
558 p=GetConfigureInfo("*",exception);
559 if (p == (const ConfigureInfo *) NULL)
560 return((char **) NULL);
561 options=(char **) AcquireQuantumMemory((size_t)
562 GetNumberOfElementsInLinkedList(configure_cache)+1UL,sizeof(*options));
563 if (options == (char **) NULL)
564 return((char **) NULL);
565 LockSemaphoreInfo(configure_semaphore);
566 ResetLinkedListIterator(configure_cache);
567 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
568 for (i=0; p != (const ConfigureInfo *) NULL; )
570 if ((p->stealth == MagickFalse) &&
571 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
572 options[i++]=ConstantString(p->name);
573 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
575 UnlockSemaphoreInfo(configure_semaphore);
576 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
577 options[i]=(char *) NULL;
578 *number_options=(size_t) i;
583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587 % G e t C o n f i g u r e O p t i o n %
591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593 % GetConfigureOption() returns the value associated with the configure option.
595 % The format of the GetConfigureOption method is:
597 % char *GetConfigureOption(const char *option)
599 % A description of each parameter follows:
601 % o configure_info: The configure info.
604 MagickExport char *GetConfigureOption(const char *option)
615 assert(option != (const char *) NULL);
616 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
617 exception=AcquireExceptionInfo();
618 configure_info=GetConfigureInfo(option,exception);
619 exception=DestroyExceptionInfo(exception);
620 if (configure_info == (ConfigureInfo *) NULL)
621 return((char *) NULL);
622 value=GetConfigureValue(configure_info);
623 if ((value == (const char *) NULL) || (*value == '\0'))
624 return((char *) NULL);
625 return(ConstantString(value));
629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633 % G e t C o n f i g u r e O p t i o n s %
637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639 % GetConfigureOptions() returns any Magick configuration options associated
640 % with the specified filename.
642 % The format of the GetConfigureOptions method is:
644 % LinkedListInfo *GetConfigureOptions(const char *filename,
645 % ExceptionInfo *exception)
647 % A description of each parameter follows:
649 % o filename: the configure file name.
651 % o exception: return any errors or warnings in this structure.
654 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
655 ExceptionInfo *exception)
658 path[MagickPathExtent];
670 assert(filename != (const char *) NULL);
671 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
672 assert(exception != (ExceptionInfo *) NULL);
673 (void) CopyMagickString(path,filename,MagickPathExtent);
675 Load XML from configuration files to linked-list.
677 options=NewLinkedList(0);
678 paths=GetConfigurePaths(filename,exception);
679 if (paths != (LinkedListInfo *) NULL)
681 ResetLinkedListIterator(paths);
682 element=(const char *) GetNextValueInLinkedList(paths);
683 while (element != (const char *) NULL)
685 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",element,
687 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
688 "Searching for configure file: \"%s\"",path);
689 xml=ConfigureFileToStringInfo(path);
690 if (xml != (StringInfo *) NULL)
691 (void) AppendValueToLinkedList(options,xml);
692 element=(const char *) GetNextValueInLinkedList(paths);
694 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
696 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
697 if (GetNumberOfElementsInLinkedList(options) == 0)
702 blob=(char *) NTResourceToBlob(filename);
703 if (blob != (char *) NULL)
705 xml=AcquireStringInfo(0);
706 SetStringInfoLength(xml,strlen(blob)+1);
707 SetStringInfoDatum(xml,(unsigned char *) blob);
708 SetStringInfoPath(xml,filename);
709 (void) AppendValueToLinkedList(options,xml);
713 if (GetNumberOfElementsInLinkedList(options) == 0)
714 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
715 "UnableToOpenConfigureFile","`%s'",filename);
716 ResetLinkedListIterator(options);
721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
725 % G e t C o n f i g u r e P a t h s %
729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731 % GetConfigurePaths() returns any Magick configuration paths associated
732 % with the specified filename.
734 % The format of the GetConfigurePaths method is:
736 % LinkedListInfo *GetConfigurePaths(const char *filename,
737 % ExceptionInfo *exception)
739 % A description of each parameter follows:
741 % o filename: the configure file name.
743 % o exception: return any errors or warnings in this structure.
746 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
747 ExceptionInfo *exception)
749 #define RegistryKey "ConfigurePath"
750 #define MagickCoreDLL "CORE_RL_MagickCore_.dll"
751 #define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll"
754 path[MagickPathExtent];
759 assert(filename != (const char *) NULL);
760 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
761 assert(exception != (ExceptionInfo *) NULL);
762 (void) CopyMagickString(path,filename,MagickPathExtent);
763 paths=NewLinkedList(0);
769 Search $MAGICK_CONFIGURE_PATH.
771 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
772 if (configure_path != (char *) NULL)
778 for (p=configure_path-1; p != (char *) NULL; )
780 (void) CopyMagickString(path,p+1,MagickPathExtent);
781 q=strchr(path,DirectoryListSeparator);
782 if (q != (char *) NULL)
784 q=path+strlen(path)-1;
785 if ((q >= path) && (*q != *DirectorySeparator))
786 (void) ConcatenateMagickString(path,DirectorySeparator,
788 (void) AppendValueToLinkedList(paths,ConstantString(path));
789 p=strchr(p+1,DirectoryListSeparator);
791 configure_path=DestroyString(configure_path);
794 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
795 #if defined(MAGICKCORE_SHARE_PATH)
796 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
798 #if defined(MAGICKCORE_SHAREARCH_PATH)
799 (void) AppendValueToLinkedList(paths,ConstantString(
800 MAGICKCORE_SHAREARCH_PATH));
802 #if defined(MAGICKCORE_CONFIGURE_PATH)
803 (void) AppendValueToLinkedList(paths,ConstantString(
804 MAGICKCORE_CONFIGURE_PATH));
806 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
807 (void) AppendValueToLinkedList(paths,ConstantString(
808 MAGICKCORE_DOCUMENTATION_PATH));
810 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
816 Locate file via registry key.
818 key_value=NTRegistryKeyLookup(RegistryKey);
819 if (key_value != (unsigned char *) NULL)
821 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",(char *)
822 key_value,DirectorySeparator);
823 (void) AppendValueToLinkedList(paths,ConstantString(path));
824 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
834 Search under MAGICK_HOME.
836 home=GetEnvironmentValue("MAGICK_HOME");
837 if (home != (char *) NULL)
839 #if !defined(MAGICKCORE_POSIX_SUPPORT) || defined( __VMS )
840 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",home,
842 (void) AppendValueToLinkedList(paths,ConstantString(path));
844 (void) FormatLocaleString(path,MagickPathExtent,"%s/etc/%s/",home,
845 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
846 (void) AppendValueToLinkedList(paths,ConstantString(path));
847 (void) FormatLocaleString(path,MagickPathExtent,"%s/share/%s/",home,
848 MAGICKCORE_SHARE_RELATIVE_PATH);
849 (void) AppendValueToLinkedList(paths,ConstantString(path));
850 (void) FormatLocaleString(path,MagickPathExtent,"%s",
851 MAGICKCORE_SHAREARCH_PATH);
852 (void) AppendValueToLinkedList(paths,ConstantString(path));
854 home=DestroyString(home);
857 if (*GetClientPath() != '\0')
859 #if !defined(MAGICKCORE_POSIX_SUPPORT) || defined( __VMS )
860 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",GetClientPath(),
862 (void) AppendValueToLinkedList(paths,ConstantString(path));
865 prefix[MagickPathExtent];
868 Search based on executable directory if directory is known.
870 (void) CopyMagickString(prefix,GetClientPath(),MagickPathExtent);
871 ChopPathComponents(prefix,1);
872 (void) FormatLocaleString(path,MagickPathExtent,"%s/etc/%s/",prefix,
873 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
874 (void) AppendValueToLinkedList(paths,ConstantString(path));
875 (void) FormatLocaleString(path,MagickPathExtent,"%s/share/%s/",prefix,
876 MAGICKCORE_SHARE_RELATIVE_PATH);
877 (void) AppendValueToLinkedList(paths,ConstantString(path));
878 (void) FormatLocaleString(path,MagickPathExtent,"%s",
879 MAGICKCORE_SHAREARCH_PATH);
880 (void) AppendValueToLinkedList(paths,ConstantString(path));
884 Search current directory.
886 (void) AppendValueToLinkedList(paths,ConstantString(""));
892 home=GetEnvironmentValue("XDG_CONFIG_HOME");
893 if (home == (char *) NULL)
894 home=GetEnvironmentValue("LOCALAPPDATA");
895 if (home == (char *) NULL)
896 home=GetEnvironmentValue("APPDATA");
897 if (home == (char *) NULL)
898 home=GetEnvironmentValue("USERPROFILE");
899 if (home != (char *) NULL)
902 Search $XDG_CONFIG_HOME/ImageMagick.
904 (void) FormatLocaleString(path,MagickPathExtent,"%s%sImageMagick%s",
905 home,DirectorySeparator,DirectorySeparator);
906 (void) AppendValueToLinkedList(paths,ConstantString(path));
907 home=DestroyString(home);
909 home=GetEnvironmentValue("HOME");
910 if (home != (char *) NULL)
913 Search $HOME/.config/ImageMagick.
915 (void) FormatLocaleString(path,MagickPathExtent,
916 "%s%s.config%sImageMagick%s",home,DirectorySeparator,
917 DirectorySeparator,DirectorySeparator);
918 (void) AppendValueToLinkedList(paths,ConstantString(path));
919 home=DestroyString(home);
922 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
925 module_path[MagickPathExtent];
927 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
928 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
936 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",module_path,
938 key_value=NTRegistryKeyLookup(RegistryKey);
939 if (key_value == (unsigned char *) NULL)
940 (void) AppendValueToLinkedList(paths,ConstantString(path));
942 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
944 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
947 Search PerlMagick module path.
949 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",module_path,
951 (void) AppendValueToLinkedList(paths,ConstantString(path));
952 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",module_path,
953 "\\inc\\lib\\auto\\Image\\Magick\\");
954 (void) AppendValueToLinkedList(paths,ConstantString(path));
962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
966 % G e t C o n f i g u r e V a l u e %
970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
972 % GetConfigureValue() returns the value associated with the configure info.
974 % The format of the GetConfigureValue method is:
976 % const char *GetConfigureValue(const ConfigureInfo *configure_info)
978 % A description of each parameter follows:
980 % o configure_info: The configure info.
983 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
985 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
986 assert(configure_info != (ConfigureInfo *) NULL);
987 assert(configure_info->signature == MagickCoreSignature);
988 return(configure_info->value);
992 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
996 + 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 %
1000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1002 % IsConfigureCacheInstantiated() determines if the configure list is
1003 % instantiated. If not, it instantiates the list and returns it.
1005 % The format of the IsConfigureInstantiated method is:
1007 % MagickBooleanType IsConfigureCacheInstantiated(ExceptionInfo *exception)
1009 % A description of each parameter follows.
1011 % o exception: return any errors or warnings in this structure.
1014 static MagickBooleanType IsConfigureCacheInstantiated(ExceptionInfo *exception)
1016 if (configure_cache == (LinkedListInfo *) NULL)
1018 if (configure_semaphore == (SemaphoreInfo *) NULL)
1019 ActivateSemaphoreInfo(&configure_semaphore);
1020 LockSemaphoreInfo(configure_semaphore);
1021 if (configure_cache == (LinkedListInfo *) NULL)
1022 configure_cache=AcquireConfigureCache(ConfigureFilename,exception);
1023 UnlockSemaphoreInfo(configure_semaphore);
1025 return(configure_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
1029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1033 % L i s t C o n f i g u r e I n f o %
1037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1039 % ListConfigureInfo() lists the configure info to a file.
1041 % The format of the ListConfigureInfo method is:
1043 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
1045 % A description of each parameter follows.
1047 % o file: An pointer to a FILE.
1049 % o exception: return any errors or warnings in this structure.
1052 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
1053 ExceptionInfo *exception)
1072 if (file == (const FILE *) NULL)
1074 configure_info=GetConfigureInfoList("*",&number_options,exception);
1075 if (configure_info == (const ConfigureInfo **) NULL)
1076 return(MagickFalse);
1077 path=(const char *) NULL;
1078 for (i=0; i < (ssize_t) number_options; i++)
1080 if (configure_info[i]->stealth != MagickFalse)
1082 if ((path == (const char *) NULL) ||
1083 (LocaleCompare(path,configure_info[i]->path) != 0))
1085 if (configure_info[i]->path != (char *) NULL)
1086 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
1087 configure_info[i]->path);
1088 (void) FormatLocaleFile(file,"Name Value\n");
1089 (void) FormatLocaleFile(file,
1090 "-------------------------------------------------"
1091 "------------------------------\n");
1093 path=configure_info[i]->path;
1095 if (configure_info[i]->name != (char *) NULL)
1096 name=configure_info[i]->name;
1097 (void) FormatLocaleFile(file,"%s",name);
1098 for (j=(ssize_t) strlen(name); j <= 13; j++)
1099 (void) FormatLocaleFile(file," ");
1100 (void) FormatLocaleFile(file," ");
1102 if (configure_info[i]->value != (char *) NULL)
1103 value=configure_info[i]->value;
1104 (void) FormatLocaleFile(file,"%s",value);
1105 (void) FormatLocaleFile(file,"\n");
1107 (void) fflush(file);
1108 configure_info=(const ConfigureInfo **) RelinquishMagickMemory((void *)
1114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1118 + L o a d C o n f i g u r e C a c h e %
1122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1124 % LoadConfigureCache() loads the configure configurations which provides a
1125 % mapping between configure attributes and a configure name.
1127 % The format of the LoadConfigureCache method is:
1129 % MagickBooleanType LoadConfigureCache(LinkedListInfo *cache,
1130 % const char *xml,const char *filename,const size_t depth,
1131 % ExceptionInfo *exception)
1133 % A description of each parameter follows:
1135 % o xml: The configure list in XML format.
1137 % o filename: The configure list filename.
1139 % o depth: depth of <include /> statements.
1141 % o exception: return any errors or warnings in this structure.
1144 static MagickBooleanType LoadConfigureCache(LinkedListInfo *cache,
1145 const char *xml,const char *filename,const size_t depth,
1146 ExceptionInfo *exception)
1149 keyword[MagickPathExtent],
1165 Load the configure map file.
1167 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1168 "Loading configure file \"%s\" ...",filename);
1170 configure_info=(ConfigureInfo *) NULL;
1171 token=AcquireString(xml);
1172 extent=strlen(token)+MagickPathExtent;
1173 for (q=(char *) xml; *q != '\0'; )
1178 GetNextToken(q,&q,extent,token);
1181 (void) CopyMagickString(keyword,token,MagickPathExtent);
1182 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1187 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1188 GetNextToken(q,&q,extent,token);
1191 if (LocaleNCompare(keyword,"<!--",4) == 0)
1196 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1197 GetNextToken(q,&q,extent,token);
1200 if (LocaleCompare(keyword,"<include") == 0)
1205 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1207 (void) CopyMagickString(keyword,token,MagickPathExtent);
1208 GetNextToken(q,&q,extent,token);
1211 GetNextToken(q,&q,extent,token);
1212 if (LocaleCompare(keyword,"file") == 0)
1215 (void) ThrowMagickException(exception,GetMagickModule(),
1216 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1220 path[MagickPathExtent],
1223 GetPathComponent(filename,HeadPath,path);
1225 (void) ConcatenateMagickString(path,DirectorySeparator,
1227 if (*token == *DirectorySeparator)
1228 (void) CopyMagickString(path,token,MagickPathExtent);
1230 (void) ConcatenateMagickString(path,token,MagickPathExtent);
1231 file_xml=FileToXML(path,~0UL);
1232 if (file_xml != (char *) NULL)
1234 status&=LoadConfigureCache(cache,file_xml,path,depth+1,
1236 file_xml=DestroyString(file_xml);
1243 if (LocaleCompare(keyword,"<configure") == 0)
1248 configure_info=(ConfigureInfo *) AcquireCriticalMemory(
1249 sizeof(*configure_info));
1250 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1251 configure_info->path=ConstantString(filename);
1252 configure_info->exempt=MagickFalse;
1253 configure_info->signature=MagickCoreSignature;
1256 if (configure_info == (ConfigureInfo *) NULL)
1258 if ((LocaleCompare(keyword,"/>") == 0) ||
1259 (LocaleCompare(keyword,"</policy>") == 0))
1261 status=AppendValueToLinkedList(cache,configure_info);
1262 if (status == MagickFalse)
1263 (void) ThrowMagickException(exception,GetMagickModule(),
1264 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1265 configure_info->name);
1266 configure_info=(ConfigureInfo *) NULL;
1270 Parse configure element.
1272 GetNextToken(q,(const char **) NULL,extent,token);
1275 GetNextToken(q,&q,extent,token);
1276 GetNextToken(q,&q,extent,token);
1282 if (LocaleCompare((char *) keyword,"name") == 0)
1284 configure_info->name=ConstantString(token);
1292 if (LocaleCompare((char *) keyword,"stealth") == 0)
1294 configure_info->stealth=IsStringTrue(token);
1302 if (LocaleCompare((char *) keyword,"value") == 0)
1304 configure_info->value=ConstantString(token);
1313 token=(char *) RelinquishMagickMemory(token);
1314 return(status != 0 ? MagickTrue : MagickFalse);