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/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)
163 Load external configure map.
165 cache=NewLinkedList(0);
166 if (cache == (LinkedListInfo *) NULL)
167 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
169 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
177 options=GetConfigureOptions(filename,exception);
178 option=(const StringInfo *) GetNextValueInLinkedList(options);
179 while (option != (const StringInfo *) NULL)
181 status&=LoadConfigureCache(cache,(const char *)
182 GetStringInfoDatum(option),GetStringInfoPath(option),0,exception);
183 option=(const StringInfo *) GetNextValueInLinkedList(options);
185 options=DestroyConfigureOptions(options);
189 Load built-in configure map.
191 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
196 register const ConfigureMapInfo
200 configure_info=(ConfigureInfo *) AcquireMagickMemory(
201 sizeof(*configure_info));
202 if (configure_info == (ConfigureInfo *) NULL)
204 (void) ThrowMagickException(exception,GetMagickModule(),
205 ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
208 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
209 configure_info->path=(char *) "[built-in]";
210 configure_info->name=(char *) p->name;
211 configure_info->value=(char *) p->value;
212 configure_info->exempt=MagickTrue;
213 configure_info->signature=MagickCoreSignature;
214 status&=AppendValueToLinkedList(cache,configure_info);
215 if (status == MagickFalse)
216 (void) ThrowMagickException(exception,GetMagickModule(),
217 ResourceLimitError,"MemoryAllocationFailed","`%s'",
218 configure_info->name);
224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228 + 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 %
232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234 % ConfigureComponentGenesis() instantiates the configure component.
236 % The format of the ConfigureComponentGenesis method is:
238 % MagickBooleanType ConfigureComponentGenesis(void)
241 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
243 if (configure_semaphore == (SemaphoreInfo *) NULL)
244 configure_semaphore=AcquireSemaphoreInfo();
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253 + 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 %
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
259 % ConfigureComponentTerminus() destroys the configure component.
261 % The format of the ConfigureComponentTerminus method is:
263 % ConfigureComponentTerminus(void)
267 static void *DestroyConfigureElement(void *configure_info)
269 register ConfigureInfo
272 p=(ConfigureInfo *) configure_info;
273 if (p->exempt == MagickFalse)
275 if (p->value != (char *) NULL)
276 p->value=DestroyString(p->value);
277 if (p->name != (char *) NULL)
278 p->name=DestroyString(p->name);
279 if (p->path != (char *) NULL)
280 p->path=DestroyString(p->path);
282 p=(ConfigureInfo *) RelinquishMagickMemory(p);
283 return((void *) NULL);
286 MagickPrivate void ConfigureComponentTerminus(void)
288 if (configure_semaphore == (SemaphoreInfo *) NULL)
289 ActivateSemaphoreInfo(&configure_semaphore);
290 LockSemaphoreInfo(configure_semaphore);
291 if (configure_cache != (LinkedListInfo *) NULL)
292 configure_cache=DestroyLinkedList(configure_cache,DestroyConfigureElement);
293 configure_cache=(LinkedListInfo *) NULL;
294 UnlockSemaphoreInfo(configure_semaphore);
295 RelinquishSemaphoreInfo(&configure_semaphore);
299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303 % D e s t r o y C o n f i g u r e O p t i o n s %
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309 % DestroyConfigureOptions() releases memory associated with an configure
312 % The format of the DestroyProfiles method is:
314 % LinkedListInfo *DestroyConfigureOptions(Image *image)
316 % A description of each parameter follows:
318 % o image: the image.
322 static void *DestroyOptions(void *option)
324 return(DestroyStringInfo((StringInfo *) option));
327 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
329 assert(options != (LinkedListInfo *) NULL);
330 return(DestroyLinkedList(options,DestroyOptions));
334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 + G e t C o n f i g u r e I n f o %
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344 % GetConfigureInfo() searches the configure list for the specified name and if
345 % found returns attributes for that element.
347 % The format of the GetConfigureInfo method is:
349 % const ConfigureInfo *GetConfigureInfo(const char *name,
350 % ExceptionInfo *exception)
352 % A description of each parameter follows:
354 % o configure_info: GetConfigureInfo() searches the configure list for the
355 % specified name and if found returns attributes for that element.
357 % o name: the configure name.
359 % o exception: return any errors or warnings in this structure.
362 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
363 ExceptionInfo *exception)
365 register const ConfigureInfo
368 assert(exception != (ExceptionInfo *) NULL);
369 if (IsConfigureCacheInstantiated(exception) == MagickFalse)
370 return((const ConfigureInfo *) NULL);
372 Search for configure tag.
374 LockSemaphoreInfo(configure_semaphore);
375 ResetLinkedListIterator(configure_cache);
376 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
377 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
379 UnlockSemaphoreInfo(configure_semaphore);
382 while (p != (const ConfigureInfo *) NULL)
384 if (LocaleCompare(name,p->name) == 0)
386 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
388 if (p != (ConfigureInfo *) NULL)
389 (void) InsertValueInLinkedList(configure_cache,0,
390 RemoveElementByValueFromLinkedList(configure_cache,p));
391 UnlockSemaphoreInfo(configure_semaphore);
396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400 % G e t C o n f i g u r e I n f o L i s t %
404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
406 % GetConfigureInfoList() returns any configure options that match the
409 % The format of the GetConfigureInfoList function is:
411 % const ConfigureInfo **GetConfigureInfoList(const char *pattern,
412 % size_t *number_options,ExceptionInfo *exception)
414 % A description of each parameter follows:
416 % o pattern: Specifies a pointer to a text string containing a pattern.
418 % o number_options: This integer returns the number of configure options in
421 % o exception: return any errors or warnings in this structure.
425 #if defined(__cplusplus) || defined(c_plusplus)
429 static int ConfigureInfoCompare(const void *x,const void *y)
435 p=(const ConfigureInfo **) x,
436 q=(const ConfigureInfo **) y;
437 if (LocaleCompare((*p)->path,(*q)->path) == 0)
438 return(LocaleCompare((*p)->name,(*q)->name));
439 return(LocaleCompare((*p)->path,(*q)->path));
442 #if defined(__cplusplus) || defined(c_plusplus)
446 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
447 size_t *number_options,ExceptionInfo *exception)
452 register const ConfigureInfo
459 Allocate configure list.
461 assert(pattern != (char *) NULL);
462 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
463 assert(number_options != (size_t *) NULL);
465 p=GetConfigureInfo("*",exception);
466 if (p == (const ConfigureInfo *) NULL)
467 return((const ConfigureInfo **) NULL);
468 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
469 GetNumberOfElementsInLinkedList(configure_cache)+1UL,sizeof(*options));
470 if (options == (const ConfigureInfo **) NULL)
471 return((const ConfigureInfo **) NULL);
473 Generate configure list.
475 LockSemaphoreInfo(configure_semaphore);
476 ResetLinkedListIterator(configure_cache);
477 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
478 for (i=0; p != (const ConfigureInfo *) NULL; )
480 if ((p->stealth == MagickFalse) &&
481 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
483 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
485 UnlockSemaphoreInfo(configure_semaphore);
486 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
487 options[i]=(ConfigureInfo *) NULL;
488 *number_options=(size_t) i;
493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497 % G e t C o n f i g u r e L i s t %
501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503 % GetConfigureList() returns any configure options that match the specified
506 % The format of the GetConfigureList function is:
508 % char **GetConfigureList(const char *pattern,
509 % size_t *number_options,ExceptionInfo *exception)
511 % A description of each parameter follows:
513 % o pattern: Specifies a pointer to a text string containing a pattern.
515 % o number_options: This integer returns the number of options in the list.
517 % o exception: return any errors or warnings in this structure.
521 #if defined(__cplusplus) || defined(c_plusplus)
525 static int ConfigureCompare(const void *x,const void *y)
533 return(LocaleCompare(*p,*q));
536 #if defined(__cplusplus) || defined(c_plusplus)
540 MagickExport char **GetConfigureList(const char *pattern,
541 size_t *number_options,ExceptionInfo *exception)
546 register const ConfigureInfo
553 Allocate configure list.
555 assert(pattern != (char *) NULL);
556 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
557 assert(number_options != (size_t *) NULL);
559 p=GetConfigureInfo("*",exception);
560 if (p == (const ConfigureInfo *) NULL)
561 return((char **) NULL);
562 options=(char **) AcquireQuantumMemory((size_t)
563 GetNumberOfElementsInLinkedList(configure_cache)+1UL,sizeof(*options));
564 if (options == (char **) NULL)
565 return((char **) NULL);
566 LockSemaphoreInfo(configure_semaphore);
567 ResetLinkedListIterator(configure_cache);
568 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
569 for (i=0; p != (const ConfigureInfo *) NULL; )
571 if ((p->stealth == MagickFalse) &&
572 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
573 options[i++]=ConstantString(p->name);
574 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache);
576 UnlockSemaphoreInfo(configure_semaphore);
577 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
578 options[i]=(char *) NULL;
579 *number_options=(size_t) i;
584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588 % G e t C o n f i g u r e O p t i o n %
592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
594 % GetConfigureOption() returns the value associated with the configure option.
596 % The format of the GetConfigureOption method is:
598 % char *GetConfigureOption(const char *option)
600 % A description of each parameter follows:
602 % o configure_info: The configure info.
605 MagickExport char *GetConfigureOption(const char *option)
616 assert(option != (const char *) NULL);
617 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
618 exception=AcquireExceptionInfo();
619 configure_info=GetConfigureInfo(option,exception);
620 exception=DestroyExceptionInfo(exception);
621 if (configure_info == (ConfigureInfo *) NULL)
622 return((char *) NULL);
623 value=GetConfigureValue(configure_info);
624 if ((value == (const char *) NULL) || (*value == '\0'))
625 return((char *) NULL);
626 return(ConstantString(value));
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
634 % G e t C o n f i g u r e O p t i o n s %
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 % GetConfigureOptions() returns any Magick configuration options associated
641 % with the specified filename.
643 % The format of the GetConfigureOptions method is:
645 % LinkedListInfo *GetConfigureOptions(const char *filename,
646 % ExceptionInfo *exception)
648 % A description of each parameter follows:
650 % o filename: the configure file name.
652 % o exception: return any errors or warnings in this structure.
655 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
656 ExceptionInfo *exception)
659 path[MagickPathExtent];
671 assert(filename != (const char *) NULL);
672 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
673 assert(exception != (ExceptionInfo *) NULL);
674 (void) CopyMagickString(path,filename,MagickPathExtent);
676 Load XML from configuration files to linked-list.
678 options=NewLinkedList(0);
679 paths=GetConfigurePaths(filename,exception);
680 if (paths != (LinkedListInfo *) NULL)
682 ResetLinkedListIterator(paths);
683 element=(const char *) GetNextValueInLinkedList(paths);
684 while (element != (const char *) NULL)
686 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",element,
688 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
689 "Searching for configure file: \"%s\"",path);
690 xml=ConfigureFileToStringInfo(path);
691 if (xml != (StringInfo *) NULL)
692 (void) AppendValueToLinkedList(options,xml);
693 element=(const char *) GetNextValueInLinkedList(paths);
695 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
697 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
698 if (GetNumberOfElementsInLinkedList(options) == 0)
703 blob=(char *) NTResourceToBlob(filename);
704 if (blob != (char *) NULL)
706 xml=AcquireStringInfo(0);
707 SetStringInfoLength(xml,strlen(blob)+1);
708 SetStringInfoDatum(xml,(unsigned char *) blob);
709 SetStringInfoPath(xml,filename);
710 (void) AppendValueToLinkedList(options,xml);
714 if (GetNumberOfElementsInLinkedList(options) == 0)
715 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
716 "UnableToOpenConfigureFile","`%s'",filename);
717 ResetLinkedListIterator(options);
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
726 % G e t C o n f i g u r e P a t h s %
730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
732 % GetConfigurePaths() returns any Magick configuration paths associated
733 % with the specified filename.
735 % The format of the GetConfigurePaths method is:
737 % LinkedListInfo *GetConfigurePaths(const char *filename,
738 % ExceptionInfo *exception)
740 % A description of each parameter follows:
742 % o filename: the configure file name.
744 % o exception: return any errors or warnings in this structure.
747 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
748 ExceptionInfo *exception)
750 #define RegistryKey "ConfigurePath"
751 #define MagickCoreDLL "CORE_RL_MagickCore_.dll"
752 #define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll"
755 path[MagickPathExtent];
760 assert(filename != (const char *) NULL);
761 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
762 assert(exception != (ExceptionInfo *) NULL);
763 (void) CopyMagickString(path,filename,MagickPathExtent);
764 paths=NewLinkedList(0);
770 Search $MAGICK_CONFIGURE_PATH.
772 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
773 if (configure_path != (char *) NULL)
779 for (p=configure_path-1; p != (char *) NULL; )
781 (void) CopyMagickString(path,p+1,MagickPathExtent);
782 q=strchr(path,DirectoryListSeparator);
783 if (q != (char *) NULL)
785 q=path+strlen(path)-1;
786 if ((q >= path) && (*q != *DirectorySeparator))
787 (void) ConcatenateMagickString(path,DirectorySeparator,
789 (void) AppendValueToLinkedList(paths,ConstantString(path));
790 p=strchr(p+1,DirectoryListSeparator);
792 configure_path=DestroyString(configure_path);
795 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
796 #if defined(MAGICKCORE_SHARE_PATH)
797 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
799 #if defined(MAGICKCORE_SHAREARCH_PATH)
800 (void) AppendValueToLinkedList(paths,ConstantString(
801 MAGICKCORE_SHAREARCH_PATH));
803 #if defined(MAGICKCORE_CONFIGURE_PATH)
804 (void) AppendValueToLinkedList(paths,ConstantString(
805 MAGICKCORE_CONFIGURE_PATH));
807 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
808 (void) AppendValueToLinkedList(paths,ConstantString(
809 MAGICKCORE_DOCUMENTATION_PATH));
811 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
817 Locate file via registry key.
819 key_value=NTRegistryKeyLookup(RegistryKey);
820 if (key_value != (unsigned char *) NULL)
822 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",(char *)
823 key_value,DirectorySeparator);
824 (void) AppendValueToLinkedList(paths,ConstantString(path));
825 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
835 Search under MAGICK_HOME.
837 home=GetEnvironmentValue("MAGICK_HOME");
838 if (home != (char *) NULL)
840 #if !defined(MAGICKCORE_POSIX_SUPPORT) || defined( __VMS )
841 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",home,
843 (void) AppendValueToLinkedList(paths,ConstantString(path));
845 (void) FormatLocaleString(path,MagickPathExtent,"%s/etc/%s/",home,
846 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
847 (void) AppendValueToLinkedList(paths,ConstantString(path));
848 (void) FormatLocaleString(path,MagickPathExtent,"%s/share/%s/",home,
849 MAGICKCORE_SHARE_RELATIVE_PATH);
850 (void) AppendValueToLinkedList(paths,ConstantString(path));
851 (void) FormatLocaleString(path,MagickPathExtent,"%s",
852 MAGICKCORE_SHAREARCH_PATH);
853 (void) AppendValueToLinkedList(paths,ConstantString(path));
855 home=DestroyString(home);
858 if (*GetClientPath() != '\0')
860 #if !defined(MAGICKCORE_POSIX_SUPPORT) || defined( __VMS )
861 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",GetClientPath(),
863 (void) AppendValueToLinkedList(paths,ConstantString(path));
866 prefix[MagickPathExtent];
869 Search based on executable directory if directory is known.
871 (void) CopyMagickString(prefix,GetClientPath(),MagickPathExtent);
872 ChopPathComponents(prefix,1);
873 (void) FormatLocaleString(path,MagickPathExtent,"%s/etc/%s/",prefix,
874 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
875 (void) AppendValueToLinkedList(paths,ConstantString(path));
876 (void) FormatLocaleString(path,MagickPathExtent,"%s/share/%s/",prefix,
877 MAGICKCORE_SHARE_RELATIVE_PATH);
878 (void) AppendValueToLinkedList(paths,ConstantString(path));
879 (void) FormatLocaleString(path,MagickPathExtent,"%s",
880 MAGICKCORE_SHAREARCH_PATH);
881 (void) AppendValueToLinkedList(paths,ConstantString(path));
885 Search current directory.
887 (void) AppendValueToLinkedList(paths,ConstantString(""));
893 home=GetEnvironmentValue("XDG_CONFIG_HOME");
894 if (home == (char *) NULL)
895 home=GetEnvironmentValue("LOCALAPPDATA");
896 if (home == (char *) NULL)
897 home=GetEnvironmentValue("APPDATA");
898 if (home == (char *) NULL)
899 home=GetEnvironmentValue("USERPROFILE");
900 if (home != (char *) NULL)
903 Search $XDG_CONFIG_HOME/ImageMagick.
905 (void) FormatLocaleString(path,MagickPathExtent,"%s%sImageMagick%s",
906 home,DirectorySeparator,DirectorySeparator);
907 (void) AppendValueToLinkedList(paths,ConstantString(path));
908 home=DestroyString(home);
910 home=GetEnvironmentValue("HOME");
911 if (home != (char *) NULL)
914 Search $HOME/.config/ImageMagick.
916 (void) FormatLocaleString(path,MagickPathExtent,
917 "%s%s.config%sImageMagick%s",home,DirectorySeparator,
918 DirectorySeparator,DirectorySeparator);
919 (void) AppendValueToLinkedList(paths,ConstantString(path));
920 home=DestroyString(home);
923 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
926 module_path[MagickPathExtent];
928 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
929 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
937 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",module_path,
939 key_value=NTRegistryKeyLookup(RegistryKey);
940 if (key_value == (unsigned char *) NULL)
941 (void) AppendValueToLinkedList(paths,ConstantString(path));
943 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
945 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
948 Search PerlMagick module path.
950 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",module_path,
952 (void) AppendValueToLinkedList(paths,ConstantString(path));
953 (void) FormatLocaleString(path,MagickPathExtent,"%s%s",module_path,
954 "\\inc\\lib\\auto\\Image\\Magick\\");
955 (void) AppendValueToLinkedList(paths,ConstantString(path));
963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
967 % G e t C o n f i g u r e V a l u e %
971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
973 % GetConfigureValue() returns the value associated with the configure info.
975 % The format of the GetConfigureValue method is:
977 % const char *GetConfigureValue(const ConfigureInfo *configure_info)
979 % A description of each parameter follows:
981 % o configure_info: The configure info.
984 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
986 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
987 assert(configure_info != (ConfigureInfo *) NULL);
988 assert(configure_info->signature == MagickCoreSignature);
989 return(configure_info->value);
993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
997 + 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 %
1001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1003 % IsConfigureCacheInstantiated() determines if the configure list is
1004 % instantiated. If not, it instantiates the list and returns it.
1006 % The format of the IsConfigureInstantiated method is:
1008 % MagickBooleanType IsConfigureCacheInstantiated(ExceptionInfo *exception)
1010 % A description of each parameter follows.
1012 % o exception: return any errors or warnings in this structure.
1015 static MagickBooleanType IsConfigureCacheInstantiated(ExceptionInfo *exception)
1017 if (configure_cache == (LinkedListInfo *) NULL)
1019 if (configure_semaphore == (SemaphoreInfo *) NULL)
1020 ActivateSemaphoreInfo(&configure_semaphore);
1021 LockSemaphoreInfo(configure_semaphore);
1022 if (configure_cache == (LinkedListInfo *) NULL)
1023 configure_cache=AcquireConfigureCache(ConfigureFilename,exception);
1024 UnlockSemaphoreInfo(configure_semaphore);
1026 return(configure_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
1030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1034 % L i s t C o n f i g u r e I n f o %
1038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1040 % ListConfigureInfo() lists the configure info to a file.
1042 % The format of the ListConfigureInfo method is:
1044 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
1046 % A description of each parameter follows.
1048 % o file: An pointer to a FILE.
1050 % o exception: return any errors or warnings in this structure.
1053 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
1054 ExceptionInfo *exception)
1073 if (file == (const FILE *) NULL)
1075 configure_info=GetConfigureInfoList("*",&number_options,exception);
1076 if (configure_info == (const ConfigureInfo **) NULL)
1077 return(MagickFalse);
1078 path=(const char *) NULL;
1079 for (i=0; i < (ssize_t) number_options; i++)
1081 if (configure_info[i]->stealth != MagickFalse)
1083 if ((path == (const char *) NULL) ||
1084 (LocaleCompare(path,configure_info[i]->path) != 0))
1086 if (configure_info[i]->path != (char *) NULL)
1087 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
1088 configure_info[i]->path);
1089 (void) FormatLocaleFile(file,"Name Value\n");
1090 (void) FormatLocaleFile(file,
1091 "-------------------------------------------------"
1092 "------------------------------\n");
1094 path=configure_info[i]->path;
1096 if (configure_info[i]->name != (char *) NULL)
1097 name=configure_info[i]->name;
1098 (void) FormatLocaleFile(file,"%s",name);
1099 for (j=(ssize_t) strlen(name); j <= 13; j++)
1100 (void) FormatLocaleFile(file," ");
1101 (void) FormatLocaleFile(file," ");
1103 if (configure_info[i]->value != (char *) NULL)
1104 value=configure_info[i]->value;
1105 (void) FormatLocaleFile(file,"%s",value);
1106 (void) FormatLocaleFile(file,"\n");
1108 (void) fflush(file);
1109 configure_info=(const ConfigureInfo **) RelinquishMagickMemory((void *)
1115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1119 + L o a d C o n f i g u r e C a c h e %
1123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1125 % LoadConfigureCache() loads the configure configurations which provides a
1126 % mapping between configure attributes and a configure name.
1128 % The format of the LoadConfigureCache method is:
1130 % MagickBooleanType LoadConfigureCache(LinkedListInfo *cache,
1131 % const char *xml,const char *filename,const size_t depth,
1132 % ExceptionInfo *exception)
1134 % A description of each parameter follows:
1136 % o xml: The configure list in XML format.
1138 % o filename: The configure list filename.
1140 % o depth: depth of <include /> statements.
1142 % o exception: return any errors or warnings in this structure.
1145 static MagickBooleanType LoadConfigureCache(LinkedListInfo *cache,
1146 const char *xml,const char *filename,const size_t depth,
1147 ExceptionInfo *exception)
1150 keyword[MagickPathExtent],
1166 Load the configure map file.
1168 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1169 "Loading configure file \"%s\" ...",filename);
1171 configure_info=(ConfigureInfo *) NULL;
1172 token=AcquireString(xml);
1173 extent=strlen(token)+MagickPathExtent;
1174 for (q=(char *) xml; *q != '\0'; )
1179 GetNextToken(q,&q,extent,token);
1182 (void) CopyMagickString(keyword,token,MagickPathExtent);
1183 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1188 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1189 GetNextToken(q,&q,extent,token);
1192 if (LocaleNCompare(keyword,"<!--",4) == 0)
1197 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1198 GetNextToken(q,&q,extent,token);
1201 if (LocaleCompare(keyword,"<include") == 0)
1206 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1208 (void) CopyMagickString(keyword,token,MagickPathExtent);
1209 GetNextToken(q,&q,extent,token);
1212 GetNextToken(q,&q,extent,token);
1213 if (LocaleCompare(keyword,"file") == 0)
1216 (void) ThrowMagickException(exception,GetMagickModule(),
1217 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1221 path[MagickPathExtent],
1224 GetPathComponent(filename,HeadPath,path);
1226 (void) ConcatenateMagickString(path,DirectorySeparator,
1228 if (*token == *DirectorySeparator)
1229 (void) CopyMagickString(path,token,MagickPathExtent);
1231 (void) ConcatenateMagickString(path,token,MagickPathExtent);
1232 file_xml=FileToXML(path,~0UL);
1233 if (file_xml != (char *) NULL)
1235 status&=LoadConfigureCache(cache,file_xml,path,depth+1,
1237 file_xml=DestroyString(file_xml);
1244 if (LocaleCompare(keyword,"<configure") == 0)
1249 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1250 sizeof(*configure_info));
1251 if (configure_info == (ConfigureInfo *) NULL)
1252 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1253 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1254 configure_info->path=ConstantString(filename);
1255 configure_info->exempt=MagickFalse;
1256 configure_info->signature=MagickCoreSignature;
1259 if (configure_info == (ConfigureInfo *) NULL)
1261 if ((LocaleCompare(keyword,"/>") == 0) ||
1262 (LocaleCompare(keyword,"</policy>") == 0))
1264 status=AppendValueToLinkedList(cache,configure_info);
1265 if (status == MagickFalse)
1266 (void) ThrowMagickException(exception,GetMagickModule(),
1267 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1268 configure_info->name);
1269 configure_info=(ConfigureInfo *) NULL;
1273 Parse configure element.
1275 GetNextToken(q,(const char **) NULL,extent,token);
1278 GetNextToken(q,&q,extent,token);
1279 GetNextToken(q,&q,extent,token);
1285 if (LocaleCompare((char *) keyword,"name") == 0)
1287 configure_info->name=ConstantString(token);
1295 if (LocaleCompare((char *) keyword,"stealth") == 0)
1297 configure_info->stealth=IsStringTrue(token);
1305 if (LocaleCompare((char *) keyword,"value") == 0)
1307 configure_info->value=ConstantString(token);
1316 token=(char *) RelinquishMagickMemory(token);
1317 return(status != 0 ? MagickTrue : MagickFalse);